diff --git a/.gitignore b/.gitignore index ed24fba..4c36e3a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# pyenv +.python-version + # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml @@ -206,6 +209,8 @@ venv/ ENV/ env.bak/ venv.bak/ +!docker-compose/examples/*/env +!docker-compose/{{ cookiecutter.__project_slug }}/env # Spyder project settings .spyderproject diff --git a/README.md b/README.md index 137fa40..6a60b02 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,17 @@ Project directory structure templates for the Python Cookiecutter package. -## What's Cookiecutter? +# What's Cookiecutter? The Python package [Cookiecutter](https://github.com/cookiecutter/cookiecutter) assists in creating directory structure for whatever purpose you need such as for example a new Python project, an Ansible role or a `docker-compose` project - anything really that benefits from a unifirm reproducible directory structure. If you've ever wanted to put project structure best practices into version control then Cookiecutter's here to help. Cookiecutter is governed by so-called Cookiecutter templates, most of its magic inside Cookiecutter templates happens via the [Jinja2 template engine](https://palletsprojects.com/p/jinja/). You'll feel right at home if you're familiar with Ansible. -## Repo layout +# Repo layout Each subdirectory in this repo is a Cookiecutter template, you'll recognize them from their telltale `cookiecutter.json` files. Directories usually also have a readme file explaining more about each individual template. -## Get started +# Get started Get Cookiecutter like so: ``` @@ -57,3 +57,176 @@ The end result is a directory structure that has everything you need to hit the └── env └── fully.qualified.domain.name.example ``` + +# Developing + +To change Cookiecutter templates get yourself an environment then make, test and commit your changes. First things first, the environment. + +## Environment + +Get yourself a Python virtual environment. In this example we're assuming you're running a Linux operating system and you'll be using [pyenv](https://github.com/pyenv/pyenv) to manage virtual environments. + +### pyenv + +- Install pyenv with what they are calling their automatic installer. Feel free to also read up on pyenv on their [GitHub project page](https://github.com/pyenv/pyenv). + ``` + curl https://pyenv.run | bash + ``` + +- Following the installer's instruction add at least the following commands to your `~/.bashrc` file + ``` + export PYENV_ROOT="$HOME/.pyenv" + command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + ``` + +- You will also likely want to add this line which will make sure pyenv auto-activates venvs when you navigate into certain directories. More on that down at [venv](#venv). + ``` + eval "$(pyenv virtualenv-init -)" + ``` + +- Also make sure `~/.bashrc` gets loaded for example by including this in a `~/.bash_profile` file + ``` + [[ -f ~/.bashrc ]] && . ~/.bashrc + ``` + +- Reload `~/.bashrc` + ``` + source ~/.bashrc + ``` + +### Python + +- Update pyenv's package list + ``` + pyenv update + ``` +- Pick a Python version you like, for example copy-paste `3.11.4`: + ``` + pyenv install --list | less + + ... + 3.10.12 + 3.11.0 + 3.11-dev + 3.11.1 + 3.11.2 + 3.11.3 + 3.11.4 + 3.12.0b2 + 3.12-dev + 3.13-dev + ... + ``` +- Install Python, wait for compilation to finish on your machine + ``` + pyenv install 3.11.4 + ``` + +### Repo + +- Clone this repo + ``` + git clone https://quico.space/Quico/py-cookiecutter-templates.git ~/py-cookiecutter-templates + ``` + +### venv + +- Create a virtual environment where `3.11.4` is the Python version you want to use in this venv and `cookiecutter-3.11.4` is the name of your venv. Adding or dropping the Python version from your venv name comes down to personal preference. + ``` + pyenv virtualenv 3.11.4 cookiecutter-3.11.4 + ``` + +- In your repo path `~/py-cookiecutter-templates` create a `.python-version` file to tell pyenv to always activate your desired venv when inside this dir. + ``` + cd ~/py-cookiecutter-templates + pyenv local cookiecutter-3.11.4 + ``` + pyenv will immediately prefix your shell's `${PS1}` prompt with the venv name. + ``` + (cookiecutter-3.11.4) [✔ 23:19 user@machine py-cookiecutter-templates]$ + ``` + It will deactivate the venv and drop its prefix as soon as you navigate out of this dir. + ``` + (cookiecutter-3.11.4) [✔ 23:19 user@machine py-cookiecutter-templates]$ cd + [✔ 23:19 user@machine ~]$ + ``` + For now though stay in `~/py-cookiecutter-templates`, you're going to want to pip-install [cookiecutter](https://pypi.org/project/cookiecutter). + +- Upgrade `pip` + ``` + pip install --upgrade pip + ``` + +- Install [cookiecutter](https://pypi.org/project/cookiecutter) + ``` + pip install cookiecutter + ``` + +All done, your environment is set up. + +## Change + +Make some code changes, for example to the Docker Compose Cookiecutter template. When you're happy run your local Cookiecutter template to see how your changes are rendering. + +- Create `/tmp/cookiecutter-docker-compose` + ``` + mkdir '/tmp/cookiecutter-docker-compose' + ``` + +- Render a Docker Compose directory into your output directory, answer Cookiecutter's prompts: + ``` + # cookiecutter ~/py-cookiecutter-templates \ + --directory docker-compose \ + --output-dir /tmp/cookiecutter-docker-compose + + project_slug [dir-name]: mydir + service [mydir]: myservice + component_list [myservice]: mycomponent_one,mycomponent_two + context [ctx]: ux_novosibirsk + ``` + +- Observe that in `/tmp/cookiecutter-docker-compose` you now have your rendered Docker Compose dir: + ``` + # tree /tmp/cookiecutter-docker-compose + + /tmp/cookiecutter-docker-compose + └── mydir + ├── build-context + │   ├── mycomponent_one + │   │   ├── docker-data + │   │   ├── Dockerfile + │   │   └── extras + │   └── mycomponent_two + │   ├── docker-data + │   ├── Dockerfile + │   └── extras + ├── common-settings.yml + ├── docker-compose.override.yml + ├── docker-compose.yml + └── env + └── fqdn_context.env.example + ``` + +- For rapid testing you will most likely want to not type prompt answers repeatedly. Give them as command line arguments instead, also specify `--no-input` to suppress prompts: + ``` + cookiecutter ~/py-cookiecutter-templates \ + --no-input \ + --directory docker-compose \ + --output-dir /tmp/cookiecutter-docker-compose \ + project_slug=mydir \ + service=myservice \ + component_list=mycomponent_one,mycomponent_two \ + context=ux_novosibirsk + ``` + +## Commit prep + +When you're about ready to commit changes into this repo check the following bullet points. + +- Did you update the [Cookiecutter template README.md file](docker-compose/README.md), here for example for Docker Compose? + - Change in behavior? + - An updated example directory layout? + - Updated example file content? +- Did you commit a new completely rendered example directory structure into [docker-compose/examples](docker-compose/examples) dir? +- Did you change something that affects existing example directories? If so rerender them. diff --git a/docker-compose/README.md b/docker-compose/README.md index 2869ead..18d5675 100644 --- a/docker-compose/README.md +++ b/docker-compose/README.md @@ -13,6 +13,10 @@ 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. @@ -60,13 +64,13 @@ Your four answers translate as follows into rendered files. ... ``` -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 so it can't be empty. +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 - └── fully.qualified.domain.name.example <--- + └── fqdn_context.env.example <--- ``` Which then looks like: @@ -75,6 +79,12 @@ Your four answers translate as follows into rendered files. ... ``` +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 `` 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 @@ -132,7 +142,7 @@ Consider Cookiecutter's project directory and rendered files a starting point. I 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): +_**This**_ will cause obvious issues (but the `image:` key is kinda correct): ``` services: infinispan/server: @@ -140,7 +150,7 @@ services: 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`): +_**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: diff --git a/docker-compose/cookiecutter.json b/docker-compose/cookiecutter.json index 07bc351..d4f1e8c 100644 --- a/docker-compose/cookiecutter.json +++ b/docker-compose/cookiecutter.json @@ -6,5 +6,6 @@ "component_list": "{{ cookiecutter.__service_slug }}", "__component_list_slug": "{{ cookiecutter.component_list.lower().replace(' ', '_').replace('-', '_') }}", "context": "ctx", - "__context_slug": "{{ cookiecutter.context.lower().replace(' ', '_').replace('-', '_') }}" + "__context_slug": "{{ cookiecutter.context.lower().replace(' ', '_').replace('-', '_') }}", + "build": ["no", "yes"] } diff --git a/docker-compose/examples/grafana/docker-compose.yml b/docker-compose/examples/grafana/docker-compose.yml index 8be8499..73bfe39 100644 --- a/docker-compose/examples/grafana/docker-compose.yml +++ b/docker-compose/examples/grafana/docker-compose.yml @@ -5,15 +5,18 @@ services: networks: grafana-default: profiles: ["full", "grafana"] + depends_on: + nginx: + condition: service_healthy extends: file: common-settings.yml service: common-settings ports: # - "8080:80" volumes: - # - /opt/docker-data/grafana-grafana-${CONTEXT}/grafana/data/db:/usr/lib/grafana - # - /opt/docker-data/grafana-grafana-${CONTEXT}/grafana/data/logs:/var/log/grafana - # - /opt/docker-data/grafana-grafana-${CONTEXT}/grafana/config:/etc/grafana + # - /opt/docker-data/grafana-${CONTEXT}/grafana/data/db:/usr/lib/grafana + # - /opt/docker-data/grafana-${CONTEXT}/grafana/data/logs:/var/log/grafana + # - /opt/docker-data/grafana-${CONTEXT}/grafana/config:/etc/grafana environment: # GRAFANA_USER: ${GRAFANA_USER} # GRAFANA_PASSWORD: ${GRAFANA_PASSWORD} @@ -23,15 +26,21 @@ services: networks: grafana-default: profiles: ["full", "nginx"] + healthcheck: + test: ["CMD", "fping", "--count=1", "${GRAFANA_VIP}", "--period=500", "--quiet"] + interval: 3s + timeout: 1s + retries: 60 + start_period: 2s extends: file: common-settings.yml service: common-settings ports: # - "8080:80" volumes: - # - /opt/docker-data/grafana-nginx-${CONTEXT}/nginx/data/db:/usr/lib/nginx - # - /opt/docker-data/grafana-nginx-${CONTEXT}/nginx/data/logs:/var/log/nginx - # - /opt/docker-data/grafana-nginx-${CONTEXT}/nginx/config:/etc/nginx + # - /opt/docker-data/grafana-${CONTEXT}/nginx/data/db:/usr/lib/nginx + # - /opt/docker-data/grafana-${CONTEXT}/nginx/data/logs:/var/log/nginx + # - /opt/docker-data/grafana-${CONTEXT}/nginx/config:/etc/nginx environment: # NGINX_USER: ${NGINX_USER} # NGINX_PASSWORD: ${NGINX_PASSWORD} @@ -44,4 +53,4 @@ networks: ipam: driver: default config: - # - subnet: 172.21.184.0/24 + - subnet: ${SUBNET} diff --git a/docker-compose/examples/grafana/env/fully.qualified.domain.name.example b/docker-compose/examples/grafana/env/fqdn_context.env.example similarity index 62% rename from docker-compose/examples/grafana/env/fully.qualified.domain.name.example rename to docker-compose/examples/grafana/env/fqdn_context.env.example index b482555..cfec8dd 100644 --- a/docker-compose/examples/grafana/env/fully.qualified.domain.name.example +++ b/docker-compose/examples/grafana/env/fqdn_context.env.example @@ -6,6 +6,7 @@ CONTEXT=cncf # --- # GRAFANA_VERSION=x.y.z # NGINX_VERSION=x.y.z +# GRAFANA_VIP=10.1.1.2 @@ -24,6 +25,16 @@ CONTEXT=cncf +# Subnet to use for this Docker Compose project. Docker defaults to +# container networks in prefix 172.16.0.0/12 which is 1 million addresses in +# the range from 172.16.0.0 to 172.31.255.255. Docker uses 172.17.0.0/16 for +# itself. Use any sensible prefix in 172.16.0.0/12 here except for Docker's +# own 172.17.0.0/16. +# --- +SUBNET=172.30.95.0/24 + + + # See 'docker-compose.override.yml' for how to make a variable available in # a Dockerfile # --- diff --git a/docker-compose/examples/hashicorpvault/docker-compose.yml b/docker-compose/examples/hashicorpvault/docker-compose.yml index 6e0ecf9..0d917e1 100644 --- a/docker-compose/examples/hashicorpvault/docker-compose.yml +++ b/docker-compose/examples/hashicorpvault/docker-compose.yml @@ -25,4 +25,4 @@ networks: ipam: driver: default config: - # - subnet: 172.21.184.0/24 + - subnet: ${SUBNET} diff --git a/docker-compose/examples/hashicorpvault/env/fully.qualified.domain.name.example b/docker-compose/examples/hashicorpvault/env/fqdn_context.env.example similarity index 62% rename from docker-compose/examples/hashicorpvault/env/fully.qualified.domain.name.example rename to docker-compose/examples/hashicorpvault/env/fqdn_context.env.example index dd4646f..b43af71 100644 --- a/docker-compose/examples/hashicorpvault/env/fully.qualified.domain.name.example +++ b/docker-compose/examples/hashicorpvault/env/fqdn_context.env.example @@ -5,6 +5,7 @@ CONTEXT=fsf # Set something sensible here and uncomment # --- # VAULT_VERSION=x.y.z +# VAULT_VIP=10.1.1.2 @@ -23,6 +24,16 @@ CONTEXT=fsf +# Subnet to use for this Docker Compose project. Docker defaults to +# container networks in prefix 172.16.0.0/12 which is 1 million addresses in +# the range from 172.16.0.0 to 172.31.255.255. Docker uses 172.17.0.0/16 for +# itself. Use any sensible prefix in 172.16.0.0/12 here except for Docker's +# own 172.17.0.0/16. +# --- +SUBNET=172.30.95.0/24 + + + # See 'docker-compose.override.yml' for how to make a variable available in # a Dockerfile # --- diff --git a/docker-compose/{{ cookiecutter.__project_slug }}/README.md b/docker-compose/{{ cookiecutter.__project_slug }}/README.md new file mode 100644 index 0000000..c395ae2 --- /dev/null +++ b/docker-compose/{{ cookiecutter.__project_slug }}/README.md @@ -0,0 +1,80 @@ +# {{ cookiecutter.__service_slug.capitalize() }} Docker Compose files + +Docker Compose files to spin up an instance of {{ cookiecutter.__service_slug.capitalize() }}. + +# How to run + +Add a `COMPOSE_ENV` file and save its location as a shell variable along with the location where this repo lives, here for example `/opt/containers/{{ cookiecutter.__project_slug }}` plus all other variables. At [env/fqdn_context.env.example](env/fqdn_context.env.example) you'll find an example environment file. + +When everything's ready start {{ cookiecutter.__service_slug.capitalize() }} with Docker Compose, otherwise head down to [Initial setup](#initial-setup) first. + +## Environment +``` +export COMPOSE_DIR='/opt/containers/{{ cookiecutter.__project_slug }}' +export COMPOSE_CTX='{{ cookiecutter.__context_slug }}' +export COMPOSE_PROJECT='{{ cookiecutter.__service_slug }}-'"${COMPOSE_CTX}" +export COMPOSE_FILE="${COMPOSE_DIR}"'/docker-compose.yml'{% if cookiecutter.build == "yes" %} +export COMPOSE_OVERRIDE="${COMPOSE_DIR%/}"'/docker-compose.override.yml'{% endif %} +export COMPOSE_ENV= +``` + +{%- if cookiecutter.build == "yes" %} + +## Build + +``` +docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE}" --env-file "${COMPOSE_ENV}" --profile 'build' build +``` +{%- endif %} + +## Start + +``` +{%- if ',' in cookiecutter.__component_list_slug %} +docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach +{%- else %} +docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" up --detach +{%- endif %} +``` + +# Initial setup + +We're assuming you run Docker Compose workloads with ZFS-based bind mounts. ZFS management, creating a zpool and setting adequate properties for its datasets is out of scope of this document. + +## Datasets + +Create ZFS datasets and set permissions as needed. + +* Parent dateset + ``` + zfs create -o mountpoint=/opt/docker-data 'zpool/docker-data' + ``` + +* Container-specific datasets + ``` +{%- if ',' in cookiecutter.__component_list_slug -%} +{%- set components = cookiecutter.__component_list_slug.split(',') -%} +{%- for component in components %} + zfs create -p 'zpool/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ component }}/data/db' + zfs create -p 'zpool/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ component }}/data/logs' + zfs create -p 'zpool/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ component }}/config' +{%- endfor -%} +{%- else %} + zfs create -p 'zpool/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ cookiecutter.__service_slug }}/data/db' + zfs create -p 'zpool/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ cookiecutter.__service_slug }}/data/logs' + zfs create -p 'zpool/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ cookiecutter.__service_slug }}/config' +{%- endif %} + ``` + When changing bind mount locations to real ones remember to also update `volumes:` in [docker-compose.yml](docker-compose.yml). + +* Change ownership + ``` +{%- set components = cookiecutter.__component_list_slug.split(',') -%} +{% for component in components %} +{%- if loop.first %} + chown -R 1000:1000 '/opt/docker-data/{{ cookiecutter.__service_slug }}-${COMPOSE_CTX}/{{ cookiecutter.__service_slug }}/data' +{%- endif %} +{%- endfor %} + ``` + +When done head back up to [How to run](#how-to-run). diff --git a/docker-compose/{{ cookiecutter.__project_slug }}/docker-compose.yml b/docker-compose/{{ cookiecutter.__project_slug }}/docker-compose.yml index 3be4ce4..0ed11c1 100644 --- a/docker-compose/{{ cookiecutter.__project_slug }}/docker-compose.yml +++ b/docker-compose/{{ cookiecutter.__project_slug }}/docker-compose.yml @@ -1,6 +1,15 @@ services: {%- if ',' in cookiecutter.__component_list_slug -%} {%- set components = cookiecutter.__component_list_slug.split(',') -%} +{%- set ns = namespace(found=false) -%} +{%- for component in components %} + {%- if loop.first -%} + {%- set ns.first_component = component -%} + {%- elif N is undefined -%} + {%- set ns.second_component = component -%} + {%- set N = 0 -%} + {%- endif -%} +{%- endfor -%} {%- for component in components %} {{ component }}: image: "{{ component }}:${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}" @@ -8,15 +17,29 @@ services: networks: {{ cookiecutter.__service_slug }}-default: profiles: ["full", "{{ component }}"] + {% if loop.first -%} + depends_on: + {{ ns.second_component }}: + condition: service_healthy + {%- else -%} + healthcheck: + test: ["CMD", "fping", "--count=1", "${% raw %}{{% endraw %}{{ ns.first_component.upper() }}_VIP{% raw %}}{% endraw %}", "--period=500", "--quiet"] + interval: 3s + timeout: 1s + retries: 60 + start_period: 2s + {%- endif %} extends: file: common-settings.yml service: common-settings ports: # - "8080:80" volumes: - # - /opt/docker-data/{{ cookiecutter.__service_slug }}-{{ component }}-${CONTEXT}/{{ component }}/data/db:/usr/lib/{{ component }} - # - /opt/docker-data/{{ cookiecutter.__service_slug }}-{{ component }}-${CONTEXT}/{{ component }}/data/logs:/var/log/{{ component }} - # - /opt/docker-data/{{ cookiecutter.__service_slug }}-{{ component }}-${CONTEXT}/{{ component }}/config:/etc/{{ component }} + # When changing bind mount locations to real ones remember to + # also update "Initial setup" section in README.md. + # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/{{ component }}/data/db:/usr/lib/{{ component }} + # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/{{ component }}/data/logs:/var/log/{{ component }} + # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/{{ component }}/config:/etc/{{ component }} environment: # {{ component.upper() }}_USER: ${% raw %}{{% endraw %}{{ component.upper() }}_USER{% raw %}}{% endraw %} # {{ component.upper() }}_PASSWORD: ${% raw %}{{% endraw %}{{ component.upper() }}_PASSWORD{% raw %}}{% endraw %} @@ -33,9 +56,11 @@ services: ports: # - "8080:80" volumes: - # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/data/db:/usr/lib/{{ cookiecutter.__service_slug }} - # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/data/logs:/var/log/{{ cookiecutter.__service_slug }} - # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/config:/etc/{{ cookiecutter.__service_slug }} + # When changing bind mount locations to real ones remember to + # also update "Initial setup" section in README.md. + # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/{{ cookiecutter.__service_slug }}/data/db:/usr/lib/{{ cookiecutter.__service_slug }} + # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/{{ cookiecutter.__service_slug }}/data/logs:/var/log/{{ cookiecutter.__service_slug }} + # - /opt/docker-data/{{ cookiecutter.__service_slug }}-${CONTEXT}/{{ cookiecutter.__service_slug }}/config:/etc/{{ cookiecutter.__service_slug }} environment: # {{ cookiecutter.__component_list_slug.upper() }}_USER: ${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_USER{% raw %}}{% endraw %} # {{ cookiecutter.__component_list_slug.upper() }}_PASSWORD: ${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_PASSWORD{% raw %}}{% endraw %} @@ -49,4 +74,4 @@ networks: ipam: driver: default config: - # - subnet: 172.21.184.0/24 + - subnet: ${SUBNET} diff --git a/docker-compose/{{ cookiecutter.__project_slug }}/env/fully.qualified.domain.name.example b/docker-compose/{{ cookiecutter.__project_slug }}/env/fqdn_context.env.example similarity index 62% rename from docker-compose/{{ cookiecutter.__project_slug }}/env/fully.qualified.domain.name.example rename to docker-compose/{{ cookiecutter.__project_slug }}/env/fqdn_context.env.example index fc0b853..78f62a3 100644 --- a/docker-compose/{{ cookiecutter.__project_slug }}/env/fully.qualified.domain.name.example +++ b/docker-compose/{{ cookiecutter.__project_slug }}/env/fqdn_context.env.example @@ -8,6 +8,11 @@ CONTEXT={{ cookiecutter.__context_slug }} {% for component in components %} # {{ component.upper() }}_VERSION=x.y.z {%- endfor %} +{%- for component in components %} +{%- if loop.first %} +# {{ component.upper() }}_VIP=10.1.1.2 +{%- endif %} +{%- endfor %} @@ -26,6 +31,16 @@ CONTEXT={{ cookiecutter.__context_slug }} +# Subnet to use for this Docker Compose project. Docker defaults to +# container networks in prefix 172.16.0.0/12 which is 1 million addresses in +# the range from 172.16.0.0 to 172.31.255.255. Docker uses 172.17.0.0/16 for +# itself. Use any sensible prefix in 172.16.0.0/12 here except for Docker's +# own 172.17.0.0/16. +# --- +SUBNET=172.30.95.0/24 + + + # See 'docker-compose.override.yml' for how to make a variable available in # a Dockerfile # ---