Over the years, Docker has become the de facto standard for building, shipping and running server applications. Docker allows you to store all the instructions needed to build the environment that will host your software next to the code, in the repository of the project.

I'm very excited to announce that after 6 years of teamwork, Symfony and API Platform now include an industry-first set of tools designed to automatically create, manage and run the Docker containers needed for your applications.

Docker Compose and Dockerfile Flex Configurators

As you probably know, Symfony comes with a handy tool called Flex. Flex is a Composer plugin that makes it easy to add new features to your projects. When you install a new PHP library, Flex automatically generates the code and configuration necessary to get that library set up.

And Flex has new superpowers! It is now able to generate and update a docker-compose.yml file to add the services needed by the packages you just installed!

For instance, to use the Doctrine ORM, you need a DBMS. Well, guess what? When installing Doctrine (e.g. composer require orm), Flex will now ask if you want it to update your docker-compose.yml file. If you answer "yes", it automatically adds a Postgres server that's ready to be used!

Another example: let's say you are using Symfony UX Turbo and you want to take advantage of its great real-time capabilities. Then, you need a Mercure.rocks hub. Symfony Flex has you covered: it can automatically add one to your docker-compose.yml file!

Run docker-compose up and everything is ready!

In addition to the Docker Compose configurator, a Dockerfile configurator has also been added. It's able to add the PHP extensions required by the PHP packages you install (e.g. pdo_pgsql) to a compatible Dockerfile. More on that later!

Currently, the following Flex recipes leverage these new configurators:

PHP package Docker Compose addition Dockerfile addition
symfony/orm-pack postgres pdo_pgsql
symfony/mercure-bundle dunglas/mercure  
symfony/panther   chromedriver geckodriver
symfony/mailer schickling/mailcatcher  
blackfireio/blackfire-symfony-meta blackfire/blackfire  

The Docker Compose configurator also generates two override files: docker-compose.override.yml contains the specific configuration needed in development, and docker-compose.prod.yml the configuration needed in production. We'll come back to this.

Symfony CLI and Docker Compose

The Symfony CLI, which Fabien open-sourced during the opening keynote of the SymfonyWorld conference, is able to automatically detect Docker Compose services and to automatically configure your apps to use them.

To do so, Symfony CLI queries the Docker Engine API to find the ports used by the Docker containers and populates the environment variables used by the app to connect to them. Thanks to the generated docker-compose.override.yml, the services added by Symfony Flex are compatible with this feature.

Symfony CLI Docker information in the Symfony Toolbar

And that's not all: you can start several projects at the same time without any conflict (with, for example, a different Postgres server per project). To achieve this, the Docker Compose services in docker-compose.override.yml are mapped to random ports on the host! Run docker-compose ps in your project directory to see the assigned ports.

Docker Skeleton and Installer

The Symfony CLI is the easiest way to get started with Symfony. But it needs a local PHP installation, a local Composer installation, and is designed to be used only in development.

What if you want to be sure that all the developers in your team use the exact same PHP version? What if you want to facilitate the onboarding and don't want your devs to install PHP or Composer locally? What if you want to want to use the same configuration also in your continuous integration system or even in production?

Here comes Symfony Docker!

Symfony Docker is a skeleton containing everything needed to install and run a Symfony project. With Symfony Docker, as long as you have a working installation of Docker Compose, you can create new Symfony projects without having to install anything locally.

Symfony Docker comes with two simple images:

  1. PHP FPM (and CLI)
  2. the Caddy webserver

It contains a Dockerfile and docker-compose.yml files compatible with the Symfony Flex configurators. It is designed to be simple, readable and non-bloated, but still allows running your project locally, in your CI, and in production!

Like Symfony CLI, Symfony Docker also sets the environment variables used by your project to ensure that it connects to the Docker Compose services installed by the Flex configurator.

Because Symfony Docker uses the shiny Caddy web server, TLS certificates are generated and renewed automatically (both for localhost and for your real domain names in prod), HTTP/2 and HTTP/3 are natively supported, and you can install all the Caddy modules that you want (my own Mercure and Vulcain modules, an OAuth/OpenID Connect module, an HTTP cache module...)!

Getting Started with Symfony Docker is straightforward:

1
2
3
$ git clone https://github.com/dunglas/symfony-docker
$ docker-compose build --pull --no-cache
$ docker-compose up

That's all, Symfony has been installed and your project is up and running. Install Doctrine, or Blackfire, or any other package supported by the Docker configurators and the required services and PHP extensions will be installed automatically!

Symfony Docker contains more goodies such as the ability to select the version of Symfony to install. It can also be added to existing projects. Read its documentation to learn more about that.

Symfony Docker is also a GitHub template that you can use to bootstrap your project. It contains a GitHub Actions workflow that automatically runs your tests using the provided Docker containers!

Symfony Docker isn't the only skeleton compatible with the new Flex configurators! The API Platform distribution (from which Symfony Docker has been extracted) also supports them!

Kubernetes

While Symfony Docker (and the API Platform distribution) can be used in production using Docker Compose, only single-host deployments are supported.

This may be sufficient for small to medium-sized projects, but when things get serious, you'll probably want to use the king of container orchestrators: Kubernetes.

The Docker images provided by Symfony Docker have been designed to be compatible with Kubernetes. But there is more! The API Platform project provides a Helm chart (the package manager of Kubernetes) to deploy your project on any Kubernetes cluster in a single command!

This chart is entirely compatible with Symfony Docker (and you don't need to use API Platform). Copy and paste the chart in your project, and voilà!

Learn how to deploy your apps in Kubernetes

For more details about this brand new Docker integration, visit the SymfonyWorld Online 2021 Winter Edition replay and watch the talk I gave about this. You can also check below the slides of my talk:

If you like these new features, and if you want new ones like this, sponsor me and sponsor the Symfony project!

Published in #Symfony