diff --git a/CHANGELOG.md b/CHANGELOG.md index e6a994073fba22a4aeeec278bbaa5c535cf1f204..e0b70b1d983d3dc6db5e0cd4b9827484fff40e85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ -## [1.0.2](https://git.code.tecnalia.dev/smartdatalab/public/ci-cd-components/docker-compose/compare/1.0.1...1.0.2) (2024-09-13) +# [1.1.0](https://gitlab.com/to-be-continuous/docker-compose/compare/1.0.2...1.1.0) (2024-12-30) ### Bug Fixes -* **workflow:** disable MR pipeline from prod & integ branches ([bedff8b](https://git.code.tecnalia.dev/smartdatalab/public/ci-cd-components/docker-compose/commit/bedff8bbf87b5e77e66cbd34fdc08103f2cac8e5)) +* boolean value in yaml ([b1df497](https://gitlab.com/to-be-continuous/docker-compose/commit/b1df4975f45c102cd1bc566347d7c536b854ab6b)) + + +### Features + +* add Docker Swarm support ([6c9b90f](https://gitlab.com/to-be-continuous/docker-compose/commit/6c9b90f3a36ef3db20dbe32530bce6ccd8094487)) ## [1.0.2](https://gitlab.com/to-be-continuous/docker-compose/compare/1.0.1...1.0.2) (2024-05-05) diff --git a/README.md b/README.md index b24946af980293e89f6f9334f1eba2705473af01..4c29cfa0602f986918f3777a472b80d314fff89b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # GitLab CI template for Docker Compose -This project implements a GitLab CI/CD template to deploy your application with [Docker Compose](https://docs.docker.com/compose/). +This project implements a GitLab CI/CD template to deploy your application with [Docker Compose](https://docs.docker.com/compose/) or [Docker Swarm](https://docs.docker.com/engine/swarm/). ## Usage @@ -14,7 +14,7 @@ Add the following to your `.gitlab-ci.yml`: ```yaml include: # 1: include the component - - component: $CI_SERVER_FQDN/to-be-continuous/docker-compose/gitlab-ci-docker-compose@1.0.2 + - component: $CI_SERVER_FQDN/to-be-continuous/docker-compose/gitlab-ci-docker-compose@1.1.0 # 2: set/override component inputs inputs: # ⚠ this is only an example @@ -32,7 +32,7 @@ Add the following to your `.gitlab-ci.yml`: include: # 1: include the template - project: 'to-be-continuous/docker-compose' - ref: '1.0.2' + ref: '1.1.0' file: '/templates/gitlab-ci-docker-compose.yml' variables: @@ -50,7 +50,7 @@ This chapter introduces key notions and principle to understand how this templat ### Managed deployment environments -This template implements continuous delivery/continuous deployment for projects hosted on Docker Compose. +This template implements continuous delivery/continuous deployment for projects hosted on Docker Compose or Docker Swarm. It allows you to manage automatic deployment & cleanup of standard predefined environments. Each environment can be enabled/disabled by configuration. @@ -107,7 +107,7 @@ that you might use in your hook scripts or [Docker Compose files](https://docs.d * `${environment_type}`: the current deployment environment type (`review`, `integration`, `staging` or `production`) * `${environment_name}`: a generated application name to use for the current deployment environment (ex: `myapp-review-fix-bug-12` or `myapp-staging`) - _details below_ -> :information_source: the `${environment_name}` is used by the Docker Compose template as the [Docker Compose project name](https://docs.docker.com/compose/project-name/). +> :information_source: the `${environment_name}` is used by the Docker Compose template as the [Docker Compose project name](https://docs.docker.com/compose/project-name/) or Docker Stack project name. #### Generated environment name @@ -204,12 +204,17 @@ and implement the following [dotenv files](https://docs.docker.com/compose/envir 1. a `.env` file defining defaults for all environments, 2. a `${environment_type}.env` file that might redefine or override defaults for a specific environment (e.g. `staging.env`). + +#### Docker Swarm + +Setting the `DCMP_CMD` variable to `docker stack` allows targetting a cluster hence multiple hosts to deploy your containers. It uses the same configuration and dotenv files lookup strategy as the classic Docker Compose workflow. + #### Deployment The **deployment** is processed as follows by the template: 1. _optionally_ executes the `pre-compose-up.sh` script found in your project to perform pre-deployment stuff (for e.g. create required services), -2. runs [`docker-compose up`](https://docs.docker.com/reference/cli/docker/compose/up/), +2. runs [`docker-compose up`](https://docs.docker.com/reference/cli/docker/compose/up/) or [`docker stack deploy`](https://docs.docker.com/reference/cli/docker/stack/deploy/) based on the `DCMP_CMD` variable, 3. _optionally_ executes the `post-compose-up.sh` script found in your project to perform post-deployment stuff, > :information_source: Important: @@ -222,7 +227,7 @@ The **deployment** is processed as follows by the template: The **cleanup** is processed as follows by the template: 1. _optionally_ executes the `pre-compose-down.sh` script found in your project to perform pre-cleanup stuff, -2. runs [`docker-compose down`](https://docs.docker.com/reference/cli/docker/compose/down/), +2. runs [`docker-compose down`](https://docs.docker.com/reference/cli/docker/compose/down/) or [`docker stack rm`](https://docs.docker.com/reference/cli/docker/stack/rm/) based on the `DCMP_CMD` variable, 3. _optionally_ executes the `post-compose-down.sh` script found in your project to perform post-cleanup stuff, > :information_source: Important: @@ -310,18 +315,18 @@ Here are some advices about your **secrets** (variables marked with a :lock:): The Docker Compose template uses some global configuration used throughout all jobs and environments. -| Input / Variable | Description | Default value | -| ------------------------ | -------------------------------------- | ----------------- | -| `image` / `DCMP_IMAGE` | the Docker image used to run Docker Compose CLI commands | `registry.hub.docker.com/library/docker:latest` | -| `cmd` / `DCMP_CMD` | The docker compose command (`docker compose` or `docker-compose`) | _none_ (auto) | -| `base-app-name` / `DCMP_BASE_APP_NAME`| Base application name | `$CI_PROJECT_NAME` ([see GitLab doc](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)) | +| Input / Variable | Description | Default value | +| ------------------------ |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------------- | +| `image` / `DCMP_IMAGE` | The Docker image used to run Docker Compose CLI commands | `registry.hub.docker.com/library/docker:latest` | +| `cmd` / `DCMP_CMD` | The docker compose or stack command (`docker compose`, `docker-compose` or `docker stack`) | _none_ (auto) | +| `base-app-name` / `DCMP_BASE_APP_NAME`| Base application name | `$CI_PROJECT_NAME` ([see GitLab doc](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)) | | `environment-url` / `DCMP_ENVIRONMENT_URL`| Default environments url _(only define for static environment URLs declaration)_<br/>_supports late variable expansion (ex: `https://%{environment_name}.docker-compose.acme.com`)_ | _none_ | -| `scripts-dir` / `DCMP_SCRIPTS_DIR`| Directory where Compose files, dotenv files and hook scripts are located | `.` _(root project dir)_ | -| `up-opts` / `DCMP_UP_OPTS` | [`compose up` options](https://docs.docker.com/reference/cli/docker/compose/up/#options) | `--no-build --remove-orphans --wait --wait-timeout 180` | -| `down-opts`/ `DCMP_DOWN_OPTS` | [`compose down` options](https://docs.docker.com/reference/cli/docker/compose/down/#options) | `--volumes --remove-orphans --rmi all` | -| :lock: `DCMP_SSH_PRIVATE_KEY` | Default SSH key to use when connecting to Docker hosts over SSH (can be overridden per env) | _none_ | -| `ssh-known-hosts` / `DCMP_SSH_KNOWN_HOSTS` | SSH `known_hosts` (file or text variable) | _none_ | -| `compose-cleanup-review-job-tags` / `COMPOSE_CLEANUP_REVIEW_JOB_TAGS` | Tags to be used for selecting runners for the job | [] | +| `scripts-dir` / `DCMP_SCRIPTS_DIR`| Directory where Compose files, dotenv files and hook scripts are located | `.` _(root project dir)_ | +| `up-opts` / `DCMP_UP_OPTS` | [`compose up` options](https://docs.docker.com/reference/cli/docker/compose/up/#options) (only when using Docker Compose) | `--no-build --remove-orphans --wait --wait-timeout 180` | +| `down-opts`/ `DCMP_DOWN_OPTS` | [`compose down` options](https://docs.docker.com/reference/cli/docker/compose/down/#options) (only when using Docker Compose) | `--volumes --remove-orphans --rmi all` | +| `stack-deploy-opts` / `DCMP_STACK_DEPLOY_OPTS` | [`stack deploy` options](https://docs.docker.com/reference/cli/docker/stack/deploy/) (only when using Docker Stack) | `--prune` | +| :lock: `DCMP_SSH_PRIVATE_KEY` | Default SSH key to use when connecting to Docker hosts over SSH (can be overridden per env) | _none_ | +| `ssh-known-hosts` / `DCMP_SSH_KNOWN_HOSTS` | SSH `known_hosts` (file or text variable: you can get its value with `ssh-keyscan -H <DOCKER_HOST>`, mandatory if you're using a remote docker through ssh) | _none_ | ### Review environments configuration @@ -393,7 +398,7 @@ Here are variables supported to configure the production environment: ### Compose Config job -The Docker Compose template enables running [Compose Config](https://docs.docker.com/reference/cli/docker/compose/config/), thus enabling detection of syntax errors in your Compose or dotenv files. +The Docker Compose template enables running [Compose Config](https://docs.docker.com/reference/cli/docker/compose/config/) or [Stack Config](https://docs.docker.com/reference/cli/docker/stack/config/) based on `$DCMP_CMD`, thus enabling detection of syntax errors in your Compose, dotenv or Stack files. This job is mapped to the `package-test` stage and is **active** by default. @@ -403,4 +408,9 @@ Here are its parameters: | ----------------------- | ----------------------------------------- | ----------------------------- | | `config-disabled` / `DCMP_CONFIG_DISABLED` | Set to `true` to disable `compose config` | _none_ (enabled) | | `config-opts` / `DCMP_CONFIG_OPTS` | [`compose config` options](https://docs.docker.com/reference/cli/docker/compose/config/#options) | `--quiet` _(to avoid displaying secrets inadvertently)_ | +<<<<<<< HEAD | `compose-config-job-tags` / `COMPOSE_CONFIG_JOB_TAGS` | Tags to be used for selecting runners for the job | [] | +======= +| `stack-config-opts` / `DCMP_STACK_CONFIG_OPTS` | [`stack config` options](https://docs.docker.com/reference/cli/docker/stack/config/) | "" | +| `stack-config-silent` / `DCMP_STACK_CONFIG_SILENT` | Silences standard output of `stack config` command | `true` (standard output silenced) | +>>>>>>> upstream/main diff --git a/bumpversion.sh b/bumpversion.sh index 329e866dac988c049574a0a9f26ba89979c523a8..708faf434d2459d63b2bdaceada5eb32b0fd39eb 100755 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -27,7 +27,7 @@ if [[ "$curVer" ]]; then log_info "Bump version from \\e[33;1m${curVer}\\e[0m to \\e[33;1m${nextVer}\\e[0m (release type: $relType)..." # replace in README - sed -e "s/ref: *'$curVer'/ref: '$nextVer'/" -e "s/ref: *\"$curVer\”/ref: \”$nextVer\”/" -e "s/component: *\(.*\)@$curVer/component: \1@$nextVer/" README.md > README.md.next + sed -e "s/ref: *'$curVer'/ref: '$nextVer'/" -e "s/ref: *\"$curVer\"/ref: \"$nextVer\"/" -e "s/component: *\(.*\)@$curVer/component: \1@$nextVer/" README.md > README.md.next mv -f README.md.next README.md # replace in template and variants diff --git a/kicker.json b/kicker.json index bc69b798a759e88f0584552db014a16e66b9080b..f0cfa1827451487272fdcc1a6b60a071e5f2bc48 100644 --- a/kicker.json +++ b/kicker.json @@ -1,4 +1,3 @@ - { "name": "Docker Compose", "description": "Deploy your application with [Docker Compose](https://docs.docker.com/compose/)", @@ -15,8 +14,8 @@ }, { "name": "DCMP_CMD", - "description": "The docker compose command (empty means _auto_)", - "values": ["", "docker compose", "docker-compose"], + "description": "The docker compose or stack command (empty means _auto_)", + "values": ["", "docker compose", "docker-compose", "docker stack"], "advanced": true }, { @@ -38,14 +37,19 @@ }, { "name": "DCMP_UP_OPTS", - "description": "[`compose up` options](https://docs.docker.com/reference/cli/docker/compose/up/#options)", + "description": "[`compose up` options](https://docs.docker.com/reference/cli/docker/compose/up/#options) (only when using Docker Compose)", "default": "--no-build --remove-orphans --wait --wait-timeout 180" }, { "name": "DCMP_DOWN_OPTS", - "description": "[`compose down` options](https://docs.docker.com/reference/cli/docker/compose/down/#options)", + "description": "[`compose down` options](https://docs.docker.com/reference/cli/docker/compose/down/#options) (only when using Docker Compose)", "default": "--volumes --remove-orphans --rmi all" - }, + }, + { + "name": "DCMP_STACK_DEPLOY_OPTS", + "description": "[`stack deploy` options](https://docs.docker.com/reference/cli/docker/stack/deploy/) (only when using Docker Stack)", + "default": "--prune" + }, { "name": "DCMP_SSH_PRIVATE_KEY", "description": "Default SSH key to use when connecting to Docker hosts over SSH (can be overridden per env)", @@ -62,7 +66,7 @@ "default": [], "advanced": true } -], + ], "features": [ { "id": "config", @@ -82,6 +86,18 @@ "type": "array", "default": [], "advanced": true + }, + { + "name": "DCMP_STACK_CONFIG_OPTS", + "description": "[`stack config` options](https://docs.docker.com/reference/cli/docker/stack/config/)", + "advanced": true + }, + { + "name": "DCMP_STACK_CONFIG_SILENT", + "description": "Silences standard output of `stack config` command", + "type": "boolean", + "default": "true", + "advanced": true } ] }, diff --git a/templates/gitlab-ci-docker-compose.yml b/templates/gitlab-ci-docker-compose.yml index 01b028e3e340ee6441a957bd1f27079c1c443b80..1a952ac4febd687ccd5921bc471291afc5732c18 100644 --- a/templates/gitlab-ci-docker-compose.yml +++ b/templates/gitlab-ci-docker-compose.yml @@ -19,12 +19,13 @@ spec: description: The Docker image used to run Docker Compose CLI commands - **set the version required by your Docker Compose cluster** default: registry.hub.docker.com/library/docker:latest cmd: - description: "The docker compose command (empty means _auto_)" + description: "The docker compose or stack command (empty means _auto_)" default: '' options: - '' - docker compose - docker-compose + - docker stack base-app-name: description: Base application name default: $CI_PROJECT_NAME @@ -40,16 +41,26 @@ spec: config-opts: description: "[`compose config` options](https://docs.docker.com/reference/cli/docker/compose/config/#options)" default: '--quiet' + stack-config-opts: + description: "[`stack config` options](https://docs.docker.com/reference/cli/docker/stack/config/)" + default: '' + stack-config-silent: + description: Silences standard output of `stack config` command + default: true + type: boolean config-disabled: description: Disable Compose Config type: boolean default: false up-opts: - description: "[`compose up` options](https://docs.docker.com/reference/cli/docker/compose/up/#options)" + description: "[`compose up` options](https://docs.docker.com/reference/cli/docker/compose/up/#options) (only when using Docker Compose)" default: "--no-build --remove-orphans --wait --wait-timeout 180" down-opts: - description: "[`compose down` options](https://docs.docker.com/reference/cli/docker/compose/down/#options)" + description: "[`compose down` options](https://docs.docker.com/reference/cli/docker/compose/down/#options) (only when using Docker Compose)" default: "--volumes --remove-orphans --rmi all" + stack-deploy-opts: + description: "[`stack deploy` options](https://docs.docker.com/reference/cli/docker/stack/deploy/) (only when using Docker Stack)" + default: "--prune" ssh-known-hosts: description: SSH `known_hosts` (file or text variable) default: '' @@ -180,9 +191,12 @@ variables: DCMP_SCRIPTS_DIR: $[[ inputs.scripts-dir ]] DCMP_SSH_KNOWN_HOSTS: $[[ inputs.ssh-known-hosts ]] DCMP_CONFIG_OPTS: $[[ inputs.config-opts ]] + DCMP_STACK_CONFIG_OPTS: $[[ inputs.stack-config-opts ]] + DCMP_STACK_CONFIG_SILENT: $[[ inputs.stack-config-silent ]] DCMP_CONFIG_DISABLED: $[[ inputs.config-disabled ]] DCMP_UP_OPTS: $[[ inputs.up-opts ]] DCMP_DOWN_OPTS: $[[ inputs.down-opts ]] + DCMP_STACK_DEPLOY_OPTS: $[[ inputs.stack-deploy-opts ]] DCMP_REVIEW_DOCKER_HOST: $[[ inputs.review-docker-host ]] DCMP_REVIEW_APP_NAME: $[[ inputs.review-app-name ]] @@ -702,9 +716,22 @@ stages: log_info "--- \\e[32mpre-compose-up\\e[0m hook (\\e[33;1m${prescript}\\e[0m) not found: skip" fi - # up (--detach is mandatory and therefore not configurable) - # shellcheck disable=SC2086 - $DCMP_CMD up --detach $DCMP_UP_OPTS + if [[ "$DCMP_CMD" == "docker stack" ]]; then + set -a + for env_file in ${COMPOSE_ENV_FILES//,/$IFS}; do + # shellcheck disable=SC1090 + . "$env_file" + done + set +a + + compose_file_opts="-c ${COMPOSE_FILE//:/ -c }" + # shellcheck disable=SC2086 + $DCMP_CMD deploy --detach=false --with-registry-auth $DCMP_STACK_DEPLOY_OPTS $compose_file_opts "$environment_name" + else + # up (--detach is mandatory and therefore not configurable) + # shellcheck disable=SC2086 + $DCMP_CMD up --detach $DCMP_UP_OPTS + fi # maybe execute post compose-up script postscript="$DCMP_SCRIPTS_DIR/post-compose-up.sh" @@ -743,9 +770,13 @@ stages: log_info "--- \\e[32mpre-compose-down\\e[0m hook (\\e[33;1m${prescript}\\e[0m) not found: skip" fi - # down - # shellcheck disable=SC2086 - $DCMP_CMD down $DCMP_DOWN_OPTS + if [[ "$DCMP_CMD" == "docker stack" ]]; then + $DCMP_CMD rm --detach=false "$environment_name" + else + # down + # shellcheck disable=SC2086 + $DCMP_CMD down $DCMP_DOWN_OPTS + fi # maybe execute post compose-down script postscript="$DCMP_SCRIPTS_DIR/post-compose-down.sh" @@ -773,7 +804,7 @@ stages: image: $DCMP_IMAGE services: - name: "$TBC_TRACKING_IMAGE" - command: ["--service", "docker-compose", "1.0.2"] + command: ["--service", "docker-compose", "1.1.0"] before_script: - !reference [.compose-scripts] - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}" @@ -827,7 +858,16 @@ compose-config: extends: .compose-base stage: package-test script: - - $DCMP_CMD config $DCMP_CONFIG_OPTS + - | + if [[ "$DCMP_CMD" == "docker stack" ]]; then + if [[ "$DCMP_STACK_CONFIG_SILENT" == "true" ]]; then + $DCMP_CMD config -c ${COMPOSE_FILE//:/ -c } $DCMP_STACK_CONFIG_OPTS > /dev/null + else + $DCMP_CMD config -c ${COMPOSE_FILE//:/ -c } $DCMP_STACK_CONFIG_OPTS + fi + else + $DCMP_CMD config $DCMP_CONFIG_OPTS + fi parallel: matrix: - ENV_TYPE: review