Skip to main content

Craft Docker Deploy

The ansible-craft-docker-deploy job is used to deploy Craft CMS applications to Docker hosts using Ansible. It manages Docker container deployments on remote servers.

Overview

This job:

  • Uses Ansible to deploy Craft CMS applications to Docker hosts
  • Clones a specific version of the Ansible module from GitLab
  • Configures SSH access for remote server management
  • Deploys Docker containers with version tags
  • Supports environment-specific deployments (develop, staging, production)
  • Manages Docker registry authentication

Variables

The following variables can be configured:

VariableDescriptionDefaultRequired
ANSIBLE_MODULE_VERSIONVersion/tag of the Ansible module to userelease/0.0.119No
ANSIBLE_MODULE_PATHGitLab path to the Ansible module repositorywelance/platform/infrastructure/modules/ansible.gitNo
ANSIBLE_DIRDirectory where Ansible code will be placedinfrastructure_code/configuration_management/No
HOSTTarget host address or hostname''Yes
VERSIONDocker image version/tag to deploy''Yes
VAR_FILESPath to Ansible variable files''No
APP_ENVIRONMENTTarget environment''Yes
ANSIBLE_PORTSSH port for Ansible connection''Yes
ANSIBLE_USERSSH user for Ansible connection''Yes
DOCKER_USERNAMEDocker registry username''Yes
DOCKER_PASSWORDDocker registry password''Yes
DOCKER_CONTEXTDocker context to usedefaultNo

Variable Details

  • ANSIBLE_MODULE_VERSION: The Git tag or branch of the Ansible module repository to use (e.g., release/0.0.119)
  • ANSIBLE_MODULE_PATH: The GitLab project path to the Ansible module repository
  • ANSIBLE_DIR: Local directory where the Ansible module will be cloned and executed from
  • HOST: The target server hostname or IP address where the deployment will occur
  • VERSION: The Docker image version/tag to deploy. Typically sourced from .env.version file created by build jobs
  • VAR_FILES: Path to Ansible variable files (JSON or YAML) to pass additional configuration
  • APP_ENVIRONMENT: Target environment for deployment. Options:
    • 'develop' - Development environment
    • 'staging' - Staging environment
    • 'production' - Production environment
  • ANSIBLE_PORT: SSH port number for connecting to the target host (e.g., 22, 2222)
  • ANSIBLE_USER: SSH username for authenticating to the target host
  • DOCKER_USERNAME: Username for authenticating to the Docker registry
  • DOCKER_PASSWORD: Password or token for authenticating to the Docker registry
  • DOCKER_CONTEXT: Docker context to use for deployment (defaults to default)

GitLab CI/CD Variables

