Image Release Pipeline Template
The image-release.yml pipeline template provides a complete CI/CD workflow for releasing multiple Docker images from a structured directory.
Overview
This template orchestrates the Docker image release process for projects that maintain multiple Docker images in a structured images/ directory, including:
- Semantic versioning validation
- Multi-image Docker builds
- Image tagging with release versions
- Release management and GitLab release creation
Usage
include:
- project: 'welance/platform/pipelines/templates/pipeline/git-flow'
ref: release/1.0.0
file: 'image-release.yml'
variables:
PRODUCTION_TARGET: 'welance'
Pipeline Stages
The Image Release pipeline template includes the following stages:
- init - Version validation and preparation
- build - Multi-image Docker building
- release - Release tagging and GitLab release creation
Included Job Templates
The template includes the following job templates from the ci-jobs repository:
Build Jobs
build/docker-build.yml- Docker image building (includes docker-build-multi)
Release Jobs
release/merge-and-tag.yml- Merge request handling and tagging
Default Variables
variables:
CI_ARTIFACT_TOKEN: $CI_ARTIFACT_PULL_TOKEN
REGISTRY_ID: 4495833
Variable Details
- CI_ARTIFACT_TOKEN: Token for pulling artifacts from other jobs
- REGISTRY_ID: Container registry project ID
- PRODUCTION_TARGET: Must be set to
'welance'for release jobs to run
Version Validation
check_test
- Stage: init
- Purpose: Validates semantic versioning for staging deployments
- Runs on: release/* and hotfix/* branches
- Output: Sets
VERSION={RELEASE}.rc{CI_PIPELINE_IID}(e.g.,1.0.0.rc42) - Validates: Semantic versioning format from branch name
check_prod
- Stage: init
- Purpose: Validates semantic versioning for production deployments
- Runs on: MRs targeting
mainbranch - Output: Sets
VERSION={RELEASE},TAG=v{VERSION},EXTRA_DESCRIPTION - Validates: Semantic versioning format from MR source branch name
Build Jobs
build_images_staging
- Stage: build
- Extends:
.docker-build-multi - Needs: check_test
- Environment: staging
- Runs on: release/* and hotfix/* branches
- Builds: All images in
./images/directory (or specified subset) - Tags: Images with
`{RELEASE}.rc{CI_PIPELINE_IID}`version
build_images_production
- Stage: build
- Extends:
.docker-build-multi - Needs: check_prod
- Environment: production
- Runs on: MRs targeting
mainbranch - Builds: All images in
./images/directory (or specified subset) - Tags: Images with
`{RELEASE}`version
Multi-Image Build
The pipeline uses .docker-build-multi which:
- Scans Directory: Looks for subdirectories in
images/(orIMAGES_ROOT) - Builds Each Image: Builds a Docker image for each subdirectory containing a
Dockerfile - Tags Images: Tags each image with the version (staging:
`{RELEASE}.rc{CI_PIPELINE_IID}`, production:`{RELEASE}`) - Pushes Images: Pushes all built images to the container registry
Image Directory Structure
Expected structure:
.
├── images/
│ ├── image1/
│ │ └── Dockerfile
│ ├── image2/
│ │ └── Dockerfile
│ └── image3/
│ └── Dockerfile
└── .gitlab-ci.yml
Optional Configuration
You can configure which images to build:
build_images_staging:
extends: .docker-build-multi
variables:
APP_ENVIRONMENT: "staging"
IMAGES_ROOT: "images" # optional, defaults to "images"
IMAGES: "image1 image2" # optional: build only specific images
Release Jobs
merge_and_tag
- Stage: release
- Extends:
.merge_and_tag_job - Runs on: MRs targeting
main(when PRODUCTION_TARGET == "welance") - When: manual
- Merges MR, creates realign branch, creates alignment MR
release_job
- Stage: release
- Image:
registry.gitlab.com/gitlab-org/release-cli:latest - Needs: merge_and_tag
- Runs on: MRs targeting
main(when PRODUCTION_TARGET == "welance") - Creates GitLab release with tag and description
Required Variables
PRODUCTION_TARGET- Must be set to'welance'for release jobs to execute
Optional Variables
IMAGES_ROOT- Root directory containing image subdirectories (default:images)IMAGES- Space-separated list of specific images to build (default: all images inIMAGES_ROOT)
Example Configuration
Basic Configuration
include:
- project: 'welance/platform/pipelines/templates/pipeline/git-flow'
ref: release/1.0.0
file: 'image-release.yml'
variables:
PRODUCTION_TARGET: 'welance'
Build Specific Images Only
include:
- project: 'welance/platform/pipelines/templates/pipeline/git-flow'
ref: release/1.0.0
file: 'image-release.yml'
variables:
PRODUCTION_TARGET: 'welance'
build_images_staging:
extends: .docker-build-multi
variables:
APP_ENVIRONMENT: "staging"
IMAGES: "mysql-backup redis-cache" # Build only these images
Custom Images Directory
include:
- project: 'welance/platform/pipelines/templates/pipeline/git-flow'
ref: release/1.0.0
file: 'image-release.yml'
variables:
PRODUCTION_TARGET: 'welance'
build_images_staging:
extends: .docker-build-multi
variables:
APP_ENVIRONMENT: "staging"
IMAGES_ROOT: "docker-images" # Use custom directory
Branch Strategy
- release/{version} - Builds and tags images with staging version (
{version}.rc{CI_PIPELINE_IID}) - hotfix/{version} - Builds and tags images with staging version (
{version}.rc{CI_PIPELINE_IID}) - main (via MR) - Builds and tags images with production version (
{version}), creates release (manual)
Version Tagging
- Staging:
`{RELEASE}.rc{CI_PIPELINE_IID}`(e.g.,1.0.0.rc42) - Production:
`{RELEASE}`(e.g.,1.0.0)
Each image is tagged as: {CI_REGISTRY_IMAGE}/{image-name}:{VERSION}
Image Naming Convention
Images are named based on their subdirectory name:
- Directory:
images/mysql-backup/→ Image:{CI_REGISTRY_IMAGE}/mysql-backup:{VERSION} - Directory:
images/redis-cache/→ Image:{CI_REGISTRY_IMAGE}/redis-cache:{VERSION}
Workflow
Staging Workflow (release/* or hotfix/* branches)
- Version Validation:
check_testvalidates SemVer and sets`VERSION={RELEASE}.rc{CI_PIPELINE_IID}` - Build Images:
build_images_stagingbuilds all images inimages/directory - Tag & Push: Each image is tagged and pushed to registry
Production Workflow (MR → main)
- Version Validation:
check_prodvalidates SemVer and setsVERSION={RELEASE},TAG=v{VERSION} - Build Images:
build_images_productionbuilds all images inimages/directory - Tag & Push: Each image is tagged and pushed to registry
- Merge & Tag:
merge_and_tagmerges MR and creates Git tags (manual) - Release:
release_jobcreates GitLab release (automatic after merge_and_tag)
Prerequisites
- Images Directory: Project must have an
images/directory (or customIMAGES_ROOT) - Dockerfiles: Each image subdirectory must contain a
Dockerfile - Semantic Versioning: Branch names must follow
release/{version}orhotfix/{version}format - Container Registry: GitLab Container Registry must be enabled
- PRODUCTION_TARGET: Must be set to
'welance'for release jobs
Example Project Structure
.
├── images/
│ ├── mysql-backup/
│ │ ├── Dockerfile
│ │ └── backup.sh
│ ├── redis-cache/
│ │ ├── Dockerfile
│ │ └── cache-config.conf
│ └── nginx-proxy/
│ ├── Dockerfile
│ └── nginx.conf
├── .gitlab-ci.yml
└── CHANGELOG.md
Notes
- The pipeline builds all images in the
images/directory by default - Use
IMAGESvariable to build only specific images - Staging builds use release candidate versions (
`.rc{CI_PIPELINE_IID}`) - Production builds use exact version from branch name
- Release jobs only run when
PRODUCTION_TARGET == "welance" - The pipeline targets
mainbranch (notmaster) - Each image is built independently and can be deployed separately
- The pipeline validates semantic versioning before building
- Release jobs create GitLab releases with links to container images
- The
merge_and_tagjob creates realign branches for keeping develop in sync