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 {
        server_name  example.app;
        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;

            internal;
        }

        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:

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

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

example_nginx

image

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

restart

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

volumes

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.

ports

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

depends_on

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

example_php

context

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

working_dir

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

volumes

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)

Collapse
 
ramlev profile image
Hasse R. Hansen

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

Collapse
 
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.