Print this page

Example of Full CI/CD pipeline for Joomla

17 October 2025

Полный GitLab CI/CD для проекта devopz.tech: от Shell до Kubernetes и ArgoCD

1. Подготовка среды GitLab Runner

Shell Executor (базовый уровень)

Первым делом поднимаем GitLab Runner на сервере (build или prod).


sudo apt update && sudo apt install -y gitlab-runner docker.io
sudo usermod -aG docker gitlab-runner
sudo visudo
# Добавляем:
gitlab-runner ALL=(ALL) NOPASSWD: ALL

Теперь регистрируем runner:


sudo gitlab-runner register
# Executor: shell
# Tags: build-shell, prod-shell

gitlab-runner list

2. Простейший shell-deploy: DEV → PROD

.gitlab-ci.yml (минимальный Shell Executor)


stages:
  - build
  - test
  - deploy
  - cleanup

variables:
  APP_DIR: "/var/www/devopz"
  MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
  MYSQL_DATABASE: jdb

build_dev:
  stage: build
  tags: [build-shell]
  only:
    - dev
  script:
    - echo "? Building dev site..."
    - sudo rm -rf $APP_DIR
    - sudo mkdir -p $APP_DIR
    - sudo cp -r * $APP_DIR
    - sudo chown -R www-data:www-data $APP_DIR
    - sudo mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" jdb < $APP_DIR/jdb.sql

test_dev:
  stage: test
  tags: [build-shell]
  only:
    - dev
  needs: [build_dev]
  script:
    - apt -y install httpie
    - http --check-status http://localhost || (echo "Dev DOWN"; exit 1)

deploy_prod:
  stage: deploy
  tags: [prod-shell]
  only:
    - main
  script:
    - echo "? Deploying prod site..."
    - sudo cp -r $APP_DIR /var/www/devopz.bckp
    - sudo rm -rf $APP_DIR
    - sudo mkdir -p $APP_DIR
    - sudo cp -r * $APP_DIR
    - sudo chown -R www-data:www-data $APP_DIR
    - sudo mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" jdb < $APP_DIR/jdb.sql

cleanup:
  stage: cleanup
  script:
    - echo "? Cleaning up runner workspace..."
    - sudo rm -rf /home/gitlab-runner/builds/*

Комментарий: Это основа, которую можно запускать без Docker — идеально подходит для первого CI/CD шага на VPS.


3. Docker Layer: контейнеризация Joomla + MySQL

Dockerfile:


FROM joomla:3.10.11-php7.4-apache
COPY . /var/www/html

docker-compose.yml:


version: "3.8"
services:
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: jdb
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - mysql-data:/var/lib/mysql

  joomla:
    build: .
    ports:
      - "8080:80"
    depends_on:
      - mysql
    environment:
      JOOMLA_DB_HOST: mysql
      JOOMLA_DB_NAME: jdb
      JOOMLA_DB_USER: ${MYSQL_USER}
      JOOMLA_DB_PASSWORD: ${MYSQL_PASSWORD}

volumes:
  mysql-data:

Pipeline с Docker:


stages:
  - build
  - test
  - deliver
  - cleanup

build_docker:
  stage: build
  image: docker:latest
  services: [docker:dind]
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE/joomla:${CI_COMMIT_SHORT_SHA} .
    - docker-compose up -d
    - sleep 60
    - curl -fsS http://localhost:8080 || (echo "DOWN"; exit 1)

deliver_docker:
  stage: deliver
  script:
    - docker push $CI_REGISTRY_IMAGE/joomla:${CI_COMMIT_SHORT_SHA}

cleanup:
  stage: cleanup
  script:
    - docker-compose down
    - docker image prune -f

4. Kubernetes + Helm + ArgoCD (GitOps-style)

Helm values.yaml:


joomla:
  image: registry.gitlab.com/devopz/joomla:latest
  service:
    type: ClusterIP
    port: 80

mysql:
  image: mysql:5.7
  persistence:
    enabled: true
    size: 5Gi

GitLab CI Job для деплоя:


deploy_k8s:
  stage: deploy
  image: bitnami/kubectl:latest
  before_script:
    - echo "$KUBECONFIG_CONTENT" | base64 -d > ~/.kube/config
  script:
    - helm upgrade --install devopz ./charts/devopz -n prod

Интеграция с ArgoCD:


notify_argocd:
  stage: notify
  script:
    - curl -X POST -H "Content-Type: application/json" \
      -d '{"ref": "main"}' https://argocd.devopz.tech/api/webhook

5. Secret Management через Vault


before_script:
  - export MYSQL_ROOT_PASSWORD=$(vault kv get -field=MYSQL_ROOT_PASSWORD secret/devopz)

envFrom:
  - secretRef:
      name: mysql-secrets

Сами секреты создаёт Vault Agent Injector в Kubernetes.


6. Автоматизация миграций БД


db_migrate:
  stage: migrate
  image: mysql:5.7
  script:
    - mysql -h mysql -u root -p"$MYSQL_ROOT_PASSWORD" jdb < migrations/update.sql

7. Blue-Green и Canary Deploy

Добавляем два Helm release: devopz-green и devopz-blue. ArgoCD рулит переключением трафика через аннотации Ingress:


nginx.ingress.kubernetes.io/service-upstream: "true"
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"

✅ Итого

  • Shell executor → базовый деплой
  • Docker → контейнеризация и изоляция
  • Kubernetes + Helm → оркестрация
  • Vault → безопасные секреты
  • ArgoCD → GitOps автодеплой
  • Blue/Green → без даунтайма

? Следующий шаг

Развернём полноценный CI/CD с GitLab → Vault → Helm → ArgoCD → Kubernetes.