How to Dockerize a Laravel App to run in Laravel Forge


3 min read

So I'm almost sure you were already in the previous blog post. If not, you might want to visit How to deploy Docker Applications with Laravel Forge.

  • Note: Servers for demo purposes are now deleted, which will break URLs in the screenshots

This will be a "show by example", so let's build an App from scratch and deploy it!

Have your application ready

Let's make a fresh Laravel Application with Sail Builder

curl -s ",redis" | bash

cd example-docker-forge

sail up -d

When it finishes, you should be up and running! ๐Ÿš€


Let's get some more Docker magic into it!

So now, let's make this really easy, by using a package I built. Run the following commands:

composer require ijpatricio/docker-for-forge --dev

php artisan dockerEnv:install

It will ask you a few questions:

  • App Domain: The host that will be registered with Traefik, routing requests from such host to that container (service).
  • App Name and Vendor Name are used to populate the docker-compose.yml


For the time being, it makes a single container, with Supervisor (as in Laravel Sail) guaranteeing the webserver running (Nginx), the PHP interpreter (PHP-fpm), and cron (scheduling). Take into consideration using this "as-is" just with a single container. More complex scenarios are possible; this is keeping everything simple for the sake of understanding the basics!

I could go into details, but everything is taken care of regarding permissions so that Laravel Forge can read the logs in the UI, we can mount a storage folder, can run commands, and more. Maybe in another post, I could explain things further!

The build will use multiple steps, keeping the image lean. Builds frontend, installs composer dependencies, and more. The sensible basics have been covered. Customize at taste!

Also, .env variables can be used to change some values, but I kept things in the repo for simplicity.

Before committing the code, let's do one more thing:

mv docker-compose.yml

echo "docker-compose.yml" >> .gitignore

This is so that each environment will use a specific docker-compose. For example, we locally have a database, but in production, we most likely have that service separated in another VPS.

Commit your code, let's deploy!

On to Laravel Forge

Back on the UI, let's add a website.


And we should get something like this. Use your repository. Un-check "Install Composer Dependencies".


We arrive on the App tab. We now change the deploy script accordingly.


And here is the code:

cd /home/forge/example-docker-forge

git pull origin $FORGE_SITE_BRANCH

cp docker-compose.yml

docker-compose build

docker-compose up -d --remove-orphans

# Run commands as `forge` user, not `root`
function forgeCmd {
    docker-compose exec example-docker-forge bash -c "gosu forge bash -c \"$@\""

# Run this just the first time, so it doesn't keep changing
forgeCmd "php artisan key:generate"

# add route cache, db migrate, and your other commands as you see fit!
# forgeCmd "php artisan migrate --force"

Check that environment variables are properly set!


The build can now run!


Ta-daaaa ๐Ÿš€

Logs are available from the UI:


Storage folder is mounted into the container. This app has its own instance of Redis, so no need for prefixes and so on!

And of course, our website is live, and SSL secured:


Happy coding, happy deploys ๐Ÿ˜ƒ