提升程式碼審查效率:使用 GitLab Review Apps 部署臨時環境
Supercharging Code Reviews: Deploying Ephemeral Environments with GitLab Review Apps
GitLab Review Apps 可為每個活躍 Merge Request 自動建立隔離的臨時環境,提供預覽連結供審查者測試,並在合併或關閉時清除。文章示範以 `.gitlab-ci.yml` 設定部署與清理工作,並用 `auto_stop_in: 1 week` 清理閒置的預覽環境。
DEV Community
0 Add reaction
0 Like
0 Unicorn
0 Exploding Head
0 Raised Hands
0 Fire
0 Jump to Comments 0 Save Boost
Pick as gem
Copy link
Copied to Clipboard
Share to XShare to LinkedInShare to FacebookShare to Mastodon
Pavan Kumar Sadashiv Posted on Oct 16
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 |
+-------------------------------------------------------------+
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/"
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"
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:
- A frontend engineer opens an MR altering a critical checkout modal.
- The pipeline triggers and deploys the preview in under 2 minutes.
- The Product Manager and QA lead click "View App" directly in the MR description.
- They test the checkout flow on mobile, tablet, and desktop without checking out the git branch locally or installing local npm packages.
- 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
- Eliminate Review Bottlenecks: Non-technical stakeholders (designers, PMs, QA) can test pull requests without needing Git or local developer environments.
- Zero Waste:
on_stopandauto_stop_inguarantee that dynamic preview infrastructure is deleted automatically. - Enterprise Confidence: Visual and functional verification happens before code ever touches the
mainbranch.
Resources & Links
- GitLab Profile: gitlab.com/hrlpavan
- GitLab Contributor Profile: contributors.gitlab.com/users/hrlpavan
- GitHub: @hrlpavan
How does your team handle preview environments for pull requests? Let's discuss in the comments below!
Tiger Data (Creators of TimescaleDB)Promoted
Agent Memory Is a Search Problem, Not a Storage Problem
Long-term conversational memory is the ability to recall and reason over months of past conversations. It is one of the hardest unsolved problems in AI assistants, and the field has converged on a shared assumption about how to solve it.
Read More
Top comments (0)
Subscribe

Personal Trusted UserCreate template Templates let you quickly answer FAQs or store snippets for re-use.
Submit PreviewDismiss
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink.
- [x] Hide child comments as well
Confirm
For further actions, you may consider blocking this person and/or reporting abuse
Tiger Data (Creators of TimescaleDB)Promoted
Fork, Break, Fix, Delete: Hands-On with Tiger MCP
A coding agent can read your codebase, run your tests, and open a pull request. Point it at your database and the calculus changes: a bad migration isn't something you undo with git, so most teams draw a line the agent isn't allowed to cross.
In this hands-on workshop, you'll wire Tiger MCP into the coding agent you already use and give it a database it's allowed to break.
Follow
Founder & MD, HRL International | AI Chief Architect & Tech Lead | C++/GPU Compute, DSA Optimization & Agentic Orchestration | 100x Production Engineering
- Location India,Mangalore
- Joined Oct 10, 2026
More from Pavan Kumar Sadashiv
Reusable Pipelines Done Right: Building Typed GitLab CI/CD Components for the CI/CD Catalog #gitlab#cicd#devops#opensourceMastering Monorepos in GitLab CI/CD: Dynamic Child Pipelines & Path-Based Triggers #gitlab#cicd#devops#architecture
👋 Kindness is contagious
Show your support for this compelling post and become part of the vibrant DEV Community. All levels of coders can share insights and build collective wisdom.
Even a brief “thank you” can brighten an author’s day. Drop your kudos below!
At DEV, sharing know-how paves the way and strengthens connections. If this article resonated with you, a quick note of thanks goes a long way.
Count me in!
DEV Community — A space to discuss and keep up software development and manage your software career
Built on Forem — the open source software that powers DEV and other inclusive communities.
Made with love and Ruby on Rails. DEV Community © 2016 - 2026.

We're a place where coders share, stay up-to-date and grow their careers.
來源:DEV Community · dev.to




Pavan Kumar Sadashiv