Splitting application code and docker deployment files

deploymentdocker

I am beginning the process of moving my django stack to docker containers. Most examples I have seen put the Dockerfile and docker-compose.yml files in the same repository as the application source code.

I have been using ansible for deployment so far, it's served me well, and I intend to keep it while gradually packaging the various services into containers. All my ansible files are in their own git repository, separate from the app source code, so all my config is versioned. This has worked very well so far.

My question is about location of docker files. I have put them with the app code, but I now feel that this is forcing me to put deployment-related info in the app code, which I feel is wrong.

An example: I use Celery for various processes, which relies on rabbitmq for messaging. Each one lives in a container as seems to be recommended. I need to pass Celery the password for rabbitmq, which I'm passing as an environment variable in docker-compose.yml. So in short, my deployment password is in the app code. This is only one of several examples.

What is the best practice to split up app code VS deployment config and scripts in this context? Or more specifically, where should the docker files live?

Best Answer

It often makes sense to version docker-compose.yml files separately from your application, because they are specific to different deployments, and reference multiple docker images from several microservices, which are usually kept in their own individual repositories. Although you should look into solutions like the docker secret command for managing things like your rabbitmq password, rather than baking it into your app.

However, Dockerfiles are not about deployment. They are much more akin to a build script. If you keep your Dockerfiles with different deployment scripts, you run the risk of having different images in different environments. What you want is the same image in development, debug, testing, staging, and all the different customer configurations in production. You might customize it a little with environment variables, but keeping the image the same buys you a lot, and keeping the Dockerfile with the code is the easiest way to ensure that.

In summary, keep Dockerfiles with the code, but separate your yaml files if you have a lot of different deployment environments to keep track of.

Related Topic