Setting up CI/CD for website via GitLab CI/CD
GitLab CI/CD is one of the most functional built-in tools. Pipeline is described in .gitlab-ci.yml in repo root. GitLab.com provides shared runners; self-hosted runners on any server are possible.
Basic .gitlab-ci.yml structure
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
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 for execution
deploy_staging:
rules:
- if: $CI_COMMIT_BRANCH == "develop"
deploy_production:
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual # Manual approval for prod
Docker in Docker (DinD)
build_image:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
PHP/Laravel + PostgreSQL tests
test:
stage: test
image: php:8.3-cli
services:
- postgres:16
variables:
POSTGRES_DB: test_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secret
before_script:
- apt-get update && apt-get install -y libpq-dev
- docker-php-ext-install pdo_pgsql
- composer install
script:
- php artisan migrate --force
- php artisan test
Environments and Review Apps
deploy_review:
script:
- ./deploy-review.sh $CI_COMMIT_REF_SLUG
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.preview.mysite.com
rules:
- if: $CI_MERGE_REQUEST_ID
Setup time: 1-2 days for basic pipeline with SSH deploy.







