Docker for Symfony 4

This blog post is an introduction to devs who want to start using Docker with Symfony4. It will guide you through creating a Symfony 4 project running on Docker.

Before we start, you’ll need to install Docker in your machine. You can download it from the official website.

Once Docker is installed, I strongly recommend playing with the getting started guide. Here the guide for macs and here the guide for windows. However, if you’re lazy like me, just use this command to make sure it’s installed.

docker --version

Once all of that is out of the way, we can start with the Symfony 4 project and the Docker environment that will run it.

For the sake of the example, I’ve created a local environment running PHP5 to make things a bit trickier, since Symfony4 runs on PHP7.

Let’s try to create an empty SF4 skeleton on my local machine.

composer create-project symfony/skeleton symfony

Right off the bat I get the following error

[InvalidArgumentException]
Could not find package symfony/skeleton with stability stable in a version installable using your PHP version 5.6.29.

So as you can see, we’ve created an environment running PHP5 and we cannot create a SF4 project, which runs on PHP7. Docker should help us solve this problem 🙂

We have two cases I’m going to tap on.

Case 1: I’m creating a SF4 project from scratch and I want to set up a development environment with Docker.

Step1: Clone the docker-symfony4 repository which has the docker configuration files.

git clone https://github.com/joeymasip/docker-symfony4.git

Step2: Create the Symfony project skeleton.

First off, let’s start docker containters with the project we just downloaded.

#cd to the location where you cloned the project
cd ~/Development/docker-symfony4
#start the containers
docker-compose up -d 

This command starts the containers. The parameter -d makes them run in the background. If you omit the -d you’ll see the log.

Docker should start building (if it’s the first time for these images) and running with the containers in the background.

We will need to create the symfony project inside the php image bash, since it’s the only place we have PHP7. Remember we still have PHP5 in our machine, so first thing is to log into the bash for the php7 image.

docker-compose exec php-fpm bash

Once in there, we’re in a PHP7 image, so we should be able to create the skeleton for the symfony project.

#inside php-fpm bash
composer create-project symfony/skeleton symfony

Step3: Move the contents of the skeleton into the root of the application.

Unless you want to change the config of the working dir inside the docker-composer.yml, we need the symfony project to be in the root folder. Moreover, we can not clone the contents into the root folder directly like so (composer create-project symfony/skeleton .) because the installer deletes the contents of the folder you’re cloning into. Since it’s too risky, this option is not allowed. More info here.

Long story short, I’ve found this is the cleaner way to do it.

