164 lines
6.5 KiB
Markdown
Raw Normal View History

# 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
Select build:
1 - no
2 - yes
Choose from 1, 2 [1]:
```
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.
1. The `project_slug` is used only as directory name. A container named `vault` may be fine but the project directory name `hashicorpvault` might be more descriptive.
```
.
2022-06-06 04:42:40 +02:00
└── hashicorpvault <--- Here
├── build-context
│   ├── docker-data
│   │   └── .gitkeep
│   ├── Dockerfile
...
```
2. The `service` variable by default copies your `project_slug` answer. It's a style decision whether you leave it at that and just hit `Enter`. The service name will come up in rendered `docker-compose.yml` at purely cosmetic locations such as the `networks:` key, `container_name:` and `/opt/docker-data` volume mount presets, here with `ftp` 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}/... <---
...
```
3. Treat `component_list` as the list of Docker images that make up your service. Each `docker-compose` project forms a *__service__* - see above - that consists of either a single or multiple *__components__*. They're your `services:`, your container, volume, variable names etc.:
```
services:
2022-06-06 04:42:40 +02:00
grafana: <---
image: "grafana:${GRAFANA_VERSION}" <---
container_name: "grafana-grafana-${CONTEXT}" <---
...
environment:
2022-06-06 04:42:40 +02:00
# GRAFANA_USER: ${GRAFANA_USER} <---
# GRAFANA_PASSWORD: ${GRAFANA_PASSWORD} <---
...
```
4. The `context` prompt is a generic string to help you distinguish deployments. It can be whatever you want such as for example a team name, here `cncf` which shows up as a preset in an example env file. It defaults to `ctx` just so it can't be empty.
```
.
└── grafana
...
└── env
└── fqdn_context.env.example <---
```
Which then looks like:
```
CONTEXT=cncf
...
```
5. Prompt `build` is a yes-no question. Cookiecutter will create a `README.md` file with copy-pastable Docker Compose commands pre-filled. If you answer `yes` to this prompt `README.md` will contain an example paragraph that explains the build process along the lines of:
```
docker compose ... --profile 'build' build
```
Whereas by answering `no` (or just hitting `<Enter>` to accept the default of `no`) no such paragraph will be added to the example Markdown file. Build instructions are only really needed if you need to locally build a derivative image.
Also check out [the Caveats section](#caveats) 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
│   └── fqdn_context.env.example
└── README.md
```
2022-06-05 00:29:10 +02:00
Check out file contents over in the [examples/grafana](examples/grafana) subdir.
2022-06-05 00:34:49 +02:00
### 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
│   └── fqdn_context.env.example
└── README.md
```
Check out file contents over in the [examples/hashicorpvault](examples/hashicorpvault) subdir.
## Caveats
2022-06-06 04:43:49 +02:00
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](https://infinispan.org/) 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}"
```
2022-06-06 04:45:05 +02:00
You're going to want to keep it simple and go with option 2.