Using lando to run laravel in docker

Laravel comes with laravel sail, which is great! Personally I prefer using Lando as I find it gives me alot more features, like tooling, proxy and events.

I suggest looking through the docs to see if lando is for you!

This tutorial assumes that you have already installed lando and docker by following the guide on the website

You do not need php or composer installed locally to follow this guide!

Set up a laravel project!

First we will initialize a new laravel project.

If you already have an existing project, just go into the root of the project and run lando init and follow the guide. After that you can skip to the next section!

Go to the root of where you store your web projects. Now run the following command. Be sure to replace my-app before you run it! The name cannot contain spaces!

SITENAME=my-app; docker run --rm --interactive --tty \
--volume $PWD:/app \
--user $(id -u):$(id -g) \
composer create-project laravel/laravel $SITENAME ^9.0 \
&& cd $SITENAME \
&& lando init --source cwd --webroot ./public --recipe laravel --name $SITENAME

This is currently untested on Windows, so if it works/fails, feel free to send me a message on twitter at @rsinnbeck

When the command has completed, you will now have a brand new laravel project with the name you provided. In the root of the new directory you will find a file named .lando.yml. This is the config file generated by lando.

It will look something like this

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public

These lines mean the following:

  • name: The name lando uses to reference the site. This will also be prefix for the sitename when we open it in the browser later on!
  • recipe: Lando uses recipes to make setting up a new project really fast. Here we are using the laravel recipe config: Here we can pass config values to the recipe. We have set it to use the ./public directory to serve files

Configure the docker containers

Lets add some more items to our config so it resembles more what we normally use with laravel

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public
5 php: '8.0'
6 via: apache #or nginx
7 database: mysql #or mariadb or postgres
8 cache: redis #or memcached

Here we are setting which php version to use and we are telling lando which webserver, database and cache-server to install. All the containers can be suffixed with a version by using eg. :2.0

Next set up your .env file with the correct values. If you are using postgres, the database config is a bit different. Refer to the docs for the correct values.

1DB_CONNECTION=mysql
2DB_HOST=database
3DB_PORT=3306
4DB_DATABASE=laravel
5DB_USERNAME=laravel
6DB_PASSWORD=laravel
7 
8REDIS_HOST=cache

Time to try it out

Now it's time to start our new app! Simply run

lando start

Lando will now download the correct containers and start them all up. If all went well you should see a message looking something like this

1Your app has started up correctly.
2Here are some vitals:
3 
4 NAME my-app
5 LOCATION /path/to/my-app
6 SERVICES appserver, database
7 APPSERVER URLS https://localhost:49548
8 http://localhost:49549
9 http://my-app.lndo.site/
10 https://my-app.lndo.site/

Your ports are probably different that above, but that is just because lando will find a random port on each run. Notice the services. These are the names of the containers we have built. The appserver is the main container used for running php!

You can now try opening one of the http:// links, and you should see the laravel welcome page!

Using laravel through lando

So the first thing we want to do is to make sure that all migrations are run. To run artisan commands we just replace php with lando, and it will run artisan inside the php container.

lando artisan migrate

Try out a new more artisan command to see that it actually works just as running it locally!

Or you can use composer

lando composer

We can also run arbitrary php commands in the same way

lando php -v

This should give you the php version number running inside the container

We can even jump right into the php container by running

lando ssh

You are now inside the container, and can run any command as if you were on your own computer. Type exit and his enter to get back to your own machine.

Tooling

Running migrations is something we need to do quite often, so let us make a handy shortcut for it!

Add the following to your .lando.yml file

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public
5 php: '8.0'
6 via: apache
7 database: mysql
8 cache: redis
9tooling:
10 migrate:
11 service:
12 cmd: php artisan migrate

We are adding a new command (tool) called migrate. It will be run on the service named appserver which is the one running php. The command it will run is php artisan migrate

Now try running

lando migrate

As you can see it works, and we can now shorten the command just a bit. Feel free to add your own commands to make your life a little easier.

You can always get a full list of available commands by running lando

Add a container for running laravel mix

In case you want to run laravel mix (or similar) we need a container for that. Add the following to your .lando.yml file

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public
5 php: '8.0'
6 via: apache
7 database: mysql
8 cache: redis
9services:
10 node:
11 type: node:16
12 scanner: false
13 build:
14 - npm install
15tooling:
16 migrate:
17 service: appserver
18 cmd: php artisan migrate

Here we are telling lando to add an extra service, named node.

We want it to install node version 16. Lando will automatically try scanning the new service to see if it can connect to it using http. As we do not want this, we will disable the scanner.

Lastly we will tell it to run npm install as soon as it is has added the new service (just so we don't forget)

Run lando rebuild -y to rebuild all the services, and add the new node service. As all the previous containers already exist and haven't changed, it should be pretty fast.

Like we did with the migrate command earlier we will now also add a command for running npm Add the following to your .lando.yml file under the tooling: section

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public
5 php: '8.0'
6 via: apache
7 database: mysql
8 cache: redis
9services:
10 node:
11 type: node:16
12 scanner: false
13 build:
14 - npm install
15tooling:
16 migrate:
17 service: appserver
18 cmd: php artisan migrate
19 npm:
20 service: node
21 cmd: npm

Now run lando npm run dev to confirm that it's working

Add mailhog to catch mails

Let us also add mailhog, to make sure we don't accidentially send emails to our clients

First add the service

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public
5 php: '8.0'
6 via: apache
7 database: mysql
8 cache: redis
9services:
10 node:
11 type: node:16
12 scanner: false
13 build:
14 - npm install
15 mail:
16 type: mailhog
17 portforward: true
18 hogfrom:
19 - appserver
20tooling:
21 migrate:
22 service: appserver
23 cmd: php artisan migrate
24 npm:
25 service: node
26 cmd: npm

Here we add the mailhog service with the name mail. We want to let the scanner check this service as it actually has a webinterface, and we tell lando to make sure that all http requests are directed to the container. We also tell mailhog that it should grab mails from the appserver container.

Run lando rebuild -y to start the service.

Once the service is started, lando will show you an url on which you can see the mailhog interface. Here all emails from laravel will end up.

To make sure it works, change your .env file to use the new mail service

1MAIL_DRIVER=smtp
2MAIL_HOST=mail
3MAIL_PORT=1025
4MAIL_USERNAME=null
5MAIL_PASSWORD=null

Now when we send emails from laravel, they will be caught by mailhog.

Proxy

Before we wrap things up lets just add a proxy to the mailhog service, to make using it a bit easier.

Add the following to the bottom of your .lando.yml file (replace my-app with your actual project name)

1name: my-app
2recipe: laravel
3config:
4 webroot: ./public
5 php: '8.0'
6 via: apache
7 database: mysql
8 cache: redis
9services:
10 node:
11 type: node:16
12 scanner: false
13 build:
14 - npm install
15 mail:
16 type: mailhog
17 portforward: true
18 hogfrom:
19 - appserver
20tooling:
21 migrate:
22 service: appserver
23 cmd: php artisan migrate
24 npm:
25 service: node
26 cmd: npm
27proxy:
28 mail:
29 - mail.my-app.lndo.site

Run lando rebuild -y and when it is done you will see that lando now have assigned the the mail service to the provided url. This makes opening it in the future alot easier, as we can bookmark the url.

Wrap-up

We have now successfully set up a new laravel app using lando. I hope it was easy to follow and that you will be using lando in the future.

If you want more lando tutorials, you can send me a message on Twitter at @rsinnbeck