Практический пример GitLab CI/CD для devopz.tech
Предпосылки
- Ветки:
main— продакшен.dev— разработка, staging.feature/*— новые фичи.
- Окружения:
staging→devветка.production→mainветка.
- Docker images: Joomla + MySQL кастомные образы для тестирования и деплоя.
- CI/CD шаги: Build → Test → Deliver → Deploy → Cleanup.
.gitlab-ci.yml
stages:
- build
- test
- deliver
- deploy
- cleanup
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
# --------------------------
# Build stage
# --------------------------
build-joomla-mysql:
stage: build
image: docker:20.10.16
services:
- docker:20.10.16-dind
only:
- dev
- feature/*
script:
# Login to GitLab Registry
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# Build MySQL and Joomla images
- docker build -t $CI_REGISTRY_IMAGE/mysql:5.7-${CI_PIPELINE_ID} -f docker/mysql57.Dockerfile .
- docker build -t $CI_REGISTRY_IMAGE/joomla:3.10-php7.4-${CI_PIPELINE_ID} -f docker/joomla310.Dockerfile .
# Push to registry
- docker push $CI_REGISTRY_IMAGE/mysql:5.7-${CI_PIPELINE_ID}
- docker push $CI_REGISTRY_IMAGE/joomla:3.10-php7.4-${CI_PIPELINE_ID}
# --------------------------
# Test stage (staging)
# --------------------------
test-staging:
stage: test
image: docker:20.10.16
services:
- docker:20.10.16-dind
only:
- dev
- feature/*
needs: [build-joomla-mysql]
script:
- docker network create devnet || true
- docker run -d --name mysql --network devnet -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD -e MYSQL_DATABASE=jdb $CI_REGISTRY_IMAGE/mysql:5.7-${CI_PIPELINE_ID}
- docker run -d --name joomla --network devnet -p 8081:80 -e JOOMLA_DB_HOST=mysql -e JOOMLA_DB_NAME=jdb -e JOOMLA_DB_USER=$JOOMLA_DB_USER -e JOOMLA_DB_PASSWORD=$JOOMLA_DB_PASSWORD $CI_REGISTRY_IMAGE/joomla:3.10-php7.4-${CI_PIPELINE_ID}
- sleep 60
# Basic healthcheck
- 'curl -fsS http://localhost:8081 || (echo "Site is DOWN"; exit 1)'
# --------------------------
# Deliver stage (staging push)
# --------------------------
deliver-staging:
stage: deliver
image: docker:20.10.16
only:
- dev
needs: [test-staging]
script:
- echo "Delivering staging images to registry"
- docker tag $CI_REGISTRY_IMAGE/joomla:3.10-php7.4-${CI_PIPELINE_ID} $CI_REGISTRY_IMAGE/joomla:staging
- docker tag $CI_REGISTRY_IMAGE/mysql:5.7-${CI_PIPELINE_ID} $CI_REGISTRY_IMAGE/mysql:staging
- docker push $CI_REGISTRY_IMAGE/joomla:staging
- docker push $CI_REGISTRY_IMAGE/mysql:staging
# --------------------------
# Deploy stage
# --------------------------
deploy-to-prod:
stage: deploy
image: bitnami/kubectl:latest
only:
- main
script:
# Decode kubeconfig
- echo "$KUBERNETES_KUBE_CONFIG" | base64 -d > ~/.kube/config
# Deploy MySQL and Joomla
- kubectl apply -f k8s/mysql-pvc.yaml
- kubectl apply -f k8s/joomla-pvc.yaml
- kubectl apply -f k8s/mysql-deployment.yaml
- kubectl apply -f k8s/joomla-deployment.yaml
- kubectl apply -f k8s/mysql-secret.yaml
- kubectl apply -f k8s/joomla-secret.yaml
- kubectl rollout status deployment/joomla
# --------------------------
# Cleanup stage
# --------------------------
cleanup:
stage: cleanup
image: docker:20.10.16
script:
- docker system prune -af
- docker network prune -f
when: always
Что здесь происходит
- Build: билдим кастомные образы Joomla и MySQL, пушим в GitLab Registry.
- Test: разворачиваем их в staging (локальный Docker network), делаем базовый healthcheck.
- Deliver: создаём staging-теги и пушим их в реестр.
- Deploy: при мерже в
mainдеплоим на Kubernetes с использованием PVC и Secrets. - Cleanup: чистим Docker, чтобы Runner не забивал диск.
Плюсы такой схемы
- Чёткое разделение веток (
dev→ staging,main→ prod). - Авто-тестирование перед деплоем.
- Docker images и Kubernetes deploy интегрированы.
- CI/CD полностью автоматизированный, минимальное вмешательство человека.
Если хочешь, можно добавить блоки про feature flags, Blue-Green/Canary деплой и ArgoCD — будет уже enterprise-уровень CI/CD.
