DEV Community

Pavan Kumar Sadashiv
Pavan Kumar Sadashiv

Posted on

Supercharging Code Reviews: Deploying Ephemeral Environments with GitLab Review Apps

Supercharging Code Reviews: Deploying Ephemeral Environments with GitLab Review Apps

How many times has your engineering team seen a pull request with 100% passing unit tests, only to merge it and realize the frontend styling is broken or an API endpoint returns unexpected HTML?

Static code reviews on GitHub or GitLab only tell half the story. To truly validate user interfaces, cross-browser compatibility, and integrated workflows, reviewers need to interact with a live, working instance of the code.

Enter GitLab Review Apps.

Review Apps is one of GitLab CI/CD’s most powerful features. It automatically provisions a temporary, isolated ephemeral environment for every active Merge Request, provides reviewers with a direct clickable preview URL in the MR widget, and automatically tears down the environment when the branch is merged or closed.

In this practical guide, I will show you how to configure GitLab Review Apps from scratch using standard container or cloud hosting providers.


1. How GitLab Review Apps Work

+-------------------------------------------------------------+
|               Developer opens Merge Request                 |
|             (Branch: feat/redesign-nav-header)              |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|                   GitLab CI/CD Pipeline                     |
|           - Builds container / static assets                |
|           - Deploys to dynamic subdomain:                   |
|             https://mr-42-feat-redesign.preview.domain.com  |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|               Merge Request Discussion Widget               |
|      "View App" button appears directly on the MR!          |
|      Reviewers, PMs, and QA test the live preview           |
+-------------------------------------------------------------+
                              |
                              v (MR Merged / Closed)
+-------------------------------------------------------------+
|                   Automatic Teardown Job                    |
|        - Destroys preview container / frees resources       |
+-------------------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

2. Configuring Review Apps in .gitlab-ci.yml

To activate Review Apps, define a deployment job that uses GitLab’s environment keyword with dynamic naming:

stages:
  - test
  - build
  - review
  - cleanup

build_preview:
  stage: build
  image: node:20-alpine
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 day
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

deploy_review:
  stage: review
  image: alpine/curl:latest
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: https://$CI_ENVIRONMENT_SLUG.preview.mycompany.com
    on_stop: stop_review
    auto_stop_in: 1 week
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - echo "Deploying preview for $CI_COMMIT_REF_SLUG to $CI_ENVIRONMENT_URL..."
    # Example deployment script (Docker / Kubernetes / S3 / Cloudflare Pages / Vercel)
    - ./scripts/deploy-preview.sh --branch "$CI_COMMIT_REF_SLUG" --dist "dist/"
Enter fullscreen mode Exit fullscreen mode

Breaking Down the Environment Block:

  • name: review/$CI_COMMIT_REF_SLUG: Creates a uniquely scoped environment in GitLab for each branch.
  • url: https://$CI_ENVIRONMENT_SLUG.preview.mycompany.com: Tells GitLab where the preview app lives. GitLab automatically renders a clickable "View App" button directly in the Merge Request UI!
  • on_stop: stop_review: Points to the teardown job that runs when the MR is closed or merged.
  • auto_stop_in: 1 week: Safety guardrail to automatically garbage-collect stale review apps if an MR is abandoned.

3. Configuring the Automatic Teardown Job

To prevent cloud infrastructure waste, every Review App setup must include a corresponding teardown job:

stop_review:
  stage: cleanup
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    action: stop
  variables:
    GIT_STRATEGY: none # Don't need to clone repo to delete environment
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual # Allows manual stopping or triggers automatically on merge
  script:
    - echo "Tearing down ephemeral environment for $CI_COMMIT_REF_SLUG..."
    - ./scripts/destroy-preview.sh --branch "$CI_COMMIT_REF_SLUG"
Enter fullscreen mode Exit fullscreen mode

When you click Merge in GitLab, GitLab automatically fires stop_review in the background, deleting the preview container or bucket with zero manual cleanup required.


4. The Reviewer Experience

Once configured, the developer and reviewer workflow improves dramatically:

  1. A frontend engineer opens an MR altering a critical checkout modal.
  2. The pipeline triggers and deploys the preview in under 2 minutes.
  3. The Product Manager and QA lead click "View App" directly in the MR description.
  4. They test the checkout flow on mobile, tablet, and desktop without checking out the git branch locally or installing local npm packages.
  5. They approve the MR with complete confidence.

5. Deployment Options for Every Tech Stack

Review Apps work across any deployment target:

Target How It Deploys Best For
Kubernetes / OpenShift Helm chart deploying a dedicated namespace per MR. Complex microservices & full-stack apps.
Docker Compose Dynamic container spins up on a dedicated preview VM with Traefik routing. Monoliths & small teams.
Cloudflare Pages / Vercel Git commit triggers automated preview URL. Static sites & JAMstack / Next.js.
AWS S3 + CloudFront Upload to s3://previews/$CI_COMMIT_REF_SLUG/ with Route53 routing. Single Page Applications (SPAs).

6. Key Takeaways

  1. Eliminate Review Bottlenecks: Non-technical stakeholders (designers, PMs, QA) can test pull requests without needing Git or local developer environments.
  2. Zero Waste: on_stop and auto_stop_in guarantee that dynamic preview infrastructure is deleted automatically.
  3. Enterprise Confidence: Visual and functional verification happens before code ever touches the main branch.

Resources & Links

How does your team handle preview environments for pull requests? Let's discuss in the comments below!

Top comments (0)