Docker Community Forums

Share and learn in the Docker community.

Git & Does docker-compose.yml qualify as 'config'?

I have several git repos that are identical except for .config files and docker-compose.yaml files… How do you achieve having different docker-compose.yml and config files per environment without having multiple repos (per environment)?
Thanks.

I supposed it is possible to have more than one docker-compose file in the same repository under different names, but then you run the risk of running “sudo docker-compose up” without specifying the production server’s dockerfile… and then creating a bunch of staging config on production. Worst of this, in my config, would be generating wrong letsencrypt certificates for the domain - as is done by nginx-proxy docker project(s). Anyway, I guess I could make a wrapper around ‘docker-compose up’ and the like, but I was hoping for a more elegant solution :slight_smile:

You could leverage some sort of templating.

The simplest approach would be to replace every environment specific value with ${variablename} and use a bash script to either set those variables in the file or read them from a different file, then replace the variables on the fly and pass them over to docker-compose.

One of the biggest advantages is, that you can keep your compose.yml in sync for how many environments you want, without having to maintaing all of them seperatly…

example for mariadb

the template file docker-compose.template would look something like this:

version: '2.2'

services:

  ${MARIA_SERVICE_NAME}:
    image: mariadb:latest
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    restart: always
    ports:
      - ${MARIA_HOST_PORT}:3306
    volumes:
      - ${MARIA_VOLUME_HOST}:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${MARIA_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MARIA_DATABASE}
      - MYSQL_USER=${MARIA_USER}
      - MYSQL_PASSWORD=${MARIA_PASSWORD}

Execution could look like this:

#!/bin/bash -eu
MARIA_SERVICE_NAME=db
MARIA_ROOT_PASSWORD=nextcloud
MARIA_DATABASE=nextcloud
MARIA_USER=nextcloud
MARIA_PASSWORD=nextcloud
MARIA_VOLUME_HOST=/data/local/nextcloud/db

eval "echo \"$(<docker-compose.template)\"" | docker-compose -f - $@

You simply call the script and pass the docker-compose operation to it. The “-eu” flags in the first line are importent as they are resoponsible to abord the rendering, if a variable from the template file is unset.

Though, instead of defining the values in the bash script, you would externalize them, read the file in the bash script and use the eval line to render and start the stack.

eval could be replaced with envsubst(part of the gettext package), but it requires all variables to be exported into the shell prior execution.

This approach works for Docker Swarm as well :wink: If you require conditional rendering in your template, you might take a look at https://docs.gomplate.ca/.