How to Dockerize a Symfony App for Production

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

Introduction

Dockerizing your Symfony application can significantly simplify the deployment process and ensure consistency across different environments. In this tutorial, you’ll learn how to package your Symfony app into a Docker container, ready for production. We’ll go from setting up a basic Docker configuration to optimizing your setup for production use.

Prerequisites

  • A Symfony application
  • Docker installed on your local machine
  • Basic understanding of Docker concepts

The Steps

Step 1: Create a Dockerfile

Begin by creating a Dockerfile at the root of your Symfony project. This file defines the steps to build your Docker image. Here’s a basic example:

FROM php:8.1-fpm
# Install dependencies
RUN apt-get update && apt-get install -y \ 
        libpng-dev \ 
        libonig-dev \ 
        libxml2-dev \ 
        zip \ 
        unzip

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Set working directory
WORKDIR /var/www

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www

# Change current user to www
USER www-data

EXPOSE 9000
ENTRYPOINT ["php-fpm"]

In this Dockerfile, we start from the php:8.1-fpm image, install necessary extensions, set the correct permissions, and define the entry point.

Once you have your Dockerfile set up, build your image with:

docker build -t my-symfony-app .

This command will use the Dockerfile to build an image named my-symfony-app.

Step 2: Set Up Docker Compose

For a production setup, it’s common to have multiple services (like a web server and database). Docker Compose lets you configure these in a docker-compose.yml file. Create one in the root of your project:

version: '3.8'

services:
  app:
    build: .
    container_name: symfony_app
    restart: unless-stopped
    working_directory: /var/www
    volumes:
      - ./:/var/www
    environment:
      - APP_ENV=prod
    depends_on:
      - db

  db:
    image: mysql:5.7
    container_name: symfony_db
    restart: unless-stopped
    environment:
      - MYSQL_DATABASE=project_name
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
      - MYSQL_ROOT_PASSWORD=root_password
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"
volumes:
  db_data:
    driver: local

This defines two services: app, our Symfony application, and db, a MySQL database. The compose file also takes care of networking between containers, environment variables, and data persistence through volumes.

To spin up your services, run:

docker-compose up -d

Step 3: Optimize Your Dockerfile for Production

When it comes to production, it’s all about optimization and security. We will make some adjustments to our Dockerfile to improve efficiency and reduce the image size.

Multistage Builds

Utilize multistage builds in your Dockerfile to separate the build stage from the production stage:

# Build stage
FROM php:8.1-fpm AS symfony_build
# ...Same steps as before to set up the environment...

# Production stage
FROM php:8.1-fpm
COPY --from=symfony_build /var/www /var/www

This pattern allows you to have a build environment with all the necessary tools to compile your application, while the production image remains clean and lightweight.

Configuration for Production

Ensure your environments are set up correctly for production, including environment variables that reference production databases, cache systems, etc.

Conclusion

In conclusion, dockerizing a Symfony app can streamline your deployment process and maintain environment consistency. With this guide, you should now have a clear path towards preparing your application for production with Docker.