Настройка CI/CD для сайта через GitLab CI/CD
GitLab CI/CD — один из наиболее функциональных встроенных инструментов. Pipeline описывается в .gitlab-ci.yml в корне репозитория. GitLab.com предоставляет shared runners; для on-premise можно поднять собственные раннеры на любом сервере.
Базовая структура .gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
NODE_VERSION: "20"
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
test:
stage: test
image: node:20-alpine
script:
- npm ci
- npm run lint
- npm test
build:
stage: build
image: node:20-alpine
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
deploy_production:
stage: deploy
image: alpine:3.19
before_script:
- apk add --no-cache openssh-client rsync
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
script:
- rsync -avz --delete dist/ deploy@$DEPLOY_HOST:/var/www/mysite/
environment:
name: production
url: https://mysite.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
Правила запуска (rules)
rules — более гибкая замена устаревшему only/except:
deploy_staging:
rules:
- if: $CI_COMMIT_BRANCH == "develop"
when: on_success
- when: never
deploy_production:
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual # ручное одобрение для prod
Деплой на staging — автоматически при пуше в develop. Деплой на prod — только по тегу вида v1.2.3 и только после ручного нажатия кнопки в интерфейсе.
Переменные окружения
Настраиваются в Settings → CI/CD → Variables. Типы:
- Variable — обычная переменная, маскируется в логах если включено
- File — содержимое записывается во временный файл, путь передаётся в переменную
# Использование файловой переменной для .env
script:
- cp $ENV_FILE .env
- npm run build
Для группы проектов переменные задаются на уровне группы — удобно для общих ключей (AWS, Telegram, Registry credentials).
Docker in Docker (DinD)
Сборка образов внутри pipeline:
build_image:
stage: build
image: docker:24
services:
- docker:24-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
$CI_REGISTRY, $CI_REGISTRY_USER, $CI_REGISTRY_PASSWORD — предопределённые переменные GitLab. Container Registry включён в каждый проект.
PHP/Laravel + PostgreSQL в тестах
test:
stage: test
image: php:8.3-cli
services:
- postgres:16
variables:
POSTGRES_DB: test_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secret
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_DATABASE: test_db
DB_USERNAME: postgres
DB_PASSWORD: secret
before_script:
- apt-get update && apt-get install -y libpq-dev
- docker-php-ext-install pdo_pgsql
- composer install --no-interaction
- cp .env.testing .env
- php artisan key:generate
- php artisan migrate --force
script:
- php artisan test --parallel
Сервис postgres:16 поднимается как sidecar-контейнер, доступен по хостнейму postgres внутри джоба.
Environments и Review Apps
GitLab умеет создавать динамические окружения под каждый merge request:
deploy_review:
stage: deploy
script:
- ./deploy-review.sh $CI_COMMIT_REF_SLUG
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.preview.mysite.com
on_stop: stop_review
rules:
- if: $CI_MERGE_REQUEST_ID
stop_review:
stage: deploy
script:
- ./teardown-review.sh $CI_COMMIT_REF_SLUG
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
rules:
- if: $CI_MERGE_REQUEST_ID
when: manual
Каждый MR получает отдельный URL для проверки. При закрытии MR — окружение сносится.
Self-hosted Runner
На своём сервере:
# Установка раннера
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | bash
apt-get install gitlab-runner
# Регистрация
gitlab-runner register \
--url https://gitlab.com \
--registration-token <TOKEN> \
--executor docker \
--docker-image alpine:latest
Self-hosted раннер — нет лимитов на минуты, можно использовать более мощное железо, кеш не сбрасывается между прогонами.
Сроки настройки
Базовый .gitlab-ci.yml с тестами и SSH-деплоем — 1–2 дня. Полная конфигурация с несколькими окружениями, Docker registry, review apps, ручными одобрениями — 4–6 дней, включая настройку раннеров и отладку.







