How to Dockerize a Laravel app for production

Updated: January 15, 2024 By: Guest Contributor Post a comment

Introduction

Dockerizing your Laravel application can streamline the deployment process and ensure consistent environments across different stages of development. This guide will lead you through preparing a Docker container for your Laravel application that is optimized for production.

Before proceeding, ensure you have the following installed on your system: Docker, Docker Compose, Laravel CLI, and git if your project is version-controlled.

Setting up the Docker Environment

To begin, create a file named Dockerfile in the root of your Laravel project. This file will define the Docker image for your application.


# Start from a PHP image with Apache
FROM php:7.4-apache

# Enable Apache mod_rewrite
RUN a2enmod rewrite

# Install PHP extensions
RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev libfreetype6-dev unsatisfactory and -y zip unzip && docker-php-ext-configure gd --with-freetype=/ usr/include/ --with-jpeg=/usr/include/ && docker-php-ext-install gd pdo pdo_mysql

# Copy your applications code to the image
COPY . /var/www/html

# Copy over and run the composer install command
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer install --no-dev

# Adjust the permissions
RUN chown -R www-data:www-data /var/www

This Dockerfile begins by specifying a PHP image with Apache, enables required Apache modules, installs necessary PHP extensions, copies the application code to the container, uses Composer to install dependencies, and adjusts file permissions.

Optimizing for Production

Laravel has several commands that should be run before deploying to production. Add the following lines to your Dockerfile to handle configuration caching, route caching, and compiling views:


# Laravel optimization commands
RUN php artisan config:cache && php artisan route:cache && php artisan view:cache

These commands help reduce response times by doing the heavy lifting ahead of time, rather than on each request.

Managing Environment Variables

It’s important not to include .env files with sensitive data in your image. Rather, use environment variables which can be set on the Docker runtime. We’ll manage this by introducing Docker Compose.

Create a docker-compose.yml file:


version: '3'
services:
  app:
    build: .
    ports:
      - "80:80"
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=database
      - DB_PORT=3306
      # And other environment variables
    volumes:
      - .:/var/www/html

  database:
    image: 'mysql:5.7'
    environment:
      - MYSQL_DATABASE=homestead
      - MYSQL_USER=homestead
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=secret
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

This docker-compose.yml tells Docker how to build the application image, which ports to map, adds environment variables for both the application and the database using the MySQL image, and sets up volumes for data persistence.

Building and Running the Container

To build and start your containers, use:


docker-compose up --build

You’ll see Docker build the image according to your specifications and then start the containers.

Conclusion

Dockerizing your Laravel application aids in creating a seamless transition from development to production. It ensures that your configurations remain constant, which can significantly reduce the occurrence of ‘works on my machine’ issues.