OpsCanary
cicdgitlab ciPractitioner

Mastering Environments in GitLab CI/CD: Static vs. Dynamic

5 min read GitLab DocsAug 2, 2026Reviewed for accuracy
Share
PractitionerHands-on experience recommended

Environments in GitLab CI/CD are essential for managing different configurations and deploying code throughout your software lifecycle. They allow you to create isolated spaces for testing, staging, and production, which helps in maintaining stability and reliability in your deployments. By utilizing static environments like 'staging' and 'production', you can ensure that your deployments are consistent and repeatable. On the other hand, dynamic environments are created on-the-fly during a CI/CD pipeline and are typically used for single deployments, which is particularly useful for review apps.

Each environment can have one of three states: available, stopping, or stopped, depending on whether its stop job has run. This state management is crucial for understanding the lifecycle of your deployments. You can define deployment tiers such as development, testing, staging, and production, allowing you to categorize your environments effectively. For instance, a static environment can be defined in your CI/CD configuration as follows:

chroma
deply_staging:stage:deployscript:-echo "Deploy to staging server"environment:name:stagingurl:https://staging.example.com

In production, it’s vital to be aware of certain gotchas. For example, the stop_review job does not generate a dotenv report artifact, which means it won't recognize the DYNAMIC_ENVIRONMENT_URL environment variable. Additionally, if the environment URL is malformed, the system won't update it. Always ensure your scripts are accessible to the CI runners, especially when dealing with feature branches that may be deleted.

Key takeaways

  • Utilize static environments for consistent deployments across staging and production.
  • Leverage dynamic environments for temporary review apps that are created and destroyed per deployment.
  • Monitor environment states (available, stopping, stopped) to manage deployment lifecycles effectively.
  • Be cautious with the `stop_review` job as it doesn't recognize certain environment variables.
  • Ensure valid environment URLs to prevent deployment issues.

Why it matters

In production, managing environments effectively can significantly reduce deployment failures and improve the speed of your release cycles. Properly configured environments lead to smoother transitions from development to production.

Code examples

chroma
deploy_staging:stage:deployscript:-echo "Deploy to staging server"environment:name:stagingurl:https://staging.example.com
chroma
deploy_review_app:stage:deployscript:make deployenvironment:name:review/$CI_COMMIT_REF_SLUGurl:https://$CI_ENVIRONMENT_SLUG.example.comrules:-if:$CI_COMMIT_BRANCH == "main"when:never-if:$CI_COMMIT_BRANCH
chroma
review:script:-DYNAMIC_ENVIRONMENT_URL=$(deploy-script)# In script, get the environment URL.-echo "DYNAMIC_ENVIRONMENT_URL=$DYNAMIC_ENVIRONMENT_URL" >> deploy.env# Add the value to a dotenv file.artifacts:reports:dotenv:deploy.env# Report back dotenv file to rails.environment:name:review/$CI_COMMIT_REF_SLUGurl:$DYNAMIC_ENVIRONMENT_URL# and set the variable produced in script to `environment:url`on_stop:stop_reviewstop_review:script:-./teardown-environmentwhen:manualenvironment:name:review/$CI_COMMIT_REF_SLUGaction:stop

When NOT to use this

The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →
RailwaySponsor

Deploy any app in seconds — no infrastructure config, no DevOps overhead. Instant deployments from GitHub, built-in databases, and automatic scaling.

Start deploying free →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.