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:
| Variable | Description | Default | Required |
|---|---|---|---|
ANSIBLE_MODULE_VERSION | Version/tag of the Ansible module to use | release/0.0.119 | No |
ANSIBLE_MODULE_PATH | GitLab path to the Ansible module repository | welance/platform/infrastructure/modules/ansible.git | No |
ANSIBLE_DIR | Directory where Ansible code will be placed | infrastructure_code/configuration_management/ | No |
HOST | Target host address or hostname | '' | Yes |
VERSION | Docker image version/tag to deploy | '' | Yes |
VAR_FILES | Path to Ansible variable files | '' | No |
APP_ENVIRONMENT | Target environment | '' | Yes |
ANSIBLE_PORT | SSH port for Ansible connection | '' | Yes |
ANSIBLE_USER | SSH user for Ansible connection | '' | Yes |
DOCKER_USERNAME | Docker registry username | '' | Yes |
DOCKER_PASSWORD | Docker registry password | '' | Yes |
DOCKER_CONTEXT | Docker context to use | default | No |
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.versionfile 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 totcp://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 repositoryANSIBLE_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:
- 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:
-
List parent directories (for debugging):
ls -al ../../ -
Source version file:
source ../../.env.version- Loads the
VERSIONvariable from the.env.versionfile created by build jobs
- Loads the
-
Display deployment version:
echo "Deploy version=$VERSION" -
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
-
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-dockerfile with actual values - Displays the configured hosts file
- Replaces placeholders in the
-
Install Ansible Docker collection:
ansible-galaxy collection install community.docker- Installs the community.docker collection required for Docker operations
-
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.ymlfile - Ansible hosts template: A
hosts-dockerfile with placeholders (HOST_TO_BE_REPLACED,USER_TO_BE_REPLACED,PORT_TO_BE_REPLACED) must exist - Version file: A
.env.versionfile 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
VERSIONvariable is typically sourced from.env.versioncreated by build jobs - The
hosts-dockerfile 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_FILESparameter - Docker context can be customized for different deployment scenarios
- The Ansible image
willhallonline/ansible:2.16.4-ubuntu-22.04includes Ansible 2.16.4