feat(docker-compose): Allow directory name different from service or component names
This commit is contained in:
		| @@ -28,9 +28,10 @@ Cookiecutter prompts you for whatever info the template needs then generates fil | ||||
|  | ||||
| This is Cookiecutter prompting for info: | ||||
| ``` | ||||
| service []: grafana | ||||
| project_slug [dir-name]: grafana | ||||
| service [grafana]: | ||||
| component_list [grafana]: grafana,nginx | ||||
| context []: cncf | ||||
| context [ctx]: cncf | ||||
| ``` | ||||
|  | ||||
| The end result is a directory structure that has everything you need to hit the ground running. | ||||
|   | ||||
| @@ -9,20 +9,73 @@ cookiecutter https://quico.space/Quico/py-cookiecutter-templates.git --directory | ||||
|  | ||||
| Cookiecutter interactively prompts you for the following info, here with example answers: | ||||
| ``` | ||||
| service []: grafana | ||||
| project_slug [dir-name]: grafana | ||||
| service [grafana]: | ||||
| component_list [grafana]: grafana,nginx | ||||
| context []: cncf | ||||
| 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 | ||||
|  | ||||
| Each `docker-compose` project forms a *__service__* that may consist of either a single or multiple *__components__*. | ||||
| Your four answers translate as follows into rendered files. | ||||
|  | ||||
| The `service` variable by default is empty. In this example we've chosen to name the service `grafana`. We want `grafana` to consist of two components, namely Grafana itself and Nginx. Syntax for a multi-component `component_list` is a comma-separated list without spaces. The string `grafana,nginx` will be treated as a list of two components. Capitalization doesn't matter, we're lowercasing all strings automatically. The template prefills `component_list` with whatever you previously entered as the `service` name. To create directory structure for a _single-component service_ confirm the default. If `component_list` and `service` are identical directory structure will be that for a _single-component service_. | ||||
| 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}/... <--- | ||||
|         ... | ||||
|     ``` | ||||
|  | ||||
| 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, here `cncf`. | ||||
| 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. 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, here `cncf` which shows up as a preset in an example env file. It defaults to `ctx` just it can't be empty. | ||||
|     ``` | ||||
|     . | ||||
|     └── grafana | ||||
|         ... | ||||
|         └── env | ||||
|             └── fully.qualified.domain.name.example <--- | ||||
|     ``` | ||||
|  | ||||
|     Which then looks like: | ||||
|     ``` | ||||
|     CONTEXT=cncf | ||||
|     ... | ||||
|     ``` | ||||
|  | ||||
| Also check out [the Caveats section](#caveats) at the end to learn what this template does not do well. | ||||
|  | ||||
| ## Result | ||||
|  | ||||
| @@ -72,3 +125,27 @@ With an alternative single-component `hashicorpvault` service the result may loo | ||||
|         └── fully.qualified.domain.name.example | ||||
| ``` | ||||
| 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 perfect. | ||||
|  | ||||
| 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 simply and go with option 2. | ||||
|   | ||||
| @@ -5,6 +5,6 @@ | ||||
|     "__service_slug": "{{ cookiecutter.service.lower().replace(' ', '_').replace('-', '_') }}", | ||||
|     "component_list": "{{ cookiecutter.__service_slug }}", | ||||
|     "__component_list_slug": "{{ cookiecutter.component_list.lower().replace(' ', '_').replace('-', '_') }}", | ||||
|     "context": "", | ||||
|     "context": "ctx", | ||||
|     "__context_slug": "{{ cookiecutter.context.lower().replace(' ', '_').replace('-', '_') }}" | ||||
| } | ||||
|   | ||||
| @@ -4,10 +4,10 @@ | ||||
| # ARG EXAMPLE_ARG_FOR_DOCKERFILE | ||||
|  | ||||
| # Another env var, this one's needed in the example build step below: | ||||
| # ARG HASHICORPVAULT_VERSION | ||||
| # ARG VAULT_VERSION | ||||
|  | ||||
| # Example | ||||
| # FROM "hashicorpvault:${HASHICORPVAULT_VERSION}" | ||||
| # FROM "vault:${VAULT_VERSION}" | ||||
| # RUN apt-get update && \ | ||||
| #     apt-get -y install \ | ||||
| #     somepackage-6.q16-6-extra && \ | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| services: | ||||
|     hashicorpvault-build: | ||||
|         image: "hashicorpvault:${HASHICORPVAULT_VERSION}" | ||||
|     vault-build: | ||||
|         image: "vault:${VAULT_VERSION}" | ||||
|         profiles: ["build"] | ||||
|         build: | ||||
|             context: "build-context/hashicorpvault" | ||||
|             context: "build-context/vault" | ||||
|             dockerfile: Dockerfile | ||||
|             args: | ||||
|                 EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}" | ||||
|                 HASHICORPVAULT_VERSION: "${HASHICORPVAULT_VERSION}" | ||||
|                 VAULT_VERSION: "${VAULT_VERSION}" | ||||
|   | ||||
| @@ -1,24 +1,24 @@ | ||||
| services: | ||||
|     hashicorpvault: | ||||
|         image: "hashicorpvault:${HASHICORPVAULT_VERSION}" | ||||
|         container_name: "hashicorpvault-${CONTEXT}" | ||||
|     vault: | ||||
|         image: "vault:${VAULT_VERSION}" | ||||
|         container_name: "vault-${CONTEXT}" | ||||
|         networks: | ||||
|             hashicorpvault-default: | ||||
|             vault-default: | ||||
|         extends: | ||||
|             file: common-settings.yml | ||||
|             service: common-settings | ||||
|         ports: | ||||
|             # - "8080:80" | ||||
|         volumes: | ||||
|             # - /opt/docker-data/hashicorpvault-${CONTEXT}/data/db:/usr/lib/hashicorpvault | ||||
|             # - /opt/docker-data/hashicorpvault-${CONTEXT}/data/logs:/var/log/hashicorpvault | ||||
|             # - /opt/docker-data/hashicorpvault-${CONTEXT}/config:/etc/hashicorpvault | ||||
|             # - /opt/docker-data/vault-${CONTEXT}/data/db:/usr/lib/vault | ||||
|             # - /opt/docker-data/vault-${CONTEXT}/data/logs:/var/log/vault | ||||
|             # - /opt/docker-data/vault-${CONTEXT}/config:/etc/vault | ||||
|         environment: | ||||
|             # HASHICORPVAULT_USER: ${HASHICORPVAULT_USER} | ||||
|             # HASHICORPVAULT_PASSWORD: ${HASHICORPVAULT_PASSWORD} | ||||
|             # VAULT_USER: ${VAULT_USER} | ||||
|             # VAULT_PASSWORD: ${VAULT_PASSWORD} | ||||
| networks: | ||||
|     hashicorpvault-default: | ||||
|         name: hashicorpvault-${CONTEXT} | ||||
|     vault-default: | ||||
|         name: vault-${CONTEXT} | ||||
|         driver: bridge | ||||
|         driver_opts: | ||||
|             com.docker.network.enable_ipv6: "false" | ||||
|   | ||||
| @@ -4,7 +4,7 @@ CONTEXT=fsf | ||||
|  | ||||
| # Set something sensible here and uncomment | ||||
| # --- | ||||
| # HASHICORPVAULT_VERSION=x.y.z | ||||
| # VAULT_VERSION=x.y.z | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user