Commit 6c9b90f3 authored by Thibault Nocchi's avatar Thibault Nocchi Committed by Pierre Smeyers
Browse files

feat: add Docker Swarm support

parent 4252c8be
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
# 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

@@ -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:
@@ -312,13 +317,14 @@ The Docker Compose template uses some global configuration used throughout all j

| 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) |
| `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` |
| `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) | _none_ |

@@ -388,7 +394,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.

@@ -398,4 +404,5 @@ 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)_ |
| `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) |
 No newline at end of file
+23 −7
Original line number Diff line number Diff line

{
  "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)",
@@ -68,6 +72,18 @@
          "description": "[`compose config` options](https://docs.docker.com/reference/cli/docker/compose/config/#options)",
          "default": "--quiet",
          "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
        }
      ]
    },
+50 −10
Original line number Diff line number Diff line
@@ -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: ''
@@ -156,9 +167,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 ]]
@@ -678,9 +692,22 @@ stages:
      log_info "--- \\e[32mpre-compose-up\\e[0m hook (\\e[33;1m${prescript}\\e[0m) not found: skip"
    fi
 
    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"
@@ -719,9 +746,13 @@ stages:
      log_info "--- \\e[32mpre-compose-down\\e[0m hook (\\e[33;1m${prescript}\\e[0m) not found: skip"
    fi
 
    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"
@@ -803,7 +834,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