Introducing Docker support
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.
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
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:
Docker Compose addition
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.
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.
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.
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
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:
PHP FPM (and CLI)
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
an OAuth/OpenID Connect module, an
HTTP cache module…)!
Getting Started with Symfony Docker is straightforward:
$ 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
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
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!
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à!
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: