5.8 KiB
docker-compose template
Run it
Execute this template like so:
cookiecutter https://quico.space/Quico/py-cookiecutter-templates.git --directory 'docker-compose'
Cookiecutter interactively prompts you for the following info, here with example answers:
project_slug [dir-name]: grafana
service [grafana]:
component_list [grafana]: grafana,nginx
context [ctx]: cncf
Done, directory structure and files for your next docker-compose
project are ready for you to hit the ground running.
Explanation and terminology
Your four answers translate as follows into rendered files.
-
The
project_slug
is used only as directory name. A container namedvault
may be fine but the project directory namehashicorpvault
might be more descriptive.. └── hashicorpvault <--- Here ├── build-context │ ├── docker-data │ │ └── .gitkeep │ ├── Dockerfile ...
-
The
service
variable by default copies yourproject_slug
answer. It's a style decision whether you leave it at that and just hitEnter
. The service name will come up in rendereddocker-compose.yml
at purely cosmetic locations such as thenetworks:
key,container_name:
and/opt/docker-data
volume mount presets, here withftp
as the service name:services: mysql: image: "mysql:${MYSQL_VERSION}" container_name: "ftp-mysql-${CONTEXT}" <--- networks: ftp-default: <--- ... volumes: # - /opt/docker-data/ftp-mysql-${CONTEXT}/... <--- # - /opt/docker-data/ftp-mysql-${CONTEXT}/... <--- # - /opt/docker-data/ftp-mysql-${CONTEXT}/... <--- ...
-
Treat
component_list
as the list of Docker images that make up your service. Eachdocker-compose
project forms a service - see above - that consists of either a single or multiple components. They're yourservices:
, your container, volume, variable names etc.:services: grafana: <--- image: "grafana:${GRAFANA_VERSION}" <--- container_name: "grafana-grafana-${CONTEXT}" <--- ... environment: # GRAFANA_USER: ${GRAFANA_USER} <--- # GRAFANA_PASSWORD: ${GRAFANA_PASSWORD} <--- ...
-
The last prompt for a
context
is a generic string to help you distinguish deployments. It can be whatever you want such as for example a team name, herecncf
which shows up as a preset in an example env file. It defaults toctx
just so it can't be empty.. └── grafana ... └── env └── fully.qualified.domain.name.example <---
Which then looks like:
CONTEXT=cncf ...
Also check out the Caveats section at the end to learn what this template does not do well.
Result
Multi-component service
Above example of a multi-component (two in this case) grafana
service will give you this directory structure:
.
└── grafana
├── build-context
│ ├── grafana
│ │ ├── docker-data
│ │ │ └── .gitkeep
│ │ ├── Dockerfile
│ │ └── extras
│ │ └── .gitkeep
│ └── nginx
│ ├── docker-data
│ │ └── .gitkeep
│ ├── Dockerfile
│ └── extras
│ └── .gitkeep
├── common-settings.yml
├── docker-compose.override.yml
├── docker-compose.yml
└── env
└── fully.qualified.domain.name.example
Check out file contents over in the examples/grafana subdir.
Single-component service
With an alternative single-component hashicorpvault
service the result may look like this:
.
└── hashicorpvault
├── build-context
│ ├── docker-data
│ │ └── .gitkeep
│ ├── Dockerfile
│ └── extras
│ └── .gitkeep
├── common-settings.yml
├── docker-compose.override.yml
├── docker-compose.yml
└── env
└── fully.qualified.domain.name.example
Check out file contents over in the examples/hashicorpvault subdir.
Caveats
Consider Cookiecutter's project directory and rendered files a starting point. It won't do everything perfectly.
Imagine if you will a service that consists of Infinispan among other things. In Docker Hub's content-addressable image store Infinispan's location is at infinispan/server
so you obviously want that exact string with a forward slash to show up in your docker-compose.yml
as the image:
key's value, same with your Dockerfile
. The image:
key's value comes from what you enter in Cookiecutter's component_list
prompt. Component strings are then used to also pre-fill the volumes:
key.
This will cause obvious issues (but the image:
key is kinda correct):
services:
infinispan/server:
image: "infinispan/server:${INFINISPAN/SERVER_VERSION}"
container_name: "cacheman-infinispan/server-${CONTEXT}"
This won't cause issues (but you'll have to then go in and manually change the image:
key to use infinispan/server
):
services:
infinispan:
image: "infinispan:${INFINISPAN_VERSION}"
container_name: "cacheman-infinispan-${CONTEXT}"
You're going to want to keep it simple and go with option 2.