← Back to articles

Hybrid dev environment

In my software engineering team, we had three schools for the way to run our development stack.

Those who preferred to leverage our Docker Compose setup to run everything in docker images, including our own software. They mounted the code base in the docker image, they exposed the local port on their host, they used docker compose exec to run the application CLI. They stayed close to what we run in production (Docker images).

Then those who preferred to run everything locally (old school style). They installed PostgreSQL, RabbitMQ, and other services on their host (generally using the great packaging system of Debian and Debian-derived distributions), and of course they were running the app directly on their Linux host.

Finally, some preferred a hybrid setup: Docker Compose for external services, with the application running on their host.

Today, with the advent of uv, nvm, it’s way easier to run our own app on the host and avoid the overhead and relative complexity of Docker. These tools provide the same runtime consistency as Docker images.

That said, it’s also very convenient to leverage Docker images to start the myriad of services a modern app needs to use : postgresql, redis, kafka, rabbitmq, and so on.

As a result, this is the solution we currently enforce. Our app default settings for development target the local ports exposed by the external services declared in our docker-compose.services.yml file. We are in the process of decommissioning the Docker Compose definition of our own apps (of course we keep the Dockerfile files used for building our CI, QA, and production images).

There is less flexibility for a newcomer, but then all the software team is aligned on one way to set things up.