Topic 4.3
Environments & Deployment Jobs
In one line
GitLab's environment: keyword tracks exactly what's deployed where, and manual jobs give a human-triggered deployment gate — the same production-safety concept from Phase 2.2, expressed through GitLab's own mechanism.
Key ideas
- 01
GitLab's
environment:key on a job (environment: production) tracks that job as a DEPLOYMENT to a named environment — GitLab's own UI then shows, per environment, exactly which pipeline (and which commit) is CURRENTLY deployed there, directly answering 'what's actually running in production right now' without needing to check anywhere else. - 02
This environment tracking directly enables GitLab's own DEPLOYMENT HISTORY and ROLLBACK features — GitLab can show a genuine timeline of every deployment to a given environment, and (for supported deployment methods) offers a one-click 'Rollback' action re-running an OLDER deployment job — conceptually the same safety net as Kubernetes'
kubectl rollout undoor Helm'shelm rollback, expressed at the pipeline level instead. - 03
when: manualon a job makes it require an explicit human click in GitLab's UI to actually start — directly the same required-approval concept as GitHub Actions' Environment protection rules (Phase 2.2), just GitLab's own specific keyword for the identical underlying need: a deliberate, human-gated action for something genuinely consequential like a production deployment. - 04
A genuinely common real pattern combines both: a job with
environment: productionANDwhen: manual— GitLab tracks it as a real production deployment for its own history/rollback purposes, while ALSO requiring a human to explicitly trigger it, rather than it running automatically the moment the pipeline reaches that stage. - 05
environment: { name: review/$CI_COMMIT_REF_SLUG, url: https://$CI_COMMIT_REF_SLUG.example.com }creates a DYNAMIC, per-branch REVIEW APP — a genuinely temporary, fully deployed environment specific to one feature branch or merge request, letting a reviewer click a real, live link and interact with the actual proposed change running live, rather than reviewing code changes in the abstract alone. - 06
Review apps are commonly configured to be automatically TORN DOWN once their associated merge request is closed or merged (a
stop_reviewjob, triggeredon_stop) — genuinely important cleanup, since leaving every feature branch's own temporary environment running indefinitely would waste real infrastructure and cost over time.
Code & diagrams
Tracked as a real deployment, but requiring an explicit human click — the same idea as GitHub's environment approvals.
A gated production deployment, plus a dynamic, self-cleaning review app per merge request.
deploy-production:
stage: deploy
environment: production
when: manual # requires an explicit human click to run
script:
- ./deploy.sh production
review-app:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.example.com
on_stop: stop-review-app
script:
- ./deploy.sh review-$CI_COMMIT_REF_SLUG
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
stop-review-app:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
script:
- ./teardown.sh review-$CI_COMMIT_REF_SLUG
when: manual
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'Explain it without notes
What real, practical question does GitLab's environment tracking let a team answer immediately, without checking anywhere else?
Why would a review app that's automatically deployed per merge request also need an automatic (or at least easy, one-click) teardown mechanism?
Practice
If you have access to a real GitLab project, add environment: production and when: manual to a deployment job, and confirm it appears as a distinct manual action needing a click in GitLab's pipeline UI.
Sketch, in plain English, what triggers should control a review app's creation versus its teardown for a hypothetical project, and why those specific triggers make sense.
Trade-offs
- ↔
Review apps give reviewers a genuinely powerful, concrete way to interact with a proposed change directly rather than just reading its diff — but they add real infrastructure cost and complexity (every open merge request now potentially has its own live, running deployment) that's only worth it for changes where actually clicking around a live environment provides genuinely more insight than code review alone; a small, obviously-correct change may not need this level of review infrastructure at all.
Done when you can
I can use environment: to track a job as a deployment GitLab shows in its own deployment history.
I can use when: manual to require explicit human approval for a job like a production deployment.
I understand what a dynamic review app is and why it needs an automatic or easy teardown mechanism.