#inside php-fpm bash
mv /application/symfony/* /application
mv /application/symfony/.* /application

Now we can delete the empty folder we used for creating the skeleton

#inside php-fpm bash
rm -Rf /application/symfony

Step4: Require the components.

We can require whatever components we need.

#inside php-fpm bash
cd /application

composer require annotations
composer require --dev profiler
composer require twig
composer require orm
composer require form
composer require form validator
composer require maker-bundle

These are just a few, feel free to add the ones you want.

Step5: Creating some sample code in Symfony 4 project.

Now lets create a controller to test a sample route to make sure everything works.

#inside php-fpm bash
cd /application

bin/console make:controller Pizza

Now, open a new chrome tab and type the following URL. The port is the one we set up in the docker-compose.yml – If you check the dictionary of the ngix config, you can see that port 8000 maps the 80, which is the usual webserver port.

http://localhost:8000/pizza

We should now see our new controller action rendering a response.

Step6: Sync de database.

Finally, to sync the database, you need to update the .env file with the variables we set on the mysql image.

.env file that has been generated when requiring the orm package in Symfony4.

DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name

So if you check the docker-compose.yml file, you’ll see the credentials under the mysql configuration. So change the file to

DATABASE_URL=mysql://dbuser:dbpw@mysql:3306/docker_symfony4

Finally, let’s restart the containers

docker-compose down
docker-compose up -d
docker-compose exec php-fpm bash

Now inside the bash, you should be able to

#inside php-fpm bash
bin/console doc:sch:crea

You can connect an external database client such as Sequel Pro or MysqlWorkbench.

For the credentials remember to put again the ones we set in the mysql image.

Host: 0.0.0.0
Username: dbuser
Password: dbpw
Port: 8002

Also as a reminder, every time you composer down or kill the mysqld image, your schema will disapear! This not only means you’ll have to recreate again the following time, it also means the data will be lost. So make sure to dump the data if you need it later, or create some demo data/fixtures so you don’t have to add data manually.

Case 2: I already have a SF4 project

Maybe you cloned from elsewhere, or maybe you created it in the past with PHP7 in your local machine.

Step1: Clone the docker-symfony4 repository which has the docker configuration files.

git clone https://github.com/joeymasip/docker-symfony4.git

Step2: Move the files from the docker-symfony4 project folder you just cloned into your Symfony project root.

Move the docker-compose.yml and the folder named phpdocker containing nginx and php-fpm config for it to the root of your Symfony4 project.

Step3: Start the docker images inside your Symfony4 project folder.

cd into your Symfony project folder and type the following command

docker-compose up -d

This command starts the containers. The parameter -d makes them run in the background. If you omit the -d you’ll see the log.

Docker should start building (if it’s the first time for these images) and running with the containers in the background.

Now, open a new chrome tab and type the following URL. The port is the one we set up in the docker-compose.yml – If you check the dictionary of the ngix config, you can see that port 8000 maps the 80, which is the usual webserver port.

http://localhost:8000
http://localhost:8000/whatever-slug-you-want-from-your-project

You should see it working.

You’re already set up to develop, so happy coding with docker!

Disclaimer: The project container I created has been generated in phpdocker.io


Also published on Medium.

20 thoughts on “Docker for Symfony 4”

    1. Thank you Aisekhiel! 🙂

      Yes I’ve also downgraded to MySQl 5.6 or PostgreSql, depending on project.

      About the permissions, yes, inside the php-fpm image, root is the owner of all files. However, I usually develop on the host machine (in PhpStorm), so my user has the permissions for all the project files. This guide is by no means to be used in a production environment, it’s intended to develop only.

      If you need different permissions, you would probably have to create a user inside the image, maybe with an entry point or in the Dockerfile. Check out this stackoverflow question.

      1. Oh ! Ok, I was thinking about this for the permissions, I’m a little bit new with Linux (Ubuntu) so I prefer to work with my classic user instead of root user.

        But thanks again ! I’ll see later if I create my user in the Dockerfile or just set the root perms to him 🙂

  1. Thank you for this clear tutorial.

    When I try to connect to the DB with Sequel Pro (host 0.0.0.0, port 8002) I get the following error:

    MySQL said: Authentication plugin ‘caching_sha2_password’ cannot be loaded: dlopen(/usr/local/lib/plugin/caching_sha2_password.so, 2): image not found

    Any idea how I could fix this? Thanks!

  2. Thanks for the guide. As a beginner of Docker, it’s really clear and helpful.

    The only problem I have is that I can only migrate inside the PHP container. If I want to run Symfony console commands in my local terminal, the only method I came up with is to change “mysql:3306” to “127.0.0.1:8002”, but I need to change it back to make my app work properly.

    I wonder if there’s way to run console commands in my local terminal without changing the DATABASE_URL.

    1. Thank you Yifei for your kind comments 🙂

      I see what you mean. Indeed, outside the docker php container, the host machine does not know what “mysql” container means, and so, it will not work – as you mention, you would have to change to the host and the port so that the host machine knows how to connect.

      Think of the host as a remote machine that tries to connect. It’s similar to connecting remotely from a MySQLWorkbench or Sequel Pro, you would also have to config the 8002 port and 127.0.0.1 host.

      Unfortunately, I believe that’s how Docker works and there’s no other way 🙂

  3. Hi,
    at last an clean article that let me understand how to do it, and it worked at first shot!!

    How can you manage the DB, put a phpMyAdmin or maybe manage to connect PhpStorm database panel directly ?

    1. Thank you for your kind comment laminr 🙂

      To connect to the ddbb remotely I tend to use MySQLWorkbench. I found out it works better than SequelPro for docker connections!

      So the connection configuration in MySQLWorkbench would be something like:

      Hostname: 127.0.0.1
      Port: 8002
      Username: root
      Password: dbrootpw

      The credentials for the root user are set up in the docker-compose.yml.

      I also try to use the same root password for all projects in development, so I don’t need to edit MySQLWorkbench’s connection or add a new one, just open and connect. After all, it’s a development environment 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *