gitlab_ci 31 Q&As

Gitlab Ci FAQ & Answers

31 expert Gitlab Ci answers researched from official documentation. Every answer cites authoritative sources you can verify.

unknown

31 questions
A

GitLab CI/CD is built-in continuous integration and deployment platform integrated directly into GitLab (no separate CI tool needed). In GitLab 17.x, pipelines are defined in .gitlab-ci.yml (YAML) in repository root or using reusable CI/CD components from the CI/CD Catalog (GA in GitLab 17.0). Core workflow: commit → GitLab detects .gitlab-ci.yml → creates pipeline → runners execute jobs → artifacts/deployments. Components: jobs (executable tasks), stages (sequential groups), runners (execution agents with Docker/Kubernetes/Shell executors). GitLab 17 features: component-based configs (include: - component: gitlab.com/org/[email protected]), Auto DevOps with deployment strategies (continuous/canary/blue-green), built-in security scanning (SAST/DAST), Kubernetes integration. Free tier includes shared runners. Default stages: .pre, build, test, deploy, .post. GitLab 17.11+ improved runner management with job history tracking.

99% confidence
A

YAML file defines pipeline configuration in GitLab 17.x. Global keywords: stages (define workflow order), variables (CI/CD variables), include (import configs/components), workflow (pipeline-level rules). Modern GitLab 17 includes support components via include: - component: gitlab.com/org/[email protected] with parameterized inputs. Job structure: job_name: { stage: build, script: [commands], rules: [conditions], artifacts: {paths: [build/]}, cache: {paths: [node_modules/]} }. Example: build_job: stage: build, script: - npm install, - npm run build, artifacts: paths: [dist/], expire_in: 1 week. Jobs in same stage run parallel (up to runner concurrency), stages run sequentially. Default stages: .pre, build, test, deploy, .post. Validate with CI Lint tool (CI/CD > Editor > Validate) or API before commit. GitLab 17 supports multi-cache configurations (max 4 caches per job).

99% confidence
A

Job: unit of work in pipeline executed by GitLab Runner (build, test, deploy). Define: job_name: { script: [commands], stage: build, tags: [docker] }. In GitLab 17.x, jobs can bypass stage order using needs keyword to create DAG (Directed Acyclic Graph) pipelines. Stage: groups jobs, controls execution order. Default stages: .pre, build, test, deploy, .post. Jobs within same stage execute in parallel (limited by runner concurrency), subsequent stages wait for previous stage completion. Custom stages: stages: [compile, test, package, deploy]. Job assignment: stage: test. Hidden jobs (start with dot): reusable templates via extends. GitLab 17 optimization: use needs: [job1, job2] to start jobs immediately after dependencies complete (max 50 needs per job), reducing pipeline duration by 40-80% for complex workflows. Example: test: needs: [build], script: [npm test] runs as soon as build completes.

99% confidence
A

Artifacts: files stored on GitLab server after job execution for passing data between jobs. Define: artifacts: { paths: [build/, dist/], expire_in: 1 week, when: on_success }. In GitLab 17.x, artifacts upload after successful job completion by default. Subsequent jobs automatically download artifacts from previous stages, or specific jobs via dependencies: [job1] or needs: [job2] (needs automatically downloads artifacts). Features: automatic expiration (cleanup storage), reports (junit/cobertura/SAST), exclude patterns. When values: on_success (default), on_failure (debug logs), always (both). Access: job page UI, REST API, or dependencies keyword. Artifacts restore after caches during job setup. GitLab 17 best practice: set expire_in to minimize storage costs (default: 30 days configurable per instance). Example: test: dependencies: [build], script: [./run-tests] downloads only build job artifacts, not entire previous stage.

99% confidence
A

