148 lines
6.0 KiB
Markdown
148 lines
6.0 KiB
Markdown
# 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
|
|
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.
|
|
```
|
|
.
|
|
└── 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:
|
|
grafana: <---
|
|
image: "grafana:${GRAFANA_VERSION}" <---
|
|
container_name: "grafana-grafana-${CONTEXT}" <---
|
|
...
|
|
environment:
|
|
# GRAFANA_USER: ${GRAFANA_USER} <---
|
|
# GRAFANA_PASSWORD: ${GRAFANA_PASSWORD} <---
|
|
...
|
|
```
|
|
|
|
4. 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
|
|
```
|
|
Check out file contents over in the [examples/grafana](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
|
|
│ └── fqdn_context.env.example
|
|
└── README.md
|
|
```
|
|
Check out file contents over in the [examples/hashicorpvault](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](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}"
|
|
```
|
|
|
|
You're going to want to keep it simple and go with option 2.
|