The job uses the following built-in GitLab CI/CD variables:

  • DOCKER_HOST: Docker daemon connection (set to tcp://docker:2376)
  • DOCKER_TLS_CERTDIR: Docker TLS certificate directory (set to "/certs")

Required Secrets

The following secrets must be configured in GitLab CI/CD variables:

  • ACCESS_TOKEN: GitLab OAuth token with access to clone the Ansible module repository
  • ANSIBLE_SSH_ID_RSA: SSH private key content for authenticating to target servers

Usage

Basic Usage

variables:
ANSIBLE_MODULE_VERSION: release/0.0.119
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
HOST: 'example.com'
VERSION: ''
VAR_FILES: ''
APP_ENVIRONMENT: 'develop'
ANSIBLE_PORT: '22'
ANSIBLE_USER: 'deploy'
DOCKER_USERNAME: 'registry-user'
DOCKER_PASSWORD: 'registry-password'
DOCKER_CONTEXT: 'default'

.ansible-craft-docker-deploy:
image: willhallonline/ansible:2.16.4-ubuntu-22.04
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
ANSIBLE_DIR: infrastructure_code/configuration_management/
HOST: ''
VERSION: ''
VAR_FILES: ''
APP_ENVIRONMENT: ''
ANSIBLE_PORT: ''
ANSIBLE_USER: ''
DOCKER_USERNAME: ''
DOCKER_PASSWORD: ''
DOCKER_CONTEXT: default
before_script:
- echo "clone ansible module version "
- git clone --depth 1 --branch $ANSIBLE_MODULE_VERSION https://oauth2:[email protected]/$ANSIBLE_MODULE_PATH
- mv ansible/* $ANSIBLE_DIR
- cd $ANSIBLE_DIR
script:
- ls -al ../../
- source ../../.env.version
- echo "Deploy version=$VERSION"
- mkdir -p ~/.ssh/ && touch ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- cat $ANSIBLE_SSH_ID_RSA > ~/.ssh/id_rsa
- sed -i "s/HOST_TO_BE_REPLACED/${HOST}/g" hosts-docker
- sed -i "s/USER_TO_BE_REPLACED/${ANSIBLE_USER}/g" hosts-docker
- sed -i "s/PORT_TO_BE_REPLACED/${ANSIBLE_PORT}/g" hosts-docker
- cat hosts-docker
- ansible-galaxy collection install community.docker
- ansible-playbook playbook-craft-docker.yml -i hosts-docker --extra-vars "@${VAR_FILES}" --extra-vars "env=$APP_ENVIRONMENT" --extra-vars "tag=$VERSION" --extra-vars "docker_registry_username=$DOCKER_USERNAME" --extra-vars "docker_context=$DOCKER_CONTEXT" --extra-vars "docker_registry_password=$DOCKER_PASSWORD" --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" --private-key="~/.ssh/id_rsa"

Job Details

Before Script

The before_script section performs the following setup:

  1. Clone Ansible module:
    git clone --depth 1 --branch $ANSIBLE_MODULE_VERSION https://oauth2:[email protected]/$ANSIBLE_MODULE_PATH
    mv ansible/* $ANSIBLE_DIR
    cd $ANSIBLE_DIR
    • Clones only the specified version (shallow clone)
    • Moves Ansible files to the configured directory
    • Changes to the Ansible directory

Script

The main script performs the following steps:

  1. List parent directories (for debugging):

    ls -al ../../
  2. Source version file:

    source ../../.env.version
    • Loads the VERSION variable from the .env.version file created by build jobs
  3. Display deployment version:

    echo "Deploy version=$VERSION"
  4. Configure SSH key:

    mkdir -p ~/.ssh/ && touch ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
    cat $ANSIBLE_SSH_ID_RSA > ~/.ssh/id_rsa
    • Creates SSH directory and key file
    • Sets proper permissions (600)
    • Writes the SSH private key from GitLab variable
  5. Configure Ansible hosts file:

    sed -i "s/HOST_TO_BE_REPLACED/${HOST}/g" hosts-docker
    sed -i "s/USER_TO_BE_REPLACED/${ANSIBLE_USER}/g" hosts-docker
    sed -i "s/PORT_TO_BE_REPLACED/${ANSIBLE_PORT}/g" hosts-docker
    cat hosts-docker
    • Replaces placeholders in the hosts-docker file with actual values
    • Displays the configured hosts file
  6. Install Ansible Docker collection:

    ansible-galaxy collection install community.docker
    • Installs the community.docker collection required for Docker operations
  7. Run Ansible playbook:

    ansible-playbook playbook-craft-docker.yml \
    -i hosts-docker \
    --extra-vars "@${VAR_FILES}" \
    --extra-vars "env=$APP_ENVIRONMENT" \
    --extra-vars "tag=$VERSION" \
    --extra-vars "docker_registry_username=$DOCKER_USERNAME" \
    --extra-vars "docker_context=$DOCKER_CONTEXT" \
    --extra-vars "docker_registry_password=$DOCKER_PASSWORD" \
    --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" \
    --private-key="~/.ssh/id_rsa"

    Playbook Parameters:

    • playbook-craft-docker.yml: The Ansible playbook for Craft Docker deployment
    • -i hosts-docker: Inventory file with target hosts
    • --extra-vars "@${VAR_FILES}": Loads additional variables from file (if provided)
    • --extra-vars "env=$APP_ENVIRONMENT": Sets the target environment
    • --extra-vars "tag=$VERSION": Sets the Docker image version/tag
    • --extra-vars "docker_registry_username=$DOCKER_USERNAME": Docker registry username
    • --extra-vars "docker_context=$DOCKER_CONTEXT": Docker context to use
    • --extra-vars "docker_registry_password=$DOCKER_PASSWORD": Docker registry password
    • --private-key="~/.ssh/id_rsa": SSH private key for authentication

Configuration Examples

Development Environment

variables:
ANSIBLE_MODULE_VERSION: release/0.0.119
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
HOST: 'dev.example.com'
APP_ENVIRONMENT: 'develop'
ANSIBLE_PORT: '22'
ANSIBLE_USER: 'deploy'
DOCKER_USERNAME: '${CI_REGISTRY_USER}'
DOCKER_PASSWORD: '${CI_REGISTRY_PASSWORD}'
DOCKER_CONTEXT: 'default'

deploy-craft-dev:
extends: .ansible-craft-docker-deploy
stage: deploy
only:
- develop

Production Environment with Custom Variables

variables:
ANSIBLE_MODULE_VERSION: release/0.0.119
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
HOST: 'prod.example.com'
APP_ENVIRONMENT: 'production'
ANSIBLE_PORT: '2222'
ANSIBLE_USER: 'deploy'
VAR_FILES: 'vars/production.yml'
DOCKER_USERNAME: '${CI_REGISTRY_USER}'
DOCKER_PASSWORD: '${CI_REGISTRY_PASSWORD}'
DOCKER_CONTEXT: 'production'

deploy-craft-prod:
extends: .ansible-craft-docker-deploy
stage: deploy
only:
- main
- tags

Complete Pipeline Example

variables:
ANSIBLE_MODULE_VERSION: release/0.0.119
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git

stages:
- build
- deploy

# Build job creates .env.version file
build:
stage: build
script:
- echo "VERSION=main-12345" > .env.version
artifacts:
paths:
- .env.version

.ansible-craft-docker-deploy:
image: willhallonline/ansible:2.16.4-ubuntu-22.04
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
ANSIBLE_DIR: infrastructure_code/configuration_management/
HOST: ''
VERSION: ''
VAR_FILES: ''
APP_ENVIRONMENT: ''
ANSIBLE_PORT: ''
ANSIBLE_USER: ''
DOCKER_USERNAME: ''
DOCKER_PASSWORD: ''
DOCKER_CONTEXT: default
before_script:
- echo "clone ansible module version "
- git clone --depth 1 --branch $ANSIBLE_MODULE_VERSION https://oauth2:[email protected]/$ANSIBLE_MODULE_PATH
- mv ansible/* $ANSIBLE_DIR
- cd $ANSIBLE_DIR
script:
- ls -al ../../
- source ../../.env.version
- echo "Deploy version=$VERSION"
- mkdir -p ~/.ssh/ && touch ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- cat $ANSIBLE_SSH_ID_RSA > ~/.ssh/id_rsa
- sed -i "s/HOST_TO_BE_REPLACED/${HOST}/g" hosts-docker
- sed -i "s/USER_TO_BE_REPLACED/${ANSIBLE_USER}/g" hosts-docker
- sed -i "s/PORT_TO_BE_REPLACED/${ANSIBLE_PORT}/g" hosts-docker
- cat hosts-docker
- ansible-galaxy collection install community.docker
- ansible-playbook playbook-craft-docker.yml -i hosts-docker --extra-vars "@${VAR_FILES}" --extra-vars "env=$APP_ENVIRONMENT" --extra-vars "tag=$VERSION" --extra-vars "docker_registry_username=$DOCKER_USERNAME" --extra-vars "docker_context=$DOCKER_CONTEXT" --extra-vars "docker_registry_password=$DOCKER_PASSWORD" --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" --private-key="~/.ssh/id_rsa"

deploy-craft-develop:
extends: .ansible-craft-docker-deploy
variables:
HOST: 'dev.example.com'
APP_ENVIRONMENT: 'develop'
ANSIBLE_PORT: '22'
ANSIBLE_USER: 'deploy'
DOCKER_USERNAME: '${CI_REGISTRY_USER}'
DOCKER_PASSWORD: '${CI_REGISTRY_PASSWORD}'
stage: deploy
dependencies:
- build
only:
- develop

Prerequisites

  • Ansible module repository: The Ansible module must exist at the specified GitLab path
  • SSH access: SSH keys must be configured and have access to target servers
  • GitLab access token: OAuth token with permissions to clone the Ansible module repository
  • Ansible playbook: The repository must contain a playbook-craft-docker.yml file
  • Ansible hosts template: A hosts-docker file with placeholders (HOST_TO_BE_REPLACED, USER_TO_BE_REPLACED, PORT_TO_BE_REPLACED) must exist
  • Version file: A .env.version file must be created by a previous build job
  • Target servers: Servers must be accessible via SSH and have Docker installed
  • Docker registry access: Docker registry credentials must be valid

Security Considerations

  • SSH Keys: Store SSH private key (ANSIBLE_SSH_ID_RSA) as a GitLab CI/CD masked variable
  • Access Token: Store the GitLab access token as a masked and protected variable
  • Docker Credentials: Store Docker registry credentials as masked variables
  • Key Permissions: SSH keys should have minimal required permissions
  • StrictHostKeyChecking: The job disables strict host key checking for convenience, but this should be reviewed for production use

Notes

  • The job uses a shallow clone (--depth 1) to reduce clone time
  • The VERSION variable is typically sourced from .env.version created by build jobs
  • The hosts-docker file is dynamically configured with target host information
  • The Ansible Docker collection (community.docker) is installed automatically
  • Docker registry credentials are passed as Ansible extra variables
  • The job supports custom variable files via the VAR_FILES parameter
  • Docker context can be customized for different deployment scenarios
  • The Ansible image willhallonline/ansible:2.16.4-ubuntu-22.04 includes Ansible 2.16.4