Skip to content
Back to Deployment

GitLab CI/CD

GitLab-native CI/CD with .gitlab-ci.yml, runners, and environments.

CI/CDIntermediate

Why

GitLab CI is built into GitLab with .gitlab-ci.yml, auto-devops, and container registry. Runners can be shared or self-hosted, with autoscaling.

When

Use GitLab CI for projects on GitLab. Avoid if not on GitLab (no benefit over GitHub Actions).

How

1. Config — .gitlab-ci.yml in repo root 2. Stages — build, test, deploy 3. Runner — shared or self-hosted, tags 4. Variables — CI/CD settings or .gitlab-ci.yml 5. Cache — cache key for deps 6. Artifacts — pass between jobs 7. Environments — deploy to staging/prod

Example

# .gitlab-ci.yml stages: [build, test, deploy] build: stage: build image: node:20 script: [npm ci, npm run build] artifacts: { paths: [dist] } test: stage: test image: node:20 script: [npm ci, npm test] cache: { key: npm, paths: [node_modules] } deploy:prod: stage: deploy image: node:20 script: [npx vercel --prod --token $VERCEL_TOKEN] environment: { name: production, url: https://app.com } only: { refs: [main] } variables: { VERCEL_TOKEN: $VERCEL_TOKEN }

Common Problems

  • ⚠No runner — no shared runner or self-hosted not registered, check settings
  • ⚠Job not running — only/except rules, check branch and conditions
  • ⚠Configuration drift between environments — use infrastructure-as-code (Terraform/Pulumi) to keep dev/staging/prod identical

Best Practices

  • ✓Use cache for deps — speed up jobs, cache key by lockfile hash
  • ✓Use environments for deploys — track deployments, rollback from UI
  • ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit

FAQ