Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46178

Versioning a docker composition

I usually use simple production images composition to manage my production deployments hence exclusively relying on docker-compose.

I'm not using Kubernetes or other tools since I want to keep it simple for my simple apps (I don't deploy on multiple hosts, manage load balancing or do CD/CI)

Here is how my production composition could look like:

version: '3'

services:
    php:
        image: ${CONTAINER_REGISTRY_BASE}/php:${VERSION}
        depends_on:
          - db
        env_file:
          - ./api.env

    api:
        image: ${CONTAINER_REGISTRY_BASE}/api:${VERSION}
        depends_on:
          - php
          - db

    db:
        image: mariadb:10.2

    client:
        image: ${CONTAINER_REGISTRY_BASE}/client-prod:${VERSION}
        env_file:
          - ./client.env

    admin:
        image: ${CONTAINER_REGISTRY_BASE}/admin-prod:${VERSION}
        env_file:
          - ./admin.env

Keeping one global version for the application stack in a .env file, when I update this version I simply have to do this:

docker-compose build
docker-compose push

And in the production server (after having updated the version)

docker-compose up -d

As you can imagine, the issue is that I'm shipping the whole stack even if there is a very small modification in one of the services.

I thought about having a different version for each service but it seems quite complicated to maintain as we can't really be sure what is the last version for each.

Am I seeing it wrong ? Shouldn't I use docker-compose in production ? In which case what should I use ?

Can someone suggest me a simple deployment way based on a docker registry ?

Upvotes: 0

Views: 85

Answers (1)

Dockstar
Dockstar

Reputation: 1028

Short Answer: You should actually have separate services for each, and I'd recommend moving away from just the normal Docker server for your production to Swarm.

Long Answer: If you move to Docker Swarm, you can use the same compose file with a few changes to make it into a stack file. What this does is creates a series of services, individually maintained by the Swarm.

During your build process, I would recommend assigning each new build a specific version number, and then tagging it specifically as latest or dev. Push the latest or dev version to the repository.

The reason for this is two fold:

  1. When you update your stack file, you'll want to specify a discrete version of the image to use. IE 1.2.3 or whatever your newest is for the service you had just changed. This is because if you try to use "latest" there's a good change the Swarm won't even try to pull the image because on deployment. I've always found it's better to avoid ambiguity in the production sense
    1. For developers, whenever they start working, or whenever they're doing work on their local environment, they can always target the dev or latest image via composer overrides (basically calling two compose files in sequence, the first having core definitions, the second having changes or additions etc)

Whenever you do a docker stack deploy, it's only going to look at differences in the services to make changes. I'd play around with it, but I think it would fit your work flow a lot better.

Side note: I've never really found a good use case for databases existing in Docker shy of (1) lack of resources or (2) integration testing.

Upvotes: 1

Related Questions