How to Dockerize and Deploy Laravel

How to Dockerize and Deploy Laravel

Lukas Mauser - Co-Founder von sliplane.ioLukas Mauser
5 min

This Dockerfile packages your Laravel app with FrankenPHP, a modern PHP server that runs your app and serves HTTP from a single process on a single port, which is exactly what you want in a container.

If you're just here to copy and paste, here's the final Dockerfile that will produce an image for your Laravel app:

Dockerfile
FROM dunglas/frankenphp:1-php8.3-alpine

# Grab Composer from the official image
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

# Install the PHP extensions Laravel commonly needs
RUN install-php-extensions pcntl pdo_pgsql pdo_mysql gd zip intl opcache

WORKDIR /app

# Install dependencies first so this layer is cached when only source changes
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist

# Copy the rest of the app and build the optimized autoloader
COPY . .
RUN composer dump-autoload --optimize

# Serve through our own Caddyfile
COPY Caddyfile /etc/caddy/Caddyfile

EXPOSE 8080
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]

FrankenPHP is built on the Caddy web server, so it reads a small Caddyfile. Put this next to your Dockerfile:

{
    frankenphp
    auto_https off
}

:8080 {
    root * /app/public
    encode gzip
    php_server
}

And here's the .dockerignore file:

vendor
node_modules
.git
.env
storage/logs/*

To build and run the image, use these commands:

docker build -t laravel-app .
docker run -p 8080:8080 laravel-app

Not just here to copy and paste? Let's go over what's happening in the Dockerfile!

The Setup

For this tutorial, I assume you have a working Laravel project. The classic way to run Laravel in production is nginx in front of PHP-FPM, which means two processes, a process manager, and a fair amount of config. Inside a container that is more moving parts than you want.

FrankenPHP replaces all of that. It is a single binary that embeds PHP and a web server, so one process serves your app on one port. That maps perfectly onto how a platform runs a container, and it is fast because the runtime stays warm between requests.

The Dockerfile

  1. Base image:
  • Uses dunglas/frankenphp:1-php8.3-alpine, which bundles PHP 8.3, the FrankenPHP server, and the handy install-php-extensions helper.
  1. Composer and extensions:
  • Copies the Composer binary from the official Composer image so we don't install it by hand.
  • Installs common Laravel extensions. Adjust the list to match your app, for example drop pdo_mysql if you only use Postgres.
  1. Dependency installation:
  • Copies only composer.json and composer.lock first, then runs composer install without dev dependencies. Because this happens before the rest of the code is copied, Docker can cache it and skip reinstalling packages when you only change application code.
  1. Application code:
  • Copies the project and runs composer dump-autoload --optimize to generate a fast class map for production.
  1. Serving:
  • Copies our Caddyfile, which points the web root at Laravel's public folder and enables php_server. auto_https off is set because your hosting platform terminates TLS for you, so FrankenPHP just needs to speak plain HTTP on port 8080.

One thing to keep in mind: Laravel reads its configuration from environment variables at runtime, so set APP_KEY, your database credentials, and the rest as environment variables on your host rather than baking a .env file into the image.

Deployment

You can deploy this Docker container to any cloud provider that supports Docker. For example, you could use platforms like Heroku, DigitalOcean, or AWS ECS. Because I am the co-founder of Sliplane, I will show you how to deploy it there.

After signing up, you can create a new service by selecting your GitHub repository. Then keep the default settings, add your environment variables such as APP_KEY and the database connection, and click deploy.

Sliplane Dashboard

After deployment your Laravel app will be available under a subdomain of sliplane.app, usually it's just your service name.

You can also see the logs of your app, view metrics such as CPU and memory usage, add persistent storage for uploads, and much more. Whenever you push to your repository, Sliplane will automatically deploy your app.

If you want to try out Sliplane, the first 2 days are free! Try it out and let me know what you think :)

Deploy Laravel in 2 minutes 🚀

Push your repo to GitHub and let Sliplane build and deploy your Laravel app for you. The first 2 days are free.

Next Steps

Once the app is running, you'll probably want to run php artisan migrate on deploy and cache your config with php artisan optimize. Both fit nicely into a small startup script. Need a hand with that, or with connecting a managed database? Feel free to reach out!

Cheers,

Lukas

Welcome to your cloud platform

Sliplane makes it simple to deploy and scale your apps in the cloud. Start with a container or your favorite framework and grow from there. Try it now and get started in minutes!