Start a new Symfony5 project with docker-compose, Nginx , Php 7.4 and MariaDB
This article will contain all the steps necessary to create a symfony5 project with docker-compose, nginx and php 7.4.
File structures
To start, we’re going to need a docker folder that will contain all the necessary folders for each container. For our example, we will use nginx, php as well as mariaDB
Once this is done, we add Dockerfiles files to create our structure.
Now it is necessary to create the folder that will contain, the symfony code.
For this, in the terminal the following command imports all the desired files, in this example I create the folder “symfony”
symfony new symfony --full --no-git
By using –no-git, the symfony git will not configure and it is possible to add files to your repository without any problems.
Start Dockerfile files
The use of alpine versions allows you to have all the necessary features without the superfluous.
Database file
Change the Dockerfile file in the database folder
FROM mariadb:latest CMD ["mysqld"] EXPOSE 3306
FROM: Tells Docker which image to use, the format is repository:version
CMD: indicates which command it should initially launch. In this example, it starts the database server
EXPOSE: indicates which ports should be visible to Docker’s internal network. Other containers can use this information to connect to it.
In the nginx folder
The Dockerfile file in the nginx folder
FROM nginx:alpine CMD ["nginx"] EXPOSE 80 443
In the php-fpm folder
FROM php:fpm-alpine RUN docker-php-ext-install pdo_mysql CMD ["php-fpm"] EXPOSE 9000
In order to use a database, we also install the extension pdo_mysql.
Creating the docker-compose file
At the root of the docker folder, create a file called docker-compose.yml. It is in this one that we configure and connect all the containers between them.
version: '3.8' services: php-fpm: nginx: database:
The Build context
In order to reach the other containers, it is necessary to define the build context with a path relative to it. Like this:
services: database: build: context: ./database
Setting up the database
For the database, certain attributes are mandatory, the root password as well as a database.
It is in the environment section that one can indicate der variables to Docker. In our, the name of the database, the password as well as a user for example. In our example, this looks like this:
database: build: context: ./database environment: - MYSQL_DATABASE=symfonydb - MYSQL_USER=user - MYSQL_PASSWORD=secret - MYSQL_ROOT_PASSWORD=docker
Configuration of php-fpm
By default Docker cannot see our files or access them. To do this we use the volume section in our docker-compose.yml file
php-fpm: build: context: ./php-fpm volumes: - ../symfony:/var/www/symfony
the format is – host:container
Configuration of the nginx server
For the nginx server access to the file is also necessary
nginx: build: context: ./nginx volumes: - ../symfony:/var/www/symfony
Unfortunately this is not enough to run a server, we also need to expose ports and have configuration files.
Exposing ports
the ports section, allows to define which ports should be accessible from our machine, for nginx it is 80 and 443
nginx: build: context: ./nginx volumes: - ../symfony:/var/www/symfony ports: - "80:80" - "443:443"
By default, nginx only allows you to load HTML files, for symfony we need php-fpm.
Configuration files
To start we’re going to need new configuration files
As our php-fpm service is its own container, we need to tell Nginx how to find it. In the conf.d/default.conf file just add these lines
#conf.d/default.conf upstream php-upstream { server php-fpm:9000; }
Then in the sites folder, we can create the configuration file needed for symfony. This is a variant of what is find on the symfony site.
#sites/default.conf server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; server_name localhost; root /var/www/symfony/public; index index.php index.html index.htm; location / { try_files $uri /index.php$is_args$args; } location ~ ^/index\.php(/|$) { fastcgi_pass php-upstream; 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; } }
In the file we can see fastcgi_pass php-upstream; which corresponds to our container, it is the reference to that create in conf.d/default.conf
Now we also need to change the nginx.conf configuration file
#nginx.conf user nginx; worker_processes 4; daemon off; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; # Switch logging to console out to view via Docker #access_log /dev/stdout; #error_log /dev/stderr; sendfile on; keepalive_timeout 65; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-available/*.conf; }
Both lines includes configures nginx with the other two files created.
Now it is necessary to add all these files to the container by modifying the nginx section in docker-composer.yml
nginx: build: context: ./nginx volumes: - ../symfony:/var/www/symfony - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/sites/:/etc/nginx/sites-available - ./nginx/conf.d/:/etc/nginx/conf.d depends_on: - php-fpm ports: - "80:80" - "443:443"
Adding depends_on it is indicated that php-fpm should be started before nginx.
docker-composer.yml final
When you put all the pieces together, the file looks like this:
version: '3.8' services: php-fpm: build: context: ./php-fpm volumes: - ../symfony:/var/www/symfony nginx: build: context: ./nginx volumes: - ../symfony:/var/www/symfony - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/sites/:/etc/nginx/sites-available - ./nginx/conf.d/:/etc/nginx/conf.d depends_on: - php-fpm ports: - "80:80" - "443:443" database: build: context: ./database environment: - MYSQL_DATABASE=symfonydb - MYSQL_USER=user - MYSQL_PASSWORD=secret - MYSQL_ROOT_PASSWORD=docker
Then into the terminal in the docker file:
docker-compose up
Then we can call the url: http://localhost/
and voilà your symfony is ready: