Introducing our Docker Starter-Kit

(Lire l’article en français)

At JoliCode, most of our projects (internal or for our clients) use Docker in order to simplify the Developer Experience (DX) locally. Some projects have specific/complex architecture that require another workflow (with the Symfony binary for example). But for all others, the infrastructure is often similar: NGINX, PHP-FPM, a Database (PostgreSQL or MariaDB) and some additional services (RabbitMQ, Redis, Elasticsearch, redirection.io, …).

For a while, we copy/paste from project to project a Docker infrastructure managed with Fabric on top of Docker Compose. This architecture has diverged over the different projects, until we got some motivation to factor everything in a private repository. And after few successful projects, we decided to open-source it. Please welcome our Docker Starter-Kit:

https://github.com/jolicode/docker-starter

Under the hood

This project is available as a template repository on GitHub. It gives us an architecture that fulfill our requirements for most common project. It’s configured with Docker Composer and use lightweight images to get project quickly installed and fast to work with.

Out of the box, it comes with:

  • A NGINX server with PHP-FPM;
  • A PostgreSQL server;
  • A “builder” container for all common tasks and with the required tooling like Composer, Yarn, etc;
  • Traefik to manage the routing to containers, and to get HTTPS by default.

Fabric to the rescue

This project provides a few Fabric tasks in order to simplify the interaction with containers.

Install / Start the project:

fab start

Start a container and enter it to use Composer / Yarn / Webpack / whatever:

fab builder

Remove everything (useful after testing a project):

fab down

Some tasks were needed on all our projects, so we added them is this starter-kit. Don’t hesitate to adapt them for your project. For example, we have migrate in order to… migrate your database. Or cache_clear in order to… clear your application cache.

Run fab -l or open the fabfile.py file to get the full list.

Minimal Configuration = Simplified DX

After having factored all our knowledge and requirements in an external repository, we spent some time to simplify everything. We are using it as-it in our projects for months.

Thanks to the python overlay (with Fabric), only 3 variables could/should be configured for each project:

  • env.project_name: This will be used to prefix all docker objects (network, images, containers);
  • env.project_directory: This is the host directory containing your PHP application. Usually, we keep the default value (app);
  • env.project_hostnames : This will be all your domain names, separated with commas.

HTTPS by default

The stack is accessible over HTTPS by default thanks to an auto-signed certificate. If you project need a valid certificate (some tools refuse invalid certificate), we highly recommend you to use mkcert. By the way, the certificate in this starter-kit has been generated thanks to this awesome tools!

Oh, and Traefik is configured to redirect all traffic from HTTP to HTTPS. Safety First.

Frequently Asked Questions

FAQ is a good way to save some words, explain our choices, and answer all questions, even the one you did not asked yet.

  • Is this compatible with Symfony / Laravel / …

Yes! And if your application has a public directory that should be exposed by the Web Server (document root), it will work out of the box. It’s already the case for Symfony and Laravel. If it’s not the case, you will have to tweak the NGINX configuration.

  • It this tested?

Yes 😎. CircleCI is enabled and configured to ensure we don’t break anything. Moreover, this starter-kit shows how to use docker_layer_caching with circle and how to configure workflow. Finally, we get a nice configuration for our project.

  • What is this python overlay?!?!

Docker Compose is a useful tool to manage an application with many containers. But when you have to launch a command manually, it’s getting boring. Between the docker configuration, the environment variables to set, the project name, etc. the command line could be really hard to type and remember:

docker-compose -p offithings -f /home/loick/Work/my_project/infrastructure/orchestration/base.yml -f /home/loick/Work/my_project/infrastructure/orchestration/local.yml -f /home/loick/Work/my_project/infrastructure/orchestration/builder.yml build --build-arg PROJECT_NAME=my_project --build-arg USER_ID=1000

As developers, we are lazy and we like to automate everything and simplify things:

fab start
  • Why another Docker skeleton ?

Because we are using Docker for years, and we wanted to gather all our knowledge in one central piece instead of copying / pasting piece of configuration. This simplify a lot the starting of new projects and this adds consistency. Moreover, not everyone is comfortable with Docker, so it saves us time when a new project comes in. And since we have something that works well for us, why not open-sourcing it and let the community profit of our work? No-one is forced to use it and we don’t pretend to have the best solution that works every time. It answers our own needs.

  • I have already some idea to enhance it, would you accept Pull Request ?

As we said, it suits our needs and it could not satisfy everyone. But we are open to dialog and we accept all goods ideas and suggestion. If it meets our workflow, we will be very happy to merge your PR. Don’t hesitate to open an issue to discuss.

blog comments powered by Disqus