Introduction to the

Laravel Sail is a Docker development environment that is included with Laravel 8 by default. It allows you to quickly set up and run a PHP development environment, customized for running Laravel applications, with built-in NPM/Node support.

In this guide, you will guide a new Laravel application with Laravel Sail and create a stylised “About me” landing page using Tailwind CSS, a utility-first CSS framework designed to quickly build custom user interfaces. Finally, you’ll have a foundation that you can use to further develop Laravel applications, using Tailwind CSS in the front end and Sail in the development environment.

If you want to continue learning from an existing code base, rather than creating a project from scratch, you can access the finished demo application code on GitHub’s Do-community/Laravel-Tailwind – Starter.

The premise condition

Although the code shared in this guide should work seamlessly across multiple environments and systems, the instructions explained here were tested on an Ubuntu 20.04 native system running Docker and Docker Compose. No matter what your base operating system is, here’s what you need to set up to get started.

  • Install Docker on your local machine. If you are running Ubuntu 20.04, you can follow steps 1 and 2 in How to Install and Use Docker on Ubuntu 20.04. Windows and MacOS users will need to install Docker Desktop.
  • Install Docker Compose on your local machine. Docker Compose is included by default on Docker Desktop for Windows and MacOS systems, but Linux users need to install the Compose executable by following step 1 of How to Install and Use Docker Compose on Ubuntu 20.04.
  • A code editor (optional) for PHP. Code editors help make code easier to read and format, and they can improve productivity by pointing out problems before code is executed. You can follow our guide: how to set up Visual Studio Code for PHP projects to set up VSCode, a free Code editor, in your local development environment.

Step 1 – Create a new Laravel application using the Laravel Builder script

To get started, you’ll download and execute the official Laravel Generator script, which will pull in the necessary Docker container images to build your development environment, and then launch a new application in your current folder. This installation method does not require you to install PHP on your system, just download and execute the builder script, which sets up the Docker environment and allows you to run the actual Laravel installer.

At the end, the script asks for your sudo password to ensure that the application folder has the correct permissions for your system users. You can access the script URL from your browser and verify its contents before running the next command. In this example, we use the name MyApp, but feel free to use a different name instead.

curl -s https://laravel.build/myapp | bash
Copy the code
OutputUnable to find image 'laravelsail/php80-composer:latest' locally latest: Pulling from Laravelsail /php80-composer 852e50CD189d: Pull complete 0266fc315b01: Pull complete... Application ready! Build something amazing. Sail scaffolding installed successfully. Please provide your password so we can make some final  adjustments to your application's permissions. [sudo] password for sammy: Thank you! We hope you build something incredible. Dive in with: cd myapp && ./vendor/bin/sail upCopy the code

When the installation is complete, access the new application directory and Sail the environment.

cd myapp
./vendor/bin/sail up
Copy the code

This puts the environment in foreground mode, so you can keep up with the logs of all running containers. You’ll see a number of different services being started, using different ports to communicate with each other.

Output... Mailhog_1 |] [HTTP Binding to address: 0.0.0.0:8025... Laravel. Test_1 | Starting laravel development server: http://0.0.0.0:80... Meilisearch_1 | Server listening on: "http://0.0.0.0:7700"... Mysql_1 | T01:2021-06-23 and. 327234 z 0 [System] [MY - 010931] / Server/usr/sbin/mysqld: ready for connections. Version: '8.0.25' socket: '/ var/run/mysqld/mysqld. The sock' port: 3306 MySQL Community Server - the GPL.... Selenium_1 | 01:14:57. 417 INFO [SeleniumServer boot] - the Selenium Server is up and running on port 4444... Redis_1 | 1: M 23 Jun 2021 01:14:54 standalone = 243 * Running mode, the port = 6379....Copy the code

These are services configured by default in a Sail environment. For more information about each service, refer to the official Sail documentation.

Next, access the application from your browser at:.

http://localhost
Copy the code

If all steps are successful, you will see a page that looks like this.

The application is now started.

You can now stop the Sail environment running on your terminal by typing CTRL+C.

Step 2 – Use a Laravel Sail

Laravel Sail provides several shortcuts to manage your development environment. Most of the commands and arguments are based on the default Docker Compose API.

Control environment

To put the environment into background mode, you can run:

./vendor/bin/sail up -d
Copy the code

To stop the Sail environment that was previously started in background mode, it can run.

./vendor/bin/sail stop
Copy the code

This does not delete the connected network or volume.

To restore an environment that was previously stopped with the sail Stop command, you can use the

./vendor/bin/sail start
Copy the code

To stop an environment while deleting all related resources such as volumes and networks, you can use the sail Down command. Note that this command deletes any previously created data that is only available within the container, such as records stored in the database.

./vendor/bin/sail down
Copy the code
OutputStopping laravel-tailwind-starter_laravel.test_1 ... done
Stopping laravel-tailwind-starter_redis_1        ... done
Stopping laravel-tailwind-starter_selenium_1     ... done
Stopping laravel-tailwind-starter_mysql_1        ... done
Stopping laravel-tailwind-starter_mailhog_1      ... done
Stopping laravel-tailwind-starter_meilisearch_1  ... done
Removing laravel-tailwind-starter_laravel.test_1 ... done
Removing laravel-tailwind-starter_redis_1        ... done
Removing laravel-tailwind-starter_selenium_1     ... done
Removing laravel-tailwind-starter_mysql_1        ... done
Removing laravel-tailwind-starter_mailhog_1      ... done
Removing laravel-tailwind-starter_meilisearch_1  ... done
Removing network laravel-tailwind-starter_sail
Copy the code

Check status and logs

If your environment fails, fix it.

./vendor/bin/sail up -d
Copy the code

When your environment is up and running, you can use: check the status of all active containers.

./vendor/bin/sail ps
Copy the code
Output Name Command State Ports ------------------------------------------------------------------------------------------------------------------------ -- -- -- -- -- -- -- -- - myapp_laravel. Test_1 start - the container Up 0.0.0.0:80 - > 80 / TCP, : : : 80 - > 80 / TCP, 8000/ TCP myapp_mailhog_1 MailHog Up 0.0.0.0:1025->1025/ TCP,:::1025->1025/ TCP, 0.0.0.0:8025->8025/ TCP,:::8025->8025/ TCP myapp_meilisearCH_1 tini -- /bin/sh -c./meili... Up (healthy) 0.0.0.00:7700 ->7700/ TCP,:::7700->7700/ TCP myapp_mysql_1 docker-entrypoint.sh mysqld Up (healthy) 0.0.0.00:7700 ->7700/ TCP,:::7700->7700/ TCP myapp_mysql_1 docker-entrypoint. 0.0.0.0:3306->3306/ TCP,:::3306->3306/ TCP, 33060/ TCP myAPP_redis_1 docker-entrypoint.sh redis... Up (healthy) 0.0.0.0:6379->6379/ TCP,:::6379->6379/ TCP myAPP_selenium_1 /opt/bin/entry_point.sh Up 4444/ TCPCopy the code

The output of the sail ps command will tell you which containers associated with that particular environment are currently active, which ports are being redirected, and more importantly, what state each container is in. In the previous example output, all the services are up.

To check the container logs when you run your environment in background mode, you can use.

./vendor/bin/sail logs
Copy the code

This will show you the latest log of all services.

Attaching to laravel-tailwind-starter_laravel.test_1, laravel-tailwind-starter_mailhog_1, laravel-tailwind-starter_mysql_1, laravel-tailwind-starter_redis_1, laravel-tailwind-starter_selenium_1, laravel-tailwind-starter_meilisearch_1 ... Mysql_1 | 2021-06-24 T15:08:06. 435530 z 0 [System] [MY - 010931] / Server/usr/sbin/mysqld: ready for connections. Version: '8.0.25' socket: '/ var/run/mysqld/mysqld. The sock' port: 3306 MySQL Community Server - the GPL.... Meilisearch_1 | [the 2021-06-24 T15: thus Z INFO actix_web: : middleware: : logger] 127.0.0.1:60874 "the GET/health HTTP / 1.1" 22 200 "-" "Wget" 0.000056... Laravel. Test_1 | [Thu Jun 24 15:08:07 2021] PHP 8.0.7 Development Server (http://0.0.0.0:80) started... Selenium_1 | 15:08:06. 864 INFO [SeleniumServer boot] - the Selenium Server is up and running on port 4444... Redis_1 | 1: M 24 Jun 2021 15:08:05. 280 * Ready to accept connections... Mailhog_1 | 2021/06/24 15:08:05 Serving under http://0.0.0.0:8025/Copy the code

You can also view the logs for each service by providing an extra parameter to the command call.

./vendor/bin/sail logs redis
Copy the code
OutputAttaching to laravel tailwind - starter_redis_1 redis_1 | 1:24 Jun 2021 15:08:05. C # 278 oO0OoO0OoO0Oo Redis is Starting oO0OoO0OoO0Oo redis_1 | 1:24 Jun 2021 15:08:05 C. 278 # Redis version = 6.2.4, bits = 64, commit = 00000000, modified=0, pid=1, just started ... Redis_1 | 1: M 24 Jun 2021 15:08:05. 280 * RDB memory usage when created 0.77 Mb redis_1 | 1: M 24 Jun 2021 15:08:05. 280 * The DB the loaded from disk: 0.000 seconds redis_1 | 1: M 24 Jun 2021 15:08:05. 280 * Ready to accept connectionsCopy the code

Run Artisan and Composer

When working with your Laravel application, you’ll often need to run the Artisan command to build, test, and manage your application. You will also need to run the Composer command to manage your PHP dependencies. In addition to the default Docker Compose API, Sail provides useful shortcuts to execute these commands in your application container (myapp_laravel.test_1 in the output of the example). With a regular Docker Compose setup, running Artisan would look like this.

Use only Docker Compose

docker-compose exec app php artisan
Copy the code

With Sail, the corresponding call is shortened to.

Run Artisan with Sail

./vendor/bin/sail artisan
Copy the code

You can run Composer in a similar way.

Run Composer with Sail

./vendor/bin/sail composer
Copy the code

For more information on all the features and commands, visit the official Laravel Sail documentation.

You are now familiar with how to manage your Sail development environment and how to run commands on application containers. In the next step, you’ll set up Tailwind CSS to design and beautify your landing page.

Step 3 – Set up the Tailwind CSS with Laravel

Next, you will install and set up Tailwind CSS to set up a landing page.

Make sure your Sail environment is up and running, then install the Laravel front-end dependencies with the NPM command, which is used to download and manage JavaScript packages.

./vendor/bin/sail npm install
Copy the code
Output...
added 1327 packages, and audited 1328 packages in 20s

99 packages are looking for funding
  run `npm fund` for details
...

Copy the code

Then, install with Tailwind and its dependencies.

./vendor/bin/sail npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
Copy the code
Output...
added 9 packages, removed 22 packages, changed 7 packages, and audited 1315 packages in 5s

99 packages are looking for funding
  run `npm fund` for details
...
Copy the code

Next, you need to create a configuration file for Tailwind. To do this, you’ll use NPX, which stands for _Node package executor _ and allows you to execute a Node package. The following NPX command will generate a new default Tailwind configuration for your application.

./vendor/bin/sail npx tailwindcss init
Copy the code

This will create a new configuration file named tailwind.config.js in the root directory of your project, which looks like this.

tailwind.config.js

module.exports = {
  purge: [].darkMode: false.// or 'media' or 'class'
  theme: {
    extend: {},},variants: {
    extend: {},},plugins: [],}Copy the code

Although there are different ways to set up Tailwind in a project, in this tutorial we will use Laravel Mix and Webpack to configure Tailwind. Both libraries are used to compile and output front-end resources.

Open the file webpack.mix.js with your code editor. It’s going to look something like this.

mix.js('resources/js/app.js'.'public/js')
    .postCss('resources/css/app.css'.'public/css'[//
    ]);
Copy the code

Laravel Mix uses PostCSS to compile CSS resources. Remove the // character and include the highlighted line below, which will add Tailwind CSS to the list of CSS resources to be processed.

Remove the // character and include the following highlighted line, which requires Tailwind as a PostCSS plugin.

webpack.mix.js

  mix.js("resources/js/app.js"."public/js")
    .postCss("resources/css/app.css"."public/css"[require("tailwindcss"),]);Copy the code

Save the file after making this change.

Next, include Tailwind in your application’s main CSS file. Open resources/ CSS /app.css in your code editor and add the following three lines to the file.

resources/css/app.css

@tailwind base;
@tailwind components;
@tailwind utilities;
Copy the code

Save when finished.

Next, you will need to build front-end assets with NPM.

./vendor/bin/sail npm run dev
Copy the code

You will receive output similar to the one below, with a line like the Compiled Successfully section highlighted indicating that you have integrated all the components into your Sail environment.

Output Laravel Mix v6.0.24 stocking Compiled Successfully in 5515ms ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┬ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ File │ Size │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ / js/app. Js 597 KiB │ │ │ CSS/app. The CSS 3.81 the MiB │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ webpack compiled successfullyCopy the code

Now that Tailwind is configured, you have built the front-end assets for your site. In the next step, you will create a new landing page for your application.

Step 4 – Create a landing page

With Tailwind’s configuration in place, you can now start building the front view of your application. In Laravel, templates are typically stored in the Resources/Views directory. The page you saw earlier when you opened the application in your browser (http://localhost) is defined in a template in that directory called welcome.blade.php.

In your code editor, open a new file named index.blade.php in the Resources /views directory.

The following example template defines an “About me” HTML page with some unstyled elements. It uses an example of an avatar, but you can replace it with your own image.

Create a new IMG directory in the public applications folder.

mkdir public/img
Copy the code

Save your favorite images in this new directory named profile_image.png.

In the following example, notice the use of the highlighted {{asset… }} Secondary line to define the path of CSS and image files. This function outputs the correct public path for the application resources in the public directory.

Copy this to your own index.blade.php.

resources/views/index.blade.php

<! doctypehtml>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Sammy the Shark - About Page</title>
    <meta name="description" content="My Application Description">
    <meta name="author" content="Sammy">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div>
    <img src="{{ asset('img/profile_image.png') }}" width="200" alt="avatar"/>
    <h1>Sammy the Shark</h1>
    <p>Content Creator</p>
    <p>Hello, I'm Sammy. I am a friendly shark interested in Linux, coding, and community.
        You can find out more about me in the following links:</p>
    <div>
        <div><a href="https://twitter.com/digitalocean">Twitter</a></div>
        <div><a href="https://www.linkedin.com/company/digitalocean">LinkedIn</a></div>
        <div><a href="https://instagram.com/thedigitalocean">Instagram</a></div>
    </div>
</div>
</body>
</html>
Copy the code

When you have finished editing its contents, save the file.

Now edit the routes/web.php file and modify the main route to use the newly created template. Open the file with your code editor and replace welcome with index to change the view used by the main application endpoint. When done, the updated routing declaration will look something like this.

routes/web.php

Route::get('/'.function () {
    return view('index');
});
Copy the code

Save the file. Now you can reload the application page in your browser and see the new index page. You’ll see a page that looks like this.

By default, Tailwind removes all styles of elements, which gives you the freedom to create your views by combining and mixing Tailwind’s CSS utility classes. In the next section, you’ll learn how to combine these utility classes to create a responsive “About me” page.

Step 5 – Shape your landing page with Tailwind CSS

Building responsive pages is an important front-end development requirement, because users may access your website or application from many different devices, each with a different screen size.

Tailwind provides a selector that can apply styles for each screen size. This way, you can create responsive containers by setting the minimum width as the default, and attach additional responsive dimensions to larger screens. For example, an element using class=” W-3/4 LG: W-1/2 “will set the default width to three-quarters of the width of the parent element, which works for smaller screens, but for larger screens (LG: selector) it will use half the width of the parent element.

Note that you can combine reactive selectors with any utility class, not just one that is dependent on the size of an element. For example, you can hide an element at a breakpoint, change its color, or even turn it into a grid with variable number of columns.

You can find all the available reactive selectors and their breakpoints in Tailwind’s official documentation.

The following template sets up a responsive content area in the center of the page, using a background gradient and an avatar example. For buttons, it uses a grid flow system that splits the container into three columns starting from the middle screen, but makes the button take up the entire size of the container when the page is accessed from a smaller screen.

In the code editor to open the previous step to create the resources/views/index. The blade. The PHP file, use the following template to replace the content.

resources/views/index.blade.php

<! doctypehtml>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Sammy the Shark - About Page</title>
    <meta name="description" content="My Application Description">
    <meta name="author" content="Sammy">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body class="bg-gradient-to-r from-blue-400 via-purple-600 to-blue-700">

<div class="w-3/4 lg:w-1/2 mx-auto rounded-md bg-gray-200 shadow-lg m-20 p-10 text-center">
    <img src="{{ asset('img/profile_image.png') }}" class="w-32 lg:w-1/6 bg-blue-600 mx-auto rounded-lg mb-4" alt="avatar"/>
    <h1 class="text-3xl">Sammy the Shark</h1>
    <p class="text-gray-500 pb-4">Content Creator</p>
    <p class="text-gray-700 mb-6">Hello, I'm Sammy. I am a friendly shark interested in Linux, coding, and community.
        You can find out more about me in the following links:</p>

    <div class="grid grid-cols-1 md:grid-cols-3 grid-flow-row gap-6">
        <div class="px-4 py-2 bg-blue-600 text-gray-100 rounded-md mr-4 hover:bg-blue-700"><a href="https://twitter.com/digitalocean">Twitter</a></div>
        <div class="px-4 py-2 bg-blue-600 text-gray-100 rounded-md mr-4 hover:bg-blue-700"><a href="https://www.linkedin.com/company/digitalocean">LinkedIn</a></div>
        <div class="px-4 py-2 bg-blue-600 text-gray-100 rounded-md mr-4 hover:bg-blue-700"><a href="https://instagram.com/thedigitalocean">Instagram</a></div>
    </div>

</div>
</body>
</html>
Copy the code

This template will produce the following pages.

And that’s how the page fits into different screen sizes.

In the updated template, each HTML element has some Tailwind classes and selectors applied to them. Tailwind uses a specific name for its utility classes to create a responsive layout. Each of the following is used in the sample template to create the final result.

  • bg-gradient-to-r: Creates a left-to-right one using the specified colorThe gradient.
  • w-1/3: Sets the width of the element to one third of the width of the parent element. In Tailwind, there areLots of different waysTo set the width of an element.
  • mx-auto: Centers the element.
  • rounded-md: createRounded corners, size is “medium” (MD).
  • shadow-lg: Create ashadows, size is “large” (LG).
  • mr-*And othermVariant: Used to set elementsmargin.
  • pb-*And otherpVariant: Used to set elementspadding.
  • hover:bg-blue-700In:hoveringTo change the selected elementThe background color.

Check Tailwind’s official documentation for a complete reference to all available utility classes.

conclusion

In this tutorial, you have bootstrap a new Laravel application using Laravel Sail and Tailwind CSS. You also used Tailwind’s powerful utility classes to create a responsive “About me” landing page.

If you want to build a more complex landing page, and learn more about Tailwind in the process, you can follow our guide: How to Build a stylish landing page with Tailwind CSS, detailing how to create a complete website page using this framework.

If you want to learn more about Laravel in a project-based guide, you can refer to our series how to Build a link landing Page in PHP with Laravel. For more PHP content, check out our PHP TAB.