DEV Community

Gerard Rico Botella
Gerard Rico Botella

Posted on

How to setup docker-compose for Symfony projects

[OPTIONAL] Create symfony project

For this example, we create a simple symfony project using composer create-project command using package symfony/skeleton:

composer create-project symfony/skeleton example
Enter fullscreen mode Exit fullscreen mode

If you don't have composer installed, you can find how to do it in it's official website

Create PHP-FPM Dockerfile

Create a file named Dockerfile in your project root and write the following content:

FROM php:8.1-fpm

COPY --from=composer /usr/bin/composer /usr/bin/composer
Enter fullscreen mode Exit fullscreen mode

In this example we are using php:8.1-fpm image from php official images but other FPM images are valid too if its PHP version satisfies symfony project requirements.

In order to manage composer dependencies, we copy composer binary from composer official image using multi-stage builds

Create nginx configuration

Create nginx.conf file in your project root and write the following content:

events {
    worker_connections 1024;

http {
    server {
        root /var/www/app/public;

        location / {
            try_files $uri /index.php$is_args$args;

        location ~ ^/index\.php(/|$) {
            fastcgi_pass example_php:9000;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;

            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;


        location ~ \.php$ {
            return 404;

        error_log /var/log/nginx/api_error.log;
        access_log /var/log/nginx/api_access.log;

Enter fullscreen mode Exit fullscreen mode

The important things here are:

  • root /var/www/app/public defines the directory where de index file is located.
  • fastcgi_pass example_php:9000 instructs nginx to execute PHP scripts using server example_php and port 9000.

Puting all together

To comunicate nginx with php, we create docker-compose.yaml file in project root with the following content:

    container_name: example_nginx
    image: nginx:1.21.3-alpine
    restart: on-failure
      - './:/var/www/app:ro'
      - './nginx.conf:/etc/nginx/nginx.conf:ro'
      - "9081:80"
      - example_php

    container_name: example_php
      context: .
    working_dir: /var/www/app/
      - './:/var/www/app/'
Enter fullscreen mode Exit fullscreen mode



Indicates docker-compose the image that should be used to create the container. You can find more official images here


Indicates when should the container be restarted. You can find more info in compose specification


Makes files available for the service container. In this case, we are using two volumes:

  • './:/var/www/app:ro' that binds project files to /var/www/app directory in readonly mode
  • './nginx.conf:/etc/nginx/nginx.conf:ro' that binds nginx configuration file to /etc/nginx/nginx.conf in readonly mode

You can find more info about volumes here.


Binds container port 80 to localhost 9081. This allows us to access out symfony application using URL http://localhost:9081.

You can find more info about ports here


Expresses that this service dependens on service example_php. Remember that we configured nginx to use example_php as fastcgi_pass server.

You can find more info about depends_on here



Defines the path to the directory where the Dockerfile is located. In this case, we have both Dockerfile and docker-compose.yml in the same directory and that's why we simple use ..

You can find more info about build configuration here


Sets the application root directory as working directory to simplificate running application commands using docker exec


In this service, we make all application files available in read and write mode in order to allow write operations like cache generation and install dependencies.

Runing the app

To run the app, we just need to run docker-compose up and access our app using the URL http://localhost:9081.

Top comments (2)

ramlev profile image
Hasse R. Hansen

Or checkout ddev, so awesome and does all the magic for you

jeremymoorecom profile image
Jeremy Moore

nice write-up. I've always ran composer on an external image accessing the same code. I'll have to try including it as you demonstrated.