Compare commits
10 Commits
20d303e79a
...
master
Author | SHA1 | Date | |
---|---|---|---|
da60952fe4 | |||
d6ea3f1853 | |||
adb7bf6795 | |||
215db1682d | |||
36f2eecba1 | |||
1f588e90bc | |||
b534a9bccf | |||
e5e78a0527 | |||
d98de5aff0 | |||
ffaf43e56f |
@@ -56,7 +56,7 @@ The end result is a directory structure that has everything you need to hit the
|
|||||||
│  ├── Dockerfile
|
│  ├── Dockerfile
|
||||||
│  └── extras
|
│  └── extras
|
||||||
│  └── .gitkeep
|
│  └── .gitkeep
|
||||||
├── common-settings.yml
|
├── common-settings.yaml
|
||||||
├── compose.override.yaml
|
├── compose.override.yaml
|
||||||
├── compose.yaml
|
├── compose.yaml
|
||||||
├── env
|
├── env
|
||||||
@@ -214,7 +214,7 @@ Make some code changes, for example to the Docker Compose Cookiecutter template.
|
|||||||
│  ├── Dockerfile
|
│  ├── Dockerfile
|
||||||
│  └── extras
|
│  └── extras
|
||||||
│  └── .gitkeep
|
│  └── .gitkeep
|
||||||
├── common-settings.yml
|
├── common-settings.yaml
|
||||||
├── compose.override.yaml
|
├── compose.override.yaml
|
||||||
├── compose.yaml
|
├── compose.yaml
|
||||||
├── env
|
├── env
|
||||||
|
@@ -92,7 +92,7 @@ Above example of a multi-component (two in this case) `grafana` service will giv
|
|||||||
│  ├── Dockerfile
|
│  ├── Dockerfile
|
||||||
│  └── extras
|
│  └── extras
|
||||||
│  └── .gitkeep
|
│  └── .gitkeep
|
||||||
├── common-settings.yml
|
├── common-settings.yaml
|
||||||
├── compose.override.yaml
|
├── compose.override.yaml
|
||||||
├── compose.yaml
|
├── compose.yaml
|
||||||
├── env
|
├── env
|
||||||
@@ -113,7 +113,7 @@ With an alternative single-component `hashicorpvault` service the result may loo
|
|||||||
│  ├── Dockerfile
|
│  ├── Dockerfile
|
||||||
│  └── extras
|
│  └── extras
|
||||||
│  └── .gitkeep
|
│  └── .gitkeep
|
||||||
├── common-settings.yml
|
├── common-settings.yaml
|
||||||
├── compose.override.yaml
|
├── compose.override.yaml
|
||||||
├── compose.yaml
|
├── compose.yaml
|
||||||
├── env
|
├── env
|
||||||
|
@@ -39,18 +39,22 @@ docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --en
|
|||||||
|
|
||||||
## Copy to target
|
## Copy to target
|
||||||
|
|
||||||
Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow:
|
Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub or your private registry of choice. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow:
|
||||||
|
|
||||||
```
|
```
|
||||||
source "${COMPOSE_ENV}"
|
source "${COMPOSE_ENV}"
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME Docker Hub image name with or without slash? FIXME
|
||||||
for image in 'grafana:'"${GRAFANA_VERSION}" 'nginx:'"${NGINX_VERSION}"; do
|
for image in 'grafana:'"${GRAFANA_VERSION}" 'nginx:'"${NGINX_VERSION}"; do
|
||||||
copy-docker.sh "${image}" fully.qualified.domain.name
|
copy-docker "${image}" fully.qualified.domain.name
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start
|
## Start
|
||||||
|
|
||||||
|
FIXME Does the service use a virtual IP address? FIXME
|
||||||
|
|
||||||
|
Make sure your service's virtual IP address is bound on your target host then start containers.
|
||||||
|
|
||||||
```
|
```
|
||||||
docker --context 'fully.qualified.domain.name' compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach
|
docker --context 'fully.qualified.domain.name' compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach
|
||||||
```
|
```
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
grafana-build:
|
grafana-build:
|
||||||
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "grafana:${GRAFANA_VERSION}"
|
image: "grafana:${GRAFANA_VERSION}"
|
||||||
profiles: ["build", "build-grafana"]
|
profiles: ["build", "build-grafana"]
|
||||||
build:
|
build:
|
||||||
@@ -9,6 +10,7 @@ services:
|
|||||||
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
|
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
|
||||||
GRAFANA_VERSION: "${GRAFANA_VERSION}"
|
GRAFANA_VERSION: "${GRAFANA_VERSION}"
|
||||||
nginx-build:
|
nginx-build:
|
||||||
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "nginx:${NGINX_VERSION}"
|
image: "nginx:${NGINX_VERSION}"
|
||||||
profiles: ["build", "build-nginx"]
|
profiles: ["build", "build-nginx"]
|
||||||
build:
|
build:
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
grafana:
|
grafana:
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "grafana:${GRAFANA_VERSION}"
|
image: "grafana:${GRAFANA_VERSION}"
|
||||||
container_name: "grafana-grafana-${CONTEXT}"
|
container_name: "grafana-grafana-${CONTEXT}"
|
||||||
networks:
|
networks:
|
||||||
@@ -10,12 +10,12 @@ services:
|
|||||||
nginx:
|
nginx:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ulimits:
|
ulimits:
|
||||||
nproc: ${ULIMIT_NPROC-65535}
|
nproc: ${ULIMIT_NPROC:-65535}
|
||||||
nofile:
|
nofile:
|
||||||
soft: ${ULIMIT_NPROC-65535}
|
soft: ${ULIMIT_NPROC:-65535}
|
||||||
hard: ${ULIMIT_NPROC-65535}
|
hard: ${ULIMIT_NPROC:-65535}
|
||||||
extends:
|
extends:
|
||||||
file: common-settings.yml
|
file: common-settings.yaml
|
||||||
service: common-settings
|
service: common-settings
|
||||||
ports:
|
ports:
|
||||||
# - "8080:80"
|
# - "8080:80"
|
||||||
@@ -29,7 +29,7 @@ services:
|
|||||||
# GRAFANA_USER: ${GRAFANA_USER}
|
# GRAFANA_USER: ${GRAFANA_USER}
|
||||||
# GRAFANA_PASSWORD: ${GRAFANA_PASSWORD}
|
# GRAFANA_PASSWORD: ${GRAFANA_PASSWORD}
|
||||||
nginx:
|
nginx:
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "nginx:${NGINX_VERSION}"
|
image: "nginx:${NGINX_VERSION}"
|
||||||
container_name: "grafana-nginx-${CONTEXT}"
|
container_name: "grafana-nginx-${CONTEXT}"
|
||||||
networks:
|
networks:
|
||||||
@@ -42,12 +42,12 @@ services:
|
|||||||
retries: 60
|
retries: 60
|
||||||
start_period: 2s
|
start_period: 2s
|
||||||
ulimits:
|
ulimits:
|
||||||
nproc: ${ULIMIT_NPROC-65535}
|
nproc: ${ULIMIT_NPROC:-65535}
|
||||||
nofile:
|
nofile:
|
||||||
soft: ${ULIMIT_NPROC-65535}
|
soft: ${ULIMIT_NPROC:-65535}
|
||||||
hard: ${ULIMIT_NPROC-65535}
|
hard: ${ULIMIT_NPROC:-65535}
|
||||||
extends:
|
extends:
|
||||||
file: common-settings.yml
|
file: common-settings.yaml
|
||||||
service: common-settings
|
service: common-settings
|
||||||
ports:
|
ports:
|
||||||
# - "8080:80"
|
# - "8080:80"
|
||||||
|
@@ -7,6 +7,7 @@ CONTEXT=ux_vilnius
|
|||||||
# GRAFANA_VERSION=x.y.z
|
# GRAFANA_VERSION=x.y.z
|
||||||
# NGINX_VERSION=x.y.z
|
# NGINX_VERSION=x.y.z
|
||||||
# GRAFANA_VIP=10.1.1.2
|
# GRAFANA_VIP=10.1.1.2
|
||||||
|
# GRAFANA_BUILD_DATE=20230731
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -32,15 +32,30 @@ docker context create fully.qualified.domain.name --docker 'host=ssh://root@full
|
|||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
> Skip to [Pull](#pull) if you already have images in your private registry ready to use. Otherwise read on to build them now.
|
||||||
|
|
||||||
FIXME We build the `vault` image locally. Our adjustment to the official image is simply adding `/tmp/vault` to it. See [build-context/Dockerfile](build-context/Dockerfile). We use `/tmp/vault` to bind-mount a dedicated ZFS dataset for the application's `tmpdir` location.
|
FIXME We build the `vault` image locally. Our adjustment to the official image is simply adding `/tmp/vault` to it. See [build-context/Dockerfile](build-context/Dockerfile). We use `/tmp/vault` to bind-mount a dedicated ZFS dataset for the application's `tmpdir` location.
|
||||||
|
|
||||||
```
|
```
|
||||||
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE}" --env-file "${COMPOSE_ENV}" --profile 'build-vault' build
|
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE}" --env-file "${COMPOSE_ENV}" --profile 'build' build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Push
|
||||||
|
|
||||||
|
Push to Docker Hub or your private registry. Setting up a private registry is out of scope of this repo. Once you have a registry available you can use it like so:
|
||||||
|
- On your OS install a Docker credential helper per [github.com/docker/docker-credential-helpers](https://github.com/docker/docker-credential-helpers). This will make sure you won't store credentials hashed (and unencrypted) in `~/.docker/config.json`. On an example Arch Linux machine where D-Bus Secret Service exists this will come via something like the [docker-credential-secretservice-bin](https://aur.archlinux.org/packages/docker-credential-secretservice-bin) Arch User Repository package. Just install and you're done.
|
||||||
|
- Do a `docker login registry.example.com`, enter username and password, confirm login.
|
||||||
|
|
||||||
|
```
|
||||||
|
source "${COMPOSE_ENV}"
|
||||||
|
docker push "registry.example.com/project/vault:${VAULT_BUILD_DATE}-${VAULT_VERSION}"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pull
|
## Pull
|
||||||
|
|
||||||
FIXME Rewrite either [Build](#build) or this paragraph for which images are built and which ones pulled, `--profile 'full'` may not make sense FIXME Pull images from Docker Hub verbatim.
|
> Skip this step if you just built images that still exist locally on your build host.
|
||||||
|
|
||||||
|
FIXME Rewrite either [Build](#build) or this paragraph for which images are built and which ones pulled, `--profile 'full'` may not make sense.
|
||||||
|
|
||||||
```
|
```
|
||||||
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' pull
|
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' pull
|
||||||
@@ -48,12 +63,12 @@ docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --en
|
|||||||
|
|
||||||
## Copy to target
|
## Copy to target
|
||||||
|
|
||||||
Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow:
|
Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub or your private registry of choice. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow:
|
||||||
|
|
||||||
```
|
```
|
||||||
source "${COMPOSE_ENV}"
|
source "${COMPOSE_ENV}"
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME Docker Hub image name with or without slash? FIXME
|
||||||
copy-docker.sh 'vault:'"${VAULT_VERSION}" fully.qualified.domain.name
|
copy-docker 'vault:'"${VAULT_VERSION}" fully.qualified.domain.name
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start
|
## Start
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
services:
|
services:
|
||||||
vault-build:
|
vault-build:
|
||||||
image: "vault:${VAULT_VERSION}"
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
|
image: "registry.example.com/project/vault:${VAULT_BUILD_DATE}-${VAULT_VERSION}"
|
||||||
profiles: ["build"]
|
profiles: ["build"]
|
||||||
build:
|
build:
|
||||||
context: "build-context/vault"
|
context: "build-context"
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
|
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
services:
|
services:
|
||||||
vault:
|
vault:
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "vault:${VAULT_VERSION}"
|
image: "registry.example.com/project/vault:${VAULT_BUILD_DATE}-${VAULT_VERSION}"
|
||||||
container_name: "vault-${CONTEXT}"
|
container_name: "vault-${CONTEXT}"
|
||||||
networks:
|
networks:
|
||||||
vault-default:
|
vault-default:
|
||||||
ulimits:
|
ulimits:
|
||||||
nproc: ${ULIMIT_NPROC-65535}
|
nproc: ${ULIMIT_NPROC:-65535}
|
||||||
nofile:
|
nofile:
|
||||||
soft: ${ULIMIT_NPROC-65535}
|
soft: ${ULIMIT_NPROC:-65535}
|
||||||
hard: ${ULIMIT_NPROC-65535}
|
hard: ${ULIMIT_NPROC:-65535}
|
||||||
extends:
|
extends:
|
||||||
file: common-settings.yml
|
file: common-settings.yaml
|
||||||
service: common-settings
|
service: common-settings
|
||||||
ports:
|
ports:
|
||||||
# - "8080:80"
|
# - "8080:80"
|
||||||
|
@@ -6,6 +6,7 @@ CONTEXT=ux_vilnius
|
|||||||
# ---
|
# ---
|
||||||
# VAULT_VERSION=x.y.z
|
# VAULT_VERSION=x.y.z
|
||||||
# VAULT_VIP=10.1.1.2
|
# VAULT_VIP=10.1.1.2
|
||||||
|
# VAULT_BUILD_DATE=20230731
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -36,18 +36,40 @@ docker context create fully.qualified.domain.name --docker 'host=ssh://root@full
|
|||||||
{% set components = cookiecutter.__component_list_slug.split(',') -%}
|
{% set components = cookiecutter.__component_list_slug.split(',') -%}
|
||||||
{%- for component in components %}
|
{%- for component in components %}
|
||||||
{%- if loop.first %}
|
{%- if loop.first %}
|
||||||
|
> Skip to [Pull](#pull) if you already have images in your private registry ready to use. Otherwise read on to build them now.
|
||||||
|
|
||||||
FIXME We build the `{{ cookiecutter.__service_slug }}` image locally. Our adjustment to the official image is simply adding `/tmp/{{ cookiecutter.__service_slug }}` to it. See {% if ',' in cookiecutter.__component_list_slug %}[build-context/{{ cookiecutter.__service_slug }}/Dockerfile](build-context/{{ cookiecutter.__service_slug }}/Dockerfile){%- else %}[build-context/Dockerfile](build-context/Dockerfile){%- endif %}. We use `/tmp/{{ cookiecutter.__service_slug }}` to bind-mount a dedicated ZFS dataset for the application's `tmpdir` location.
|
FIXME We build the `{{ cookiecutter.__service_slug }}` image locally. Our adjustment to the official image is simply adding `/tmp/{{ cookiecutter.__service_slug }}` to it. See {% if ',' in cookiecutter.__component_list_slug %}[build-context/{{ cookiecutter.__service_slug }}/Dockerfile](build-context/{{ cookiecutter.__service_slug }}/Dockerfile){%- else %}[build-context/Dockerfile](build-context/Dockerfile){%- endif %}. We use `/tmp/{{ cookiecutter.__service_slug }}` to bind-mount a dedicated ZFS dataset for the application's `tmpdir` location.
|
||||||
|
|
||||||
```
|
```
|
||||||
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE}" --env-file "${COMPOSE_ENV}" --profile 'build-{{ cookiecutter.__service_slug }}' build
|
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE}" --env-file "${COMPOSE_ENV}" --profile 'build{% if ',' in cookiecutter.__component_list_slug %}-{{ cookiecutter.__service_slug }}{%- endif %}' build
|
||||||
```
|
```
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{% endfor %}
|
||||||
|
## Push
|
||||||
|
|
||||||
|
Push to Docker Hub or your private registry. Setting up a private registry is out of scope of this repo. Once you have a registry available you can use it like so:
|
||||||
|
- On your OS install a Docker credential helper per [github.com/docker/docker-credential-helpers](https://github.com/docker/docker-credential-helpers). This will make sure you won't store credentials hashed (and unencrypted) in `~/.docker/config.json`. On an example Arch Linux machine where D-Bus Secret Service exists this will come via something like the [docker-credential-secretservice-bin](https://aur.archlinux.org/packages/docker-credential-secretservice-bin) Arch User Repository package. Just install and you're done.
|
||||||
|
- Do a `docker login registry.example.com`, enter username and password, confirm login.
|
||||||
|
|
||||||
|
```
|
||||||
|
source "${COMPOSE_ENV}"
|
||||||
|
{%- set components = cookiecutter.__component_list_slug.split(',') -%}
|
||||||
|
{%- if ',' in cookiecutter.__component_list_slug %}
|
||||||
|
for image in{% for component in components %} \
|
||||||
|
'{%- if cookiecutter.build == "yes" -%}{%- if loop.first -%}registry.example.com/project/{%- endif -%}{%- endif -%}{{ component }}:'"{%- if cookiecutter.build == "yes" -%}{%- if loop.first -%}${% raw %}{{% endraw %}{{ component.upper() }}_BUILD_DATE{% raw %}}{% endraw %}-{%- endif -%}{%- endif -%}${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"{%- endfor %}; do
|
||||||
|
docker push 'registry.example.com/project/'"${image}"
|
||||||
|
done
|
||||||
|
{%- else %}
|
||||||
|
docker push "{%- if cookiecutter.build == "yes" -%}registry.example.com/project/{%- endif -%}{{ cookiecutter.__component_list_slug }}:{%- if cookiecutter.build == "yes" -%}${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_BUILD_DATE{% raw %}}{% endraw %}-{%- endif -%}${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}"
|
||||||
|
{%- endif %}
|
||||||
|
```
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
## Pull
|
## Pull
|
||||||
|
|
||||||
{% if cookiecutter.build == "yes" %}FIXME Rewrite either [Build](#build) or this paragraph for which images are built and which ones pulled, `--profile 'full'` may not make sense FIXME {% endif %}Pull images from Docker Hub verbatim.
|
{% if cookiecutter.build == "yes" %}> Skip this step if you just built images that still exist locally on your build host.
|
||||||
|
|
||||||
|
FIXME Rewrite either [Build](#build) or this paragraph for which images are built and which ones pulled, `--profile 'full'` may not make sense.{% else %}Pull images from Docker Hub verbatim.{% endif %}
|
||||||
|
|
||||||
```
|
```
|
||||||
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' pull
|
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' pull
|
||||||
@@ -55,7 +77,7 @@ docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --en
|
|||||||
|
|
||||||
## Copy to target
|
## Copy to target
|
||||||
|
|
||||||
Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow:
|
Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub or your private registry of choice. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow:
|
||||||
|
|
||||||
```
|
```
|
||||||
source "${COMPOSE_ENV}"
|
source "${COMPOSE_ENV}"
|
||||||
@@ -63,15 +85,23 @@ source "${COMPOSE_ENV}"
|
|||||||
{%- set components = cookiecutter.__component_list_slug.split(',') -%}
|
{%- set components = cookiecutter.__component_list_slug.split(',') -%}
|
||||||
{%- if ',' in cookiecutter.__component_list_slug %}
|
{%- if ',' in cookiecutter.__component_list_slug %}
|
||||||
for image in{% for component in components %} '{{ component }}:'"${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"{%- endfor %}; do
|
for image in{% for component in components %} '{{ component }}:'"${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"{%- endfor %}; do
|
||||||
copy-docker.sh "${image}" fully.qualified.domain.name
|
copy-docker "${image}" fully.qualified.domain.name
|
||||||
done
|
done
|
||||||
{%- else %}
|
{%- else %}
|
||||||
copy-docker.sh '{{ cookiecutter.__component_list_slug }}:'"${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}" fully.qualified.domain.name
|
copy-docker '{{ cookiecutter.__component_list_slug }}:'"${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}" fully.qualified.domain.name
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start
|
## Start
|
||||||
|
|
||||||
|
{%- if ',' in cookiecutter.__component_list_slug %}
|
||||||
|
|
||||||
|
FIXME Does the service use a virtual IP address? FIXME
|
||||||
|
|
||||||
|
Make sure your service's virtual IP address is bound on your target host then start containers.
|
||||||
|
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
```
|
```
|
||||||
{%- if ',' in cookiecutter.__component_list_slug %}
|
{%- if ',' in cookiecutter.__component_list_slug %}
|
||||||
docker --context 'fully.qualified.domain.name' compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach
|
docker --context 'fully.qualified.domain.name' compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach
|
||||||
|
@@ -3,7 +3,8 @@ services:
|
|||||||
{%- set components = cookiecutter.__component_list_slug.split(',') -%}
|
{%- set components = cookiecutter.__component_list_slug.split(',') -%}
|
||||||
{% for component in components %}
|
{% for component in components %}
|
||||||
{{ component }}-build:
|
{{ component }}-build:
|
||||||
image: "{{ component }}:${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
|
image: "{%- if cookiecutter.build == "yes" -%}{%- if loop.first -%}registry.example.com/project/{%- endif -%}{%- endif -%}{{ component }}:{%- if cookiecutter.build == "yes" -%}{%- if loop.first -%}${% raw %}{{% endraw %}{{ component.upper() }}_BUILD_DATE{% raw %}}{% endraw %}-{%- endif -%}{%- endif -%}${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"
|
||||||
profiles: ["build", "build-{{ component }}"]
|
profiles: ["build", "build-{{ component }}"]
|
||||||
build:
|
build:
|
||||||
context: "build-context/{{ component }}"
|
context: "build-context/{{ component }}"
|
||||||
@@ -14,10 +15,11 @@ services:
|
|||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
{{ cookiecutter.__component_list_slug }}-build:
|
{{ cookiecutter.__component_list_slug }}-build:
|
||||||
image: "{{ cookiecutter.__component_list_slug }}:${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}"
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
|
image: "{%- if cookiecutter.build == "yes" -%}registry.example.com/project/{%- endif -%}{{ cookiecutter.__component_list_slug }}:{%- if cookiecutter.build == "yes" -%}${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_BUILD_DATE{% raw %}}{% endraw %}-{%- endif -%}${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}"
|
||||||
profiles: ["build"]
|
profiles: ["build"]
|
||||||
build:
|
build:
|
||||||
context: "build-context/{{ cookiecutter.__component_list_slug }}"
|
context: "build-context"
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
|
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
|
||||||
|
@@ -12,8 +12,8 @@ services:
|
|||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{%- for component in components %}
|
{%- for component in components %}
|
||||||
{{ component }}:
|
{{ component }}:
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "{{ component }}:${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"
|
image: "{%- if cookiecutter.build == "yes" -%}{%- if loop.first -%}registry.example.com/project/{%- endif -%}{%- endif -%}{{ component }}:{%- if cookiecutter.build == "yes" -%}{%- if loop.first -%}${% raw %}{{% endraw %}{{ component.upper() }}_BUILD_DATE{% raw %}}{% endraw %}-{%- endif -%}{%- endif -%}${% raw %}{{% endraw %}{{ component.upper() }}_VERSION{% raw %}}{% endraw %}"
|
||||||
container_name: "{{ cookiecutter.__service_slug }}-{{ component }}-${CONTEXT}"
|
container_name: "{{ cookiecutter.__service_slug }}-{{ component }}-${CONTEXT}"
|
||||||
networks:
|
networks:
|
||||||
{{ cookiecutter.__service_slug }}-default:
|
{{ cookiecutter.__service_slug }}-default:
|
||||||
@@ -31,12 +31,12 @@ services:
|
|||||||
start_period: 2s
|
start_period: 2s
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
ulimits:
|
ulimits:
|
||||||
nproc: ${ULIMIT_NPROC-65535}
|
nproc: ${ULIMIT_NPROC:-65535}
|
||||||
nofile:
|
nofile:
|
||||||
soft: ${ULIMIT_NPROC-65535}
|
soft: ${ULIMIT_NPROC:-65535}
|
||||||
hard: ${ULIMIT_NPROC-65535}
|
hard: ${ULIMIT_NPROC:-65535}
|
||||||
extends:
|
extends:
|
||||||
file: common-settings.yml
|
file: common-settings.yaml
|
||||||
service: common-settings
|
service: common-settings
|
||||||
ports:
|
ports:
|
||||||
# - "8080:80"
|
# - "8080:80"
|
||||||
@@ -52,18 +52,18 @@ services:
|
|||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
{{ cookiecutter.__component_list_slug }}:
|
{{ cookiecutter.__component_list_slug }}:
|
||||||
# FIXME Docker Hub image name with or without slash? FIXME
|
# FIXME image name with or without slash? Docker Hub or private registry? With or without *_BUILD_DATE? FIXME
|
||||||
image: "{{ cookiecutter.__component_list_slug }}:${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}"
|
image: "{%- if cookiecutter.build == "yes" -%}registry.example.com/project/{%- endif -%}{{ cookiecutter.__component_list_slug }}:{%- if cookiecutter.build == "yes" -%}${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_BUILD_DATE{% raw %}}{% endraw %}-{%- endif -%}${% raw %}{{% endraw %}{{ cookiecutter.__component_list_slug.upper() }}_VERSION{% raw %}}{% endraw %}"
|
||||||
container_name: "{{ cookiecutter.__service_slug }}-${CONTEXT}"
|
container_name: "{{ cookiecutter.__service_slug }}-${CONTEXT}"
|
||||||
networks:
|
networks:
|
||||||
{{ cookiecutter.__service_slug }}-default:
|
{{ cookiecutter.__service_slug }}-default:
|
||||||
ulimits:
|
ulimits:
|
||||||
nproc: ${ULIMIT_NPROC-65535}
|
nproc: ${ULIMIT_NPROC:-65535}
|
||||||
nofile:
|
nofile:
|
||||||
soft: ${ULIMIT_NPROC-65535}
|
soft: ${ULIMIT_NPROC:-65535}
|
||||||
hard: ${ULIMIT_NPROC-65535}
|
hard: ${ULIMIT_NPROC:-65535}
|
||||||
extends:
|
extends:
|
||||||
file: common-settings.yml
|
file: common-settings.yaml
|
||||||
service: common-settings
|
service: common-settings
|
||||||
ports:
|
ports:
|
||||||
# - "8080:80"
|
# - "8080:80"
|
||||||
|
@@ -11,6 +11,7 @@ CONTEXT=ux_vilnius
|
|||||||
{%- for component in components %}
|
{%- for component in components %}
|
||||||
{%- if loop.first %}
|
{%- if loop.first %}
|
||||||
# {{ component.upper() }}_VIP=10.1.1.2
|
# {{ component.upper() }}_VIP=10.1.1.2
|
||||||
|
# {{ component.upper() }}_BUILD_DATE=20230731
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user