Cache: optimization for storing dependencies (node_modules, .m2, gems) shared between pipelines/jobs, restored before artifacts during job setup. GitLab 17 supports max 4 caches per job via cache: [{ key: gems, paths: [vendor/] }, { key: npm, paths: [node_modules/] }]. Cache policies: pull (download only), push (upload only), pull-push (default). Artifacts: job outputs (build/, dist/) stored on GitLab server, downloaded by subsequent jobs. Key differences: (1) Purpose: cache = speed optimization, artifacts = job output passing. (2) Scope: cache shared across pipelines, artifacts job-specific. (3) Restoration: caches restore first, then artifacts. (4) Storage: cache in runner/S3, artifacts on GitLab server. GitLab 17 best practice: use pull policy for read-only cache jobs (tests), pull-and-push-if-changed pattern for cache updates to reduce upload time. Example: test: cache: { key: deps, paths: [node_modules/], policy: pull }.

99% confidence
A

Rules: conditionally execute jobs using if (expressions), changes (file patterns), exists (file presence), variables (override job vars). In GitLab 17.x, rules replace deprecated only/except syntax with more powerful logic. Syntax: rules: - if: $CI_COMMIT_BRANCH == 'main', when: always. Multiple conditions support AND/OR logic: rules: - if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "merge_request_event"'. Common patterns: (1) MR-only: rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event'. (2) File changes: rules: - changes: [src/**/*.js], when: on_success. (3) Protected branches: rules: - if: $CI_COMMIT_REF_PROTECTED == 'true'. GitLab 17 enhancement: rules: exists for checking file presence before job execution. Example: deploy: rules: - if: '$CI_COMMIT_BRANCH == "main"', - if: '$CI_COMMIT_TAG =~ /^v[0-9]+/', when: manual. Best practice: combine workflow:rules (pipeline-level) with job rules for precise control.

99% confidence
A

When: controls job execution timing in GitLab 17.x pipelines. Values: on_success (default, runs after previous stage success), on_failure (runs after previous stage failure), manual (requires human click, shows orange play button), delayed (runs after start_in delay), always (runs regardless of previous status), never (skips job, workflow:rules only). Example: deploy: { stage: deploy, when: manual, allow_failure: false, script: [./deploy.sh] } creates blocking manual gate. Delayed example: notify: { when: delayed, start_in: 3 hours, script: [./notify.sh] } waits 3 hours. GitLab 17 use cases: (1) Production deploys: when: manual with protected environments. (2) Cleanup: when: always in after_script. (3) Failure alerts: when: on_failure. (4) Deployment gates: when: manual + allow_failure: false pauses pipeline. Manual jobs default to allow_failure: true (non-blocking); set allow_failure: false for approval workflows.

99% confidence
A

Variables: configuration values available in GitLab 17.x pipelines. Types: (1) Predefined (CI_COMMIT_SHA, CI_PROJECT_NAME, CI_PIPELINE_SOURCE). (2) Custom (Settings > CI/CD > Variables). (3) Group/instance variables (inherited). Define in YAML: variables: { DB_NAME: mydb, NODE_ENV: production }. Access: $VARIABLE or ${VARIABLE} in scripts. Variable attributes: Protected (only protected branches/tags), Masked (hide in logs with ***), File (write value to temp file path). GitLab 17.0+ supports ID tokens for OIDC authentication (id_tokens: VAULT_TOKEN: { aud: vault.example.com }). Precedence: job > global YAML > project > group > instance. Security best practice: protect + mask secrets, use file variables for certificates/keys. Example: deploy: variables: REGION: us-east-1, script: [aws deploy --region $REGION]. GitLab 17 enhancement: CI/CD variable expressions support regex matching in rules.

99% confidence
A

Runners: agents executing CI/CD jobs on various platforms. In GitLab 17.x, runner types: shared (all projects), group (group-level), project-specific (single project). Executors: Shell, Docker, Kubernetes, Docker Autoscale (new), Instance executor. GitLab 17.5+ deprecates Docker Machine executor (removed v20.0), use GitLab Runner Autoscaler instead. Registration changed in GitLab 17.0: registration tokens disabled, use runner authentication tokens. GitLab-hosted: shared runners on GitLab.com (free tier: 400 CI/CD minutes/month). Self-hosted: install GitLab Runner binary on infrastructure. Configuration: tags for job selection (tags: [docker, linux]), concurrent jobs (default: 1, configurable). Kubernetes executor creates new Pod per job (scalable, cloud-native). GitLab 17.11+ improved runner management UI with job history and assigned projects view. Example: test: tags: [docker], image: node:20. Use shared for quick start, self-hosted for custom environments/compliance.

99% confidence
A

Script: required keyword containing shell commands executed by GitLab Runner. Syntax: script: [command1, command2] or multi-line script: - | for complex commands. In GitLab 17.x, scripts execute in runner's shell (bash/sh/powershell). Job lifecycle: before_script → script → after_script. Important: after_script executes in new shell, cannot access script variables/state. Exit codes: non-zero (1-255) fails job immediately unless allow_failure: true. GitLab 17 best practice: keep scripts minimal, call repository scripts for maintainability (script: [./scripts/build.sh]). Multi-line example: script: - | npm ci --prefer-offline npm run build npm test. Variables available: $CI_COMMIT_SHA, $CI_PROJECT_DIR, etc. Security: scripts run with runner user permissions. Example: test: before_script: [apt-get update], script: [./run-tests.sh], after_script: [./cleanup.sh].

99% confidence
A

Needs: creates Directed Acyclic Graph (DAG) pipelines in GitLab 17.x by executing jobs out-of-order, bypassing stage sequencing. Syntax: needs: [build_job, lint_job]. Without needs: jobs wait for entire previous stage completion. With needs: job starts immediately after specified dependencies complete, reducing pipeline duration by 40-80% for complex workflows. Benefits: faster feedback, flexible dependencies (fan-in/fan-out/diamond patterns), parallel execution. Limitations: max 50 needs per job (GitLab enforced). Artifacts automatically downloaded from needed jobs. GitLab 17 optimization: visualize DAG in Pipeline Editor for debugging. Example: test: needs: [build], script: [npm test] runs as soon as build completes, not waiting for entire build stage. Use cases: multi-platform builds, microservices deployments, OS builds with complex dependency graphs. Performance: complex pipelines see 50%+ time reduction vs sequential stages.

99% confidence
A

Cache: preserves files between jobs for speed optimization in GitLab 17.x (supports max 4 caches per job). Configuration: cache: { paths: [node_modules/], key: ${CI_COMMIT_REF_SLUG} }. Caches restore before artifacts during job setup. Cache keys: static (key: deps) or dynamic (key: ${CI_COMMIT_REF_SLUG}-${CI_PIPELINE_ID}). Policies: pull (download only, for read-only jobs), push (upload only, initial cache creation), pull-push (default, update cache). Multiple caches (GitLab 13.10+): cache: [{ key: gems, paths: [vendor/] }, { key: npm, paths: [node_modules/] }]. GitLab 17 best practices: (1) Use pull policy for test/build jobs (test: cache: { key: deps, paths: [node_modules/], policy: pull }). (2) Tag runners for cache consistency (tag: [shared-cache]). (3) Implement pull-and-push-if-changed pattern (delete cache folder if unchanged to skip upload). (4) Store in S3/distributed cache for multi-runner setups. Performance: reduces npm install from 60s to 10s with proper caching.

99% confidence
A

Environment: deployment target tracking in GitLab 17.x (production, staging, review apps). Define: environment: { name: production, url: https://example.com, deployment_tier: production }. Features: deployment history tracking, one-click rollbacks, environment-specific variables, deployment approvals. Dynamic environments for review apps: environment: { name: review/$CI_COMMIT_REF_SLUG, url: https://$CI_COMMIT_REF_SLUG.example.com, on_stop: stop_review, auto_stop_in: 1 day }. Protected environments (Settings > CI/CD): restrict deployment to authorized users/groups. Stop action: cleanup job (on_stop: stop_review) with when: manual and action: stop. GitLab 17 Auto DevOps deployment strategies: continuous, canary (incremental rollout), blue-green. View in Operations > Environments with deployment timeline, metrics, logs. Example: deploy: { stage: deploy, environment: { name: staging, url: https://staging.example.com }, script: [./deploy.sh staging] }. Use for: deployment tracking, review apps per MR, rollback capability.

99% confidence
A

Include: imports external YAML configurations in GitLab 17.x for DRY pipelines. Methods: (1) include:local (same repo: /templates/.gitlab-ci.yml). (2) include:project (cross-project: project/path, file: .gitlab-ci.yml, ref: main). (3) include:remote (public URLs: https://example.com/ci.yml). (4) include:template (GitLab official: Security/SAST.gitlab-ci.yml). (5) include:component (CI/CD Catalog: gitlab.com/org/[email protected], inputs: {}). GitLab 17.0+ component support with parameterized inputs. Configuration merges: included configs deep-merge with .gitlab-ci.yml, job-level overrides win. Example: include: [{ local: /templates/docker.yml }, { component: gitlab.com/security/[email protected] }]. GitLab 17 best practices: use components for versioned organization standards, templates for quick GitLab features (SAST/DAST), local includes for repo-specific templates. Security: audit external includes, pin component versions to SHA/release. Use for: multi-project consistency, security scanning, deployment workflows.

99% confidence
A

Services: Docker containers running alongside job for integration testing in GitLab 17.x. Requires Docker/Kubernetes executor. Define: services: [mysql:8.0, redis:7]. Use cases: database testing (PostgreSQL/MySQL/MongoDB), cache testing (Redis/Memcached), browser automation (Selenium), Docker-in-Docker builds. Service access: hostname = service name or alias. Example: integration_test: { image: node:20, services: [{ name: postgres:15, alias: db }], variables: { POSTGRES_PASSWORD: test }, script: [psql -h db -U postgres] }. Docker-in-Docker: test: { image: docker:24, services: [docker:24-dind], script: [docker build -t app .] }. GitLab 17 best practices: (1) Use specific image versions (mysql:8.0, not mysql:latest). (2) Pass config via variables (POSTGRES_DB: testdb). (3) Set aliases for clarity (alias: database). (4) Use healthchecks for service readiness. Services start before before_script, accessible during script execution. Performance: services add 10-30s startup time to jobs.

99% confidence
A

Workflow: controls pipeline-level execution in GitLab 17.x using workflow:rules. Purpose: prevent duplicate pipelines, enforce pipeline conditions, auto-cancel redundant runs. Syntax: workflow: { rules: [{ if: $CI_PIPELINE_SOURCE == 'merge_request_event' }] }. Common pattern (prevent duplicates): workflow: rules: [{ if: '$CI_PIPELINE_SOURCE == "merge_request_event"' }, { if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS', when: never }, { if: $CI_COMMIT_BRANCH }]. This runs MR pipelines when MR exists, branch pipelines otherwise. GitLab 17 features: (1) workflow:auto_cancel: { on_new_commit: interruptible } cancels redundant pipelines. (2) workflow:name for dynamic names. Use cases: skip draft MRs (if: '$CI_MERGE_REQUEST_TITLE =~ /^Draft:/'), schedule-only pipelines, protected-branch-only. Default behavior: pipeline runs for every push. Best practice: define workflow:rules globally to prevent duplicate MR+branch pipelines, saving CI minutes.

99% confidence
A

GitLab 17.x secrets management: (1) CI/CD variables with masked + protected flags (Settings > CI/CD > Variables). (2) File variables for certificates/keys. (3) External secrets via OIDC: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault. Protected variables: accessible only on protected branches/tags. Masked variables: replaced with *** in job logs (regex validation required). File variables: value written to temp file, path in $VARIABLE. GitLab 17.0+ OIDC integration: id_tokens: { VAULT_TOKEN: { aud: vault.example.com } }, secrets: { DATABASE_PASSWORD: { vault: secret/data/production/db@password, token: $VAULT_TOKEN } }. Vault 1.17+ requires bound audiences for JWT auth. Best practices 2025: (1) Never hardcode secrets in .gitlab-ci.yml. (2) Use masked + protected for production secrets. (3) Rotate secrets regularly. (4) Use file variables for multi-line secrets (SSH keys, certs). (5) Prefer external secret managers for compliance. Example: deploy: script: [kubectl apply -f $KUBECONFIG_FILE] with KUBECONFIG_FILE as file variable.

99% confidence
A

Merge request (MR) pipelines run when MR is created/updated to test changes before merge. Configure with workflow: rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event'. Triggers: create MR, push to source branch, manual run. Runs on source branch only (ignores target). Prevent duplicates: workflow: rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event', - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS, when: never, - if: $CI_COMMIT_BRANCH. GitLab checks MR pipelines (not branch) when 'Pipelines must succeed' enabled. Use for: testing changes before merge, preview deployments, preventing broken main. Advanced: merge result pipelines, merge trains.

99% confidence
A

Templates: GitLab-maintained reusable YAML configurations for common CI/CD tasks. Include via: include: - template: Security/SAST.gitlab-ci.yml. GitLab 17.x official templates: (1) Security scanning (SAST, DAST, Secret Detection, Dependency Scanning, Container Scanning). (2) Auto-DevOps.gitlab-ci.yml (complete CI/CD pipeline). (3) Code-Quality.gitlab-ci.yml (linting/analysis). (4) Jobs/.gitlab-ci.yml (Build, Deploy, Test templates). Templates vs Components: templates are unversioned GitLab-maintained, components are versioned user/org-created (GitLab 17.0+). Custom templates: store in .gitlab-ci/.yml, include:local. Extends: inherit template jobs and override (my_job: { extends: .template_job, script: [custom] }). Hidden jobs (prefix with dot): use as templates. Example: include: - template: Security/SAST.gitlab-ci.yml enables SAST scanning. GitLab 17 recommendation: use official templates for quick start (security/Auto DevOps), migrate to components for customization/versioning. Find templates: GitLab repository lib/gitlab/ci/templates/.

99% confidence
A

Parallel: runs multiple job instances simultaneously in GitLab 17.x for distributed testing/builds. Syntax: parallel: 5 creates 5 identical job instances. Access instance info: CI_NODE_INDEX (1-5 index), CI_NODE_TOTAL (5 total). Matrix builds (GitLab 13.3+): parallel: { matrix: [{ PROVIDER: [aws, gcp], STACK: [eks, gke] }] } creates 4 jobs (aws/eks, aws/gke, gcp/eks, gcp/gke). Limitations: max 200 jobs per matrix (GitLab enforced). Use cases: (1) Test parallelization (split test suite: rspec --ci-node-index $CI_NODE_INDEX --ci-node-total $CI_NODE_TOTAL). (2) Multi-platform builds (OS: [linux, windows, macos]). (3) Multi-environment deployments. Performance: reduces test suite from 20min to 4min with parallel: 5 (80% faster). GitLab 17 best practice: combine with needs for DAG optimization. Example: test: { parallel: 3, script: [npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL] }. Note: consumes more CI minutes but increases productivity.

99% confidence
A

GitLab 17.x best practices for production pipelines: (1) Validate YAML: use CI Lint (CI/CD > Editor > Validate) before commit. (2) Configuration reuse: use components (include: - component: gitlab.com/org/[email protected]) for versioned configs, templates for quick starts. (3) Rules over only/except: rules: [{ if: $CI_PIPELINE_SOURCE == 'merge_request_event' }] for precise control. (4) Caching optimization: cache dependencies with pull policy for read-only jobs, max 4 caches per job. (5) DAG pipelines: use needs for 40-80% faster pipelines. (6) Security: masked + protected variables, OIDC for external secrets (Vault/AWS). (7) Maintainability: minimal scripts in YAML, call repo scripts (script: [./scripts/deploy.sh]). (8) DRY principle: use extends for job templates. (9) Prevent duplicates: workflow:rules to avoid MR+branch duplicate pipelines. (10) Manual production deploys: when: manual + allow_failure: false. (11) Review apps: dynamic environments per MR. (12) Runner tagging: consistent cache sharing. 2025 additions: pin component versions to SHA, use Auto DevOps deployment strategies (canary/blue-green), implement workflow:auto_cancel.

99% confidence
A

GitLab 17.x debugging methods: (1) CI Lint (CI/CD > Editor > Validate): validate YAML syntax, simulate pipeline. (2) Pipeline Editor: visual DAG preview, YAML validation. (3) Job logs: detailed execution logs with timestamps, exit codes. (4) CI_DEBUG_TRACE: enable verbose logging (set CI_DEBUG_TRACE=true variable, shows all commands, WARNING: may expose secrets). (5) Artifacts: save debug files (logs, core dumps) for inspection. (6) Local execution: gitlab-runner exec docker job_name (limited, deprecated GitLab 15.7+). (7) echo/set -x: add debug prints in scripts. GitLab 17 tools: Pipeline Graph shows job dependencies, Failed Jobs tab filters failures. Common issues: (1) YAML syntax errors → use CI Lint. (2) Missing artifacts → check dependencies/needs. (3) Cache misses → verify cache keys, runner tags. (4) Job not running → check rules/workflow:rules. (5) Runner unavailable → verify tags. Example debug job: debug: { script: [env, pwd, ls -la], when: on_failure, artifacts: { paths: [logs/], when: always } }. GitLab 17.11+ improved job logs with collapsible sections.

99% confidence
A

allow_failure: permits job failures without blocking pipeline in GitLab 17.x. Default: false (job failure fails pipeline), true for manual jobs (when: manual defaults to allow_failure: true). Syntax: allow_failure: true or allow_failure: { exit_codes: [137, 255] } for specific exit codes. Job execution: job runs and completes, but failure doesn't block downstream stages/jobs. UI: failed jobs with allow_failure show warning icon (⚠️), not error (❌). Use cases: (1) Experimental features (allow_failure: true). (2) Non-critical tests (code quality, performance). (3) Manual approval gates: set allow_failure: false for blocking manual jobs (when: manual, allow_failure: false pauses pipeline). (4) Flaky tests (temporary, fix root cause). (5) Exit code handling: allow_failure: { exit_codes: 137 } allows OOM failures. GitLab 17 best practice: use sparingly, don't abuse for masking real failures. Critical tests (security, unit tests) should always fail pipeline (allow_failure: false). Example: code_quality: { script: [./lint.sh], allow_failure: true } keeps pipeline green with warnings.

99% confidence
A

Components: reusable pipeline configurations with versioning, GA in GitLab 17.0, discoverable via CI/CD Catalog at gitlab.com/explore/catalog. Format: //@. Include syntax: include: - component: gitlab.com/my-org/[email protected]. GitLab 17 features: (1) Semantic versioning (v1.0.0, v1.1.0 tags). (2) Parameterized inputs (string/boolean/number/array types). (3) SHA256 integrity verification. (4) Catalog discovery. Example with inputs: include: - component: gitlab.com/components/[email protected], inputs: { environment: production, timeout: 300 }. Components use interpolation syntax: image: $[[ inputs.environment ]]-app:latest. Best practices 2025: pin to specific SHA/release (not ~latest), audit component source code for security, minimize dependencies. Component structure: dedicated project with spec.yml defining inputs/outputs. Use for: organization CI/CD standards, security scanning templates, deployment workflows.

99% confidence
A

GitLab 17 comparison of Components vs Templates: (1) Versioning: Components use SemVer (@1.0.0, @2.1.3) with immutable releases, Templates are unversioned GitLab-maintained files. (2) Source: Components from any GitLab project (gitlab.com/org/component), Templates from GitLab's official library. (3) Discoverability: Components in CI/CD Catalog (gitlab.com/explore/catalog), Templates in documentation only. (4) Inputs: Components support parameterized inputs (environment, region, timeout), Templates are static. (5) Security: Components support SHA256 integrity verification, Templates rely on GitLab trust. (6) Interpolation: Components use $[[ inputs.name ]], Templates none. Template syntax: include: - template: Security/SAST.gitlab-ci.yml (GitLab-maintained). Component syntax: include: - component: gitlab.com/security/[email protected], inputs: { severity: high } (custom/community). GitLab 17 recommendation: use Templates for quick start (Auto DevOps, security scans), Components for organization-specific production workflows with versioning.

99% confidence
A

Use when: manual with allow_failure: false to create blocking manual deployment gates. Configuration: deploy_prod: stage: deploy, environment: { name: production, url: https://prod.example.com }, when: manual, allow_failure: false, script: [./deploy.sh]. Setting allow_failure: false makes the job blocking, pausing the pipeline until an authorized user clicks the play button. Combine with protected environments (Settings > CI/CD > Protected Environments) to restrict who can approve deployments. Use for: production deployments requiring human approval, compliance requirements, critical releases. Manual jobs show orange play button in pipeline view.

99% confidence
A

Use dynamic environment names with $CI_COMMIT_REF_NAME for branch-based review apps. Configuration: review: stage: deploy, environment: { name: review/$CI_COMMIT_REF_NAME, url: https://$CI_COMMIT_REF_SLUG.review.example.com, on_stop: stop_review }, script: [./deploy-review.sh], rules: [{ if: '$CI_PIPELINE_SOURCE == "merge_request_event"' }]. Create stop action: stop_review: stage: deploy, environment: { name: review/$CI_COMMIT_REF_NAME, action: stop }, when: manual, script: [./cleanup-review.sh]. Each MR gets isolated environment. Review apps automatically appear in GitLab Environments page with deployment history and stop button.

99% confidence
A

Deploy to inactive environment (green), test, then switch traffic from active (blue). Configuration: deploy_green: stage: deploy, environment: { name: production-green }, script: [./deploy.sh green], when: manual. test_green: stage: test, dependencies: [deploy_green], script: [./smoke-test.sh green]. switch_traffic: stage: switch, environment: { name: production }, script: [./switch-traffic.sh blue green], when: manual, allow_failure: false. Requires infrastructure supporting dual environments and traffic switching (load balancer, DNS, or service mesh). Keep blue environment for instant rollback. GitLab shows both environments in Operations > Environments.

99% confidence
A

Use GitLab's incremental rollout feature for Kubernetes canary deployments. Configuration: deploy_canary: stage: deploy, environment: { name: production }, script: [./deploy.sh], resource_group: production. Enable in Settings > CI/CD > Auto DevOps > Deployment strategy: 'Timed incremental rollout'. Alternatively, manual percentage-based rollout: deploy_10: script: [./deploy.sh 10%], when: manual. deploy_50: script: [./deploy.sh 50%], when: manual. deploy_100: script: [./deploy.sh 100%], when: manual. Monitor metrics between stages. GitLab Auto DevOps uses 5-minute intervals by default (configure with AUTO_DEPLOY_WAIT_TIME variable). Requires Kubernetes with traffic splitting support.

99% confidence
A

GitLab Auto DevOps offers three deployment strategies (Settings > CI/CD > Auto DevOps > Deployment strategy): (1) Continuous deployment to production - Automatic deploy to production on main branch commits. (2) Timed incremental rollout - Gradual traffic shift with 5-minute intervals (configure with AUTO_DEPLOY_WAIT_TIME variable), sets INCREMENTAL_ROLLOUT_MODE: timed. (3) Automatic deployment to staging, manual to production - Sets STAGING_ENABLED: 1 and INCREMENTAL_ROLLOUT_MODE: manual. Auto DevOps requires base domain configured and Kubernetes cluster connected. Choose strategy before enabling Auto DevOps to avoid deployment failures.

99% confidence
A

GitLab 17.x anti-patterns causing slow/expensive/insecure pipelines: (1) No caching: rebuilds dependencies every run (use cache: { paths: [node_modules/], key: deps }). (2) Large artifacts without expiration: wastes storage (set expire_in: 1 week). (3) Complex inline scripts: unmaintainable (use script: [./scripts/build.sh] instead). (4) only/except syntax: deprecated in GitLab 17 (use rules instead). (5) Hardcoded secrets: security risk (use masked + protected variables). (6) No stage organization: unclear workflow (define logical stages). (7) Sequential stages only: slow (use needs for DAG, 40-80% faster). (8) Ignoring CI Lint: syntax errors in production. (9) Excessive parallel jobs: hits 200 job limit, wastes runners. (10) No workflow:rules: duplicate MR+branch pipelines waste CI minutes. (11) Using latest image tags: non-reproducible builds (pin to node:20.11). (12) Not using components: duplicated configs across projects. GitLab 17 best practices: cache dependencies, set artifact expiration, use DAG pipelines, implement workflow:rules, pin versions, audit with CI Lint. Performance: proper caching + needs reduces pipeline from 30min to 8min.

99% confidence