diff options
Diffstat (limited to 'doc/ci/environments/index.md')
-rw-r--r-- | doc/ci/environments/index.md | 991 |
1 files changed, 991 insertions, 0 deletions
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md new file mode 100644 index 00000000000..b6ec30b5571 --- /dev/null +++ b/doc/ci/environments/index.md @@ -0,0 +1,991 @@ +--- +stage: Release +group: Release Management +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers +type: reference +disqus_identifier: 'https://docs.gitlab.com/ee/ci/environments.html' +--- + +# Environments and deployments + +> Introduced in GitLab 8.9. + +Environments allow control of the continuous deployment of your software, +all within GitLab. + +## Introduction + +There are many stages required in the software development process before the software is ready +for public consumption. + +For example: + +1. Develop your code. +1. Test your code. +1. Deploy your code into a testing or staging environment before you release it to the public. + +This helps find bugs in your software, and also in the deployment process as well. + +GitLab CI/CD is capable of not only testing or building your projects, but also +deploying them in your infrastructure, with the added benefit of giving you a +way to track your deployments. In other words, you will always know what is +currently being deployed or has been deployed on your servers. + +It's important to know that: + +- Environments are like tags for your CI jobs, describing where code gets deployed. +- Deployments are created when [jobs](../yaml/README.md#introduction) deploy versions of code to environments, + so every environment can have one or more deployments. + +GitLab: + +- Provides a full history of your deployments for each environment. +- Keeps track of your deployments, so you always know what is currently being deployed on your + servers. + +If you have a deployment service such as [Kubernetes](../../user/project/clusters/index.md) +associated with your project, you can use it to assist with your deployments, and +can even access a [web terminal](#web-terminals) for your environment from within GitLab! + +## Configuring environments + +Configuring environments involves: + +1. Understanding how [pipelines](../pipelines/index.md) work. +1. Defining environments in your project's [`.gitlab-ci.yml`](../yaml/README.md) file. +1. Creating a job configured to deploy your application. For example, a deploy job configured with [`environment`](../yaml/README.md#environment) to deploy your application to a [Kubernetes cluster](../../user/project/clusters/index.md). + +The rest of this section illustrates how to configure environments and deployments using +an example scenario. It assumes you have already: + +- Created a [project](../../gitlab-basics/create-project.md) in GitLab. +- Set up [a Runner](../runners/README.md). + +In the scenario: + +- We are developing an application. +- We want to run tests and build our app on all branches. +- Our default branch is `master`. +- We deploy the app only when a pipeline on `master` branch is run. + +### Defining environments + +Let's consider the following `.gitlab-ci.yml` example: + +```yaml +stages: + - test + - build + - deploy + +test: + stage: test + script: echo "Running tests" + +build: + stage: build + script: echo "Building the app" + +deploy_staging: + stage: deploy + script: + - echo "Deploy to staging server" + environment: + name: staging + url: https://staging.example.com + only: + - master +``` + +We have defined three [stages](../yaml/README.md#stages): + +- `test` +- `build` +- `deploy` + +The jobs assigned to these stages will run in this order. If any job fails, then +the pipeline fails and jobs that are assigned to the next stage won't run. + +In our case: + +- The `test` job will run first. +- Then the `build` job. +- Lastly the `deploy_staging` job. + +With this configuration, we: + +- Check that the tests pass. +- Ensure that our app is able to be built successfully. +- Lastly we deploy to the staging server. + +NOTE: **Note:** +The `environment` keyword defines where the app is deployed. +The environment `name` and `url` is exposed in various places +within GitLab. Each time a job that has an environment specified +succeeds, a deployment is recorded, along with the Git SHA, and environment name. + +CAUTION: **Caution**: +Some characters are not allowed in environment names. Use only letters, +numbers, spaces, and `-`, `_`, `/`, `{`, `}`, or `.`. Also, it must not start nor end with `/`. + +In summary, with the above `.gitlab-ci.yml` we have achieved the following: + +- All branches will run the `test` and `build` jobs. +- The `deploy_staging` job will run [only](../yaml/README.md#onlyexcept-basic) on the `master` + branch, which means all merge requests that are created from branches don't + get deployed to the staging server. +- When a merge request is merged, all jobs will run and the `deploy_staging` + job will deploy our code to a staging server while the deployment + will be recorded in an environment named `staging`. + +#### Environment variables and Runner + +Starting with GitLab 8.15, the environment name is exposed to the Runner in +two forms: + +- `$CI_ENVIRONMENT_NAME`. The name given in `.gitlab-ci.yml` (with any variables + expanded). +- `$CI_ENVIRONMENT_SLUG`. A "cleaned-up" version of the name, suitable for use in URLs, + DNS, etc. + +If you change the name of an existing environment, the: + +- `$CI_ENVIRONMENT_NAME` variable will be updated with the new environment name. +- `$CI_ENVIRONMENT_SLUG` variable will remain unchanged to prevent unintended side + effects. + +Starting with GitLab 9.3, the environment URL is exposed to the Runner via +`$CI_ENVIRONMENT_URL`. The URL is expanded from either: + +- `.gitlab-ci.yml`. +- The external URL from the environment if not defined in `.gitlab-ci.yml`. + +#### Set dynamic environment URLs after a job finishes + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/17066) in GitLab 12.9. + +In a job script, you can specify a static [environment URL](#using-the-environment-url). +However, there may be times when you want a dynamic URL. For example, +if you deploy a Review App to an external hosting +service that generates a random URL per deployment, like `https://94dd65b.amazonaws.com/qa-lambda-1234567`, +you don't know the URL before the deployment script finishes. +If you want to use the environment URL in GitLab, you would have to update it manually. + +To address this problem, you can configure a deployment job to report back a set of +variables, including the URL that was dynamically-generated by the external service. +GitLab supports [dotenv](https://github.com/bkeepers/dotenv) file as the format, +and expands the `environment:url` value with variables defined in the dotenv file. + +To use this feature, specify the +[`artifacts:reports:dotenv`](../pipelines/job_artifacts.md#artifactsreportsdotenv) keyword in `.gitlab-ci.yml`. + +<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> +For an overview, see [Set dynamic URLs after a job finished](https://youtu.be/70jDXtOf4Ig). + +##### Example of setting dynamic environment URLs + +The following example shows a Review App that creates a new environment +per merge request. The `review` job is triggered by every push, and +creates or updates an environment named `review/your-branch-name`. +The environment URL is set to `$DYNAMIC_ENVIRONMENT_URL`: + +```yaml +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_SLUG + url: $DYNAMIC_ENVIRONMENT_URL # and set the variable produced in script to `environment:url` + on_stop: stop_review + +stop_review: + script: + - ./teardown-environment + when: manual + environment: + name: review/$CI_COMMIT_REF_SLUG + action: stop +``` + +As soon as the `review` job finishes, GitLab updates the `review/your-branch-name` +environment's URL. +It parses the report artifact `deploy.env`, registers a list of variables as runtime-created, +uses it for expanding `environment:url: $DYNAMIC_ENVIRONMENT_URL` and sets it to the environment URL. +You can also specify a static part of the URL at `environment:url:`, such as +`https://$DYNAMIC_ENVIRONMENT_URL`. If the value of `DYNAMIC_ENVIRONMENT_URL` is +`123.awesome.com`, the final result will be `https://123.awesome.com`. + +The assigned URL for the `review/your-branch-name` environment is visible in the UI. +[See where the environment URL is displayed](#using-the-environment-url). + +> **Notes:** +> +> - `stop_review` doesn't generate a dotenv report artifact, so it won't recognize the `DYNAMIC_ENVIRONMENT_URL` variable. Therefore you should not set `environment:url:` in the `stop_review` job. +> - If the environment URL is not valid (for example, the URL is malformed), the system doesn't update the environment URL. + +### Configuring manual deployments + +Adding `when: manual` to an automatically executed job's configuration converts it to +a job requiring manual action. + +To expand on the [previous example](#defining-environments), the following includes +another job that deploys our app to a production server and is +tracked by a `production` environment. + +The `.gitlab-ci.yml` file for this is as follows: + +```yaml +stages: + - test + - build + - deploy + +test: + stage: test + script: echo "Running tests" + +build: + stage: build + script: echo "Building the app" + +deploy_staging: + stage: deploy + script: + - echo "Deploy to staging server" + environment: + name: staging + url: https://staging.example.com + only: + - master + +deploy_prod: + stage: deploy + script: + - echo "Deploy to production server" + environment: + name: production + url: https://example.com + when: manual + only: + - master +``` + +The `when: manual` action: + +- Exposes a "play" button in GitLab's UI for that job. +- Means the `deploy_prod` job will only be triggered when the "play" button is clicked. + +You can find the "play" button in the pipelines, environments, deployments, and jobs views. + +| View | Screenshot | +|:----------------|:-------------------------------------------------------------------------------| +| Pipelines | ![Pipelines manual action](../img/environments_manual_action_pipelines.png) | +| Single pipeline | ![Pipelines manual action](../img/environments_manual_action_single_pipeline.png) | +| Environments | ![Environments manual action](../img/environments_manual_action_environments.png) | +| Deployments | ![Deployments manual action](../img/environments_manual_action_deployments.png) | +| Jobs | ![Builds manual action](../img/environments_manual_action_jobs.png) | + +Clicking on the play button in any view will trigger the `deploy_prod` job, and the +deployment will be recorded as a new environment named `production`. + +NOTE: **Note:** +If your environment's name is `production` (all lowercase), +it will get recorded in [Value Stream Analytics](../../user/project/cycle_analytics.md). + +### Configuring dynamic environments + +Regular environments are good when deploying to "stable" environments like staging or production. + +However, for environments for branches other than `master`, dynamic environments +can be used. Dynamic environments make it possible to create environments on the fly by +declaring their names dynamically in `.gitlab-ci.yml`. + +Dynamic environments are a fundamental part of [Review apps](../review_apps/index.md). + +### Configuring incremental rollouts + +Learn how to release production changes to only a portion of your Kubernetes pods with +[incremental rollouts](../environments/incremental_rollouts.md). + +#### Allowed variables + +The `name` and `url` parameters for dynamic environments can use most available CI/CD variables, +including: + +- [Predefined environment variables](../variables/README.md#predefined-environment-variables) +- [Project and group variables](../variables/README.md#gitlab-cicd-environment-variables) +- [`.gitlab-ci.yml` variables](../yaml/README.md#variables) + +However, you cannot use variables defined: + +- Under `script`. +- On the Runner's side. + +There are also other variables that are unsupported in the context of `environment:name`. +For more information, see [Where variables can be used](../variables/where_variables_can_be_used.md). + +#### Example configuration + +GitLab Runner exposes various [environment variables](../variables/README.md) when a job runs, so +you can use them as environment names. + +In the following example, the job will deploy to all branches except `master`: + +```yaml +deploy_review: + stage: deploy + script: + - echo "Deploy a review app" + environment: + name: review/$CI_COMMIT_REF_NAME + url: https://$CI_ENVIRONMENT_SLUG.example.com + only: + - branches + except: + - master +``` + +In this example: + +- The job's name is `deploy_review` and it runs on the `deploy` stage. +- We set the `environment` with the `environment:name` as `review/$CI_COMMIT_REF_NAME`. + Since the [environment name](../yaml/README.md#environmentname) can contain slashes (`/`), we can + use this pattern to distinguish between dynamic and regular environments. +- We tell the job to run [`only`](../yaml/README.md#onlyexcept-basic) on branches, + [`except`](../yaml/README.md#onlyexcept-basic) `master`. + +For the value of: + +- `environment:name`, the first part is `review`, followed by a `/` and then `$CI_COMMIT_REF_NAME`, + which receives the value of the branch name. +- `environment:url`, we want a specific and distinct URL for each branch. `$CI_COMMIT_REF_NAME` + may contain a `/` or other characters that would be invalid in a domain name or URL, + so we use `$CI_ENVIRONMENT_SLUG` to guarantee that we get a valid URL. + + For example, given a `$CI_COMMIT_REF_NAME` of `100-Do-The-Thing`, the URL will be something + like `https://100-do-the-4f99a2.example.com`. Again, the way you set up + the web server to serve these requests is based on your setup. + + We have used `$CI_ENVIRONMENT_SLUG` here because it is guaranteed to be unique. If + you're using a workflow like [GitLab Flow](../../topics/gitlab_flow.md), collisions + are unlikely and you may prefer environment names to be more closely based on the + branch name. In that case, you could use `$CI_COMMIT_REF_NAME` in `environment:url` in + the example above: `https://$CI_COMMIT_REF_NAME.example.com`, which would give a URL + of `https://100-do-the-thing.example.com`. + +NOTE: **Note:** +You are not required to use the same prefix or only slashes (`/`) in the dynamic environments' +names. However, using this format will enable the [grouping similar environments](#grouping-similar-environments) +feature. + +### Configuring Kubernetes deployments + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27630) in GitLab 12.6. + +If you are deploying to a [Kubernetes cluster](../../user/project/clusters/index.md) +associated with your project, you can configure these deployments from your +`gitlab-ci.yml` file. + +The following configuration options are supported: + +- [`namespace`](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) + +In the following example, the job will deploy your application to the +`production` Kubernetes namespace. + +```yaml +deploy: + stage: deploy + script: + - echo "Deploy to production server" + environment: + name: production + url: https://example.com + kubernetes: + namespace: production + only: + - master +``` + +When deploying to a Kubernetes cluster using GitLab's Kubernetes integration, +information about the cluster and namespace will be displayed above the job +trace on the deployment job page: + +![Deployment cluster information](../img/environments_deployment_cluster_v12_8.png) + +NOTE: **Note:** +Kubernetes configuration is not supported for Kubernetes clusters +that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters). +To follow progress on support for GitLab-managed clusters, see the +[relevant issue](https://gitlab.com/gitlab-org/gitlab/issues/38054). + +### Complete example + +The configuration in this section provides a full development workflow where your app is: + +- Tested. +- Built. +- Deployed as a Review App. +- Deployed to a staging server once the merge request is merged. +- Finally, able to be manually deployed to the production server. + +The following combines the previous configuration examples, including: + +- Defining [simple environments](#defining-environments) for testing, building, and deployment to staging. +- Adding [manual actions](#configuring-manual-deployments) for deployment to production. +- Creating [dynamic environments](#configuring-dynamic-environments) for deployments for reviewing. + +```yaml +stages: + - test + - build + - deploy + +test: + stage: test + script: echo "Running tests" + +build: + stage: build + script: echo "Building the app" + +deploy_review: + stage: deploy + script: + - echo "Deploy a review app" + environment: + name: review/$CI_COMMIT_REF_NAME + url: https://$CI_ENVIRONMENT_SLUG.example.com + only: + - branches + except: + - master + +deploy_staging: + stage: deploy + script: + - echo "Deploy to staging server" + environment: + name: staging + url: https://staging.example.com + only: + - master + +deploy_prod: + stage: deploy + script: + - echo "Deploy to production server" + environment: + name: production + url: https://example.com + when: manual + only: + - master +``` + +A more realistic example would also include copying files to a location where a +webserver (for example, NGINX) could then access and serve them. + +The example below will copy the `public` directory to `/srv/nginx/$CI_COMMIT_REF_SLUG/public`: + +```yaml +review_app: + stage: deploy + script: + - rsync -av --delete public /srv/nginx/$CI_COMMIT_REF_SLUG + environment: + name: review/$CI_COMMIT_REF_NAME + url: https://$CI_COMMIT_REF_SLUG.example.com +``` + +This example requires that NGINX and GitLab Runner are set up on the server this job will run on. + +NOTE: **Note:** +See the [limitations](#limitations) section for some edge cases regarding the naming of +your branches and Review Apps. + +The complete example provides the following workflow to developers: + +- Create a branch locally. +- Make changes and commit them. +- Push the branch to GitLab. +- Create a merge request. + +Behind the scenes, GitLab Runner will: + +- Pick up the changes and start running the jobs. +- Run the jobs sequentially as defined in `stages`: + - First, run the tests. + - If the tests succeed, build the app. + - If the build succeeds, the app is deployed to an environment with a name specific to the + branch. + +So now, every branch: + +- Gets its own environment. +- Is deployed to its own unique location, with the added benefit of: + - Having a [history of deployments](#viewing-deployment-history). + - Being able to [rollback changes](#retrying-and-rolling-back) if needed. + +For more information, see [Using the environment URL](#using-the-environment-url). + +### Protected environments + +Environments can be "protected", restricting access to them. + +For more information, see [Protected environments](protected_environments.md). + +## Working with environments + +Once environments are configured, GitLab provides many features for working with them, +as documented below. + +### Viewing environments and deployments + +A list of environments and deployment statuses is available on each project's **Operations > Environments** page. + +For example: + +![Environment view](../img/environments_available.png) + +This example shows: + +- The environment's name with a link to its deployments. +- The last deployment ID number and who performed it. +- The job ID of the last deployment with its respective job name. +- The commit information of the last deployment, such as who committed it, to what + branch, and the Git SHA of the commit. +- The exact time the last deployment was performed. +- A button that takes you to the URL that you defined under the `environment` keyword + in `.gitlab-ci.yml`. +- A button that re-deploys the latest deployment, meaning it runs the job + defined by the environment name for that specific commit. + +The information shown in the **Environments** page is limited to the latest +deployments, but an environment can have multiple deployments. + +> **Notes:** +> +> - While you can create environments manually in the web interface, we recommend +> that you define your environments in `.gitlab-ci.yml` first. They will +> be automatically created for you after the first deploy. +> - The environments page can only be viewed by users with [Reporter permission](../../user/permissions.md#project-members-permissions) +> and above. For more information on permissions, see the [permissions documentation](../../user/permissions.md). +> - Only deploys that happen after your `.gitlab-ci.yml` is properly configured +> will show up in the **Environment** and **Last deployment** lists. + +### Viewing deployment history + +GitLab keeps track of your deployments, so you: + +- Always know what is currently being deployed on your servers. +- Can have the full history of your deployments for every environment. + +Clicking on an environment shows the history of its deployments. Here's an example **Environments** page +with multiple deployments: + +![Deployments](../img/deployments_view.png) + +This view is similar to the **Environments** page, but all deployments are shown. Also in this view +is a **Rollback** button. For more information, see [Retrying and rolling back](#retrying-and-rolling-back). + +### Retrying and rolling back + +If there is a problem with a deployment, you can retry it or roll it back. + +To retry or rollback a deployment: + +1. Navigate to **Operations > Environments**. +1. Click on the environment. +1. In the deployment history list for the environment, click the: + - **Retry** button next to the last deployment, to retry that deployment. + - **Rollback** button next to a previously successful deployment, to roll back to that deployment. + +#### What to expect with a rollback + +Pressing the **Rollback** button on a specific commit will trigger a _new_ deployment with its +own unique job ID. + +This means that you will see a new deployment that points to the commit you are rolling back to. + +NOTE: **Note:** +The defined deployment process in the job's `script` determines whether the rollback succeeds or not. + +### Using the environment URL + +The [environment URL](../yaml/README.md#environmenturl) is exposed in a few +places within GitLab: + +- In a merge request widget as a link: + ![Environment URL in merge request](../img/environments_mr_review_app.png) +- In the Environments view as a button: + ![Environment URL in environments](../img/environments_available.png) +- In the Deployments view as a button: + ![Environment URL in deployments](../img/deployments_view.png) + +You can see this information in a merge request itself if: + +- The merge request is eventually merged to the default branch (usually `master`). +- That branch also deploys to an environment (for example, `staging` or `production`). + +For example: + +![Environment URLs in merge request](../img/environments_link_url_mr.png) + +#### Going from source files to public pages + +With GitLab's [Route Maps](../review_apps/index.md#route-maps) you can go directly +from source files to public pages in the environment set for Review Apps. + +### Stopping an environment + +Stopping an environment: + +- Moves it from the list of **Available** environments to the list of **Stopped** + environments on the [**Environments** page](#viewing-environments-and-deployments). +- Executes an [`on_stop` action](../yaml/README.md#environmenton_stop), if defined. + +This is often used when multiple developers are working on a project at the same time, +each of them pushing to their own branches, causing many dynamic environments to be created. + +NOTE: **Note:** +Starting with GitLab 8.14, dynamic environments are stopped automatically +when their associated branch is deleted. + +#### Automatically stopping an environment + +Environments can be stopped automatically using special configuration. + +Consider the following example where the `deploy_review` job calls `stop_review` +to clean up and stop the environment: + +```yaml +deploy_review: + stage: deploy + script: + - echo "Deploy a review app" + environment: + name: review/$CI_COMMIT_REF_NAME + url: https://$CI_ENVIRONMENT_SLUG.example.com + on_stop: stop_review + only: + - branches + except: + - master + +stop_review: + stage: deploy + variables: + GIT_STRATEGY: none + script: + - echo "Remove review app" + when: manual + environment: + name: review/$CI_COMMIT_REF_NAME + action: stop +``` + +Setting the [`GIT_STRATEGY`](../yaml/README.md#git-strategy) to `none` is necessary in the +`stop_review` job so that the [GitLab Runner](https://docs.gitlab.com/runner/) won't +try to check out the code after the branch is deleted. + +When you have an environment that has a stop action defined (typically when +the environment describes a Review App), GitLab will automatically trigger a +stop action when the associated branch is deleted. The `stop_review` job must +be in the same `stage` as the `deploy_review` job in order for the environment +to automatically stop. + +You can read more in the [`.gitlab-ci.yml` reference](../yaml/README.md#environmenton_stop). + +#### Environments auto-stop + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20956) in GitLab 12.8. + +You can set a expiry time to environments and stop them automatically after a certain period. + +For example, consider the use of this feature with Review Apps environments. +When you set up Review Apps, sometimes they keep running for a long time +because some merge requests are left as open. An example for this situation is when the author of the merge +request is not actively working on it, due to priority changes or a different approach was decided on, and the merge requests was simply forgotten. +Idle environments waste resources, therefore they +should be terminated as soon as possible. + +To address this problem, you can specify an optional expiration date for +Review Apps environments. When the expiry time is reached, GitLab will automatically trigger a job +to stop the environment, eliminating the need of manually doing so. In case an environment is updated, the expiration is renewed +ensuring that only active merge requests keep running Review Apps. + +To enable this feature, you need to specify the [`environment:auto_stop_in`](../yaml/README.md#environmentauto_stop_in) keyword in `.gitlab-ci.yml`. +You can specify a human-friendly date as the value, such as `1 hour and 30 minutes` or `1 day`. +`auto_stop_in` uses the same format of [`artifacts:expire_in` docs](../yaml/README.md#artifactsexpire_in). + +##### Auto-stop example + +In the following example, there is a basic review app setup that creates a new environment +per merge request. The `review_app` job is triggered by every push and +creates or updates an environment named `review/your-branch-name`. +The environment keeps running until `stop_review_app` is executed: + +```yaml +review_app: + script: deploy-review-app + environment: + name: review/$CI_COMMIT_REF_NAME + on_stop: stop_review_app + auto_stop_in: 1 week + +stop_review_app: + script: stop-review-app + environment: + name: review/$CI_COMMIT_REF_NAME + action: stop + when: manual +``` + +As long as a merge request is active and keeps getting new commits, +the review app will not stop, so developers don't need to worry about +re-initiating review app. + +On the other hand, since `stop_review_app` is set to `auto_stop_in: 1 week`, +if a merge request becomes inactive for more than a week, +GitLab automatically triggers the `stop_review_app` job to stop the environment. + +You can also check the expiration date of environments through the GitLab UI. To do so, +go to **Operations > Environments > Environment**. You can see the auto-stop period +at the left-top section and a pin-mark button at the right-top section. This pin-mark +button can be used to prevent auto-stopping the environment. By clicking this button, the `auto_stop_in` setting is over-written +and the environment will be active until it's stopped manually. + +![Environment auto stop](../img/environment_auto_stop_v12_8.png) + +NOTE: **NOTE** +Due to the resource limitation, a background worker for stopping environments only +runs once every hour. This means environments will not be stopped at the exact +timestamp as the specified period, but will be stopped when the hourly cron worker +detects expired environments. + +#### Delete a stopped environment + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22629) in GitLab 12.9. + +You can delete [stopped environments](#stopping-an-environment) in one of two +ways: through the GitLab UI or through the API. + +##### Delete environments through the UI + +To view the list of **Stopped** environments, navigate to **Operations > Environments** +and click the **Stopped** tab. + +From there, you can click the **Delete** button directly, or you can click the +environment name to see its details and **Delete** it from there. + +You can also delete environments by viewing the details for a +stopped environment: + + 1. Navigate to **Operations > Environments**. + 1. Click on the name of an environment within the **Stopped** environments list. + 1. Click on the **Delete** button that appears at the top for all stopped environments. + 1. Finally, confirm your chosen environment in the modal that appears to delete it. + +##### Delete environments through the API + +Environments can also be deleted by using the [Environments API](../../api/environments.md#delete-an-environment). + +### Grouping similar environments + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7015) in GitLab 8.14. + +As documented in [Configuring dynamic environments](#configuring-dynamic-environments), you can +prepend environment name with a word, followed by a `/`, and finally the branch +name, which is automatically defined by the `CI_COMMIT_REF_NAME` variable. + +In short, environments that are named like `type/foo` are all presented under the same +group, named `type`. + +In our [minimal example](#example-configuration), we named the environments `review/$CI_COMMIT_REF_NAME` +where `$CI_COMMIT_REF_NAME` is the branch name. Here is a snippet of the example: + +```yaml +deploy_review: + stage: deploy + script: + - echo "Deploy a review app" + environment: + name: review/$CI_COMMIT_REF_NAME +``` + +In this case, if you visit the **Environments** page and the branches +exist, you should see something like: + +![Environment groups](../img/environments_dynamic_groups.png) + +### Monitoring environments + +If you have enabled [Prometheus for monitoring system and response metrics](../../user/project/integrations/prometheus.md), +you can monitor the behavior of your app running in each environment. For the monitoring +dashboard to appear, you need to Configure Prometheus to collect at least one +[supported metric](../../user/project/integrations/prometheus_library/index.md). + +NOTE: **Note:** +Since GitLab 9.2, all deployments to an environment are shown directly on the monitoring dashboard. + +Once configured, GitLab will attempt to retrieve [supported performance metrics](../../user/project/integrations/prometheus_library/index.md) +for any environment that has had a successful deployment. If monitoring data was +successfully retrieved, a **Monitoring** button will appear for each environment. + +![Environment Detail with Metrics](../img/deployments_view.png) + +Clicking on the **Monitoring** button will display a new page showing up to the last +8 hours of performance data. It may take a minute or two for data to appear +after initial deployment. + +All deployments to an environment are shown directly on the monitoring dashboard, +which allows easy correlation between any changes in performance and new +versions of the app, all without leaving GitLab. + +![Monitoring dashboard](../img/environments_monitoring.png) + +#### Linking to external dashboard + +Add a [button to the Monitoring dashboard](../../user/project/operations/linking_to_an_external_dashboard.md) linking directly to your existing external dashboards. + +#### Embedding metrics in GitLab Flavored Markdown + +Metric charts can be embedded within GitLab Flavored Markdown. See [Embedding Metrics within GitLab Flavored Markdown](../../user/project/integrations/prometheus.md#embedding-metric-charts-within-gitlab-flavored-markdown) for more details. + +### Web terminals + +> Web terminals were added in GitLab 8.15 and are only available to project Maintainers and Owners. + +If you deploy to your environments with the help of a deployment service (for example, +the [Kubernetes integration](../../user/project/clusters/index.md)), GitLab can open +a terminal session to your environment. + +This is a powerful feature that allows you to debug issues without leaving the comfort +of your web browser. To enable it, just follow the instructions given in the service integration +documentation. + +Once enabled, your environments will gain a "terminal" button: + +![Terminal button on environment index](../img/environments_terminal_button_on_index.png) + +You can also access the terminal button from the page for a specific environment: + +![Terminal button for an environment](../img/environments_terminal_button_on_show.png) + +Wherever you find it, clicking the button will take you to a separate page to +establish the terminal session: + +![Terminal page](../img/environments_terminal_page.png) + +This works just like any other terminal. You'll be in the container created +by your deployment so you can: + +- Run shell commands and get responses in real time. +- Check the logs. +- Try out configuration or code tweaks etc. + +You can open multiple terminals to the same environment, they each get their own shell +session and even a multiplexer like `screen` or `tmux`. + +NOTE: **Note:** +Container-based deployments often lack basic tools (like an editor), and may +be stopped or restarted at any time. If this happens, you will lose all your +changes. Treat this as a debugging tool, not a comprehensive online IDE. + +### Check out deployments locally + +Since GitLab 8.13, a reference in the Git repository is saved for each deployment, so +knowing the state of your current environments is only a `git fetch` away. + +In your Git configuration, append the `[remote "<your-remote>"]` block with an extra +fetch line: + +```plaintext +fetch = +refs/environments/*:refs/remotes/origin/environments/* +``` + +### Scoping environments with specs + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2112) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.4. +> - [Scoping for environment variables was moved to Core](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30779) to Core in GitLab 12.2. + +You can limit the environment scope of a variable by +defining which environments it can be available for. + +Wildcards can be used, and the default environment scope is `*`, which means +any jobs will have this variable, not matter if an environment is defined or +not. + +For example, if the environment scope is `production`, then only the jobs +having the environment `production` defined would have this specific variable. +Wildcards (`*`) can be used along with the environment name, therefore if the +environment scope is `review/*` then any jobs with environment names starting +with `review/` would have that particular variable. + +Some GitLab features can behave differently for each environment. +For example, you can +[create a secret variable to be injected only into a production environment](../variables/README.md#limit-the-environment-scopes-of-environment-variables). + +In most cases, these features use the _environment specs_ mechanism, which offers +an efficient way to implement scoping within each environment group. + +Let's say there are four environments: + +- `production` +- `staging` +- `review/feature-1` +- `review/feature-2` + +Each environment can be matched with the following environment spec: + +| Environment Spec | `production` | `staging` | `review/feature-1` | `review/feature-2` | +|:-----------------|:-------------|:----------|:-------------------|:-------------------| +| * | Matched | Matched | Matched | Matched | +| production | Matched | | | | +| staging | | Matched | | | +| review/* | | | Matched | Matched | +| review/feature-1 | | | Matched | | + +As you can see, you can use specific matching for selecting a particular environment, +and also use wildcard matching (`*`) for selecting a particular environment group, +such as [Review Apps](../review_apps/index.md) (`review/*`). + +NOTE: **Note:** +The most _specific_ spec takes precedence over the other wildcard matching. +In this case, `review/feature-1` spec takes precedence over `review/*` and `*` specs. + +### Environments Dashboard **(PREMIUM)** + +See [Environments Dashboard](../environments/environments_dashboard.md) for a summary of each +environment's operational health. + +## Limitations + +In the `environment: name`, you are limited to only the [predefined environment variables](../variables/predefined_variables.md). +Re-using variables defined inside `script` as part of the environment name will not work. + +## Further reading + +Below are some links you may find interesting: + +- [The `.gitlab-ci.yml` definition of environments](../yaml/README.md#environment) +- [A blog post on Deployments & Environments](https://about.gitlab.com/blog/2016/08/26/ci-deployment-and-environments/) +- [Review Apps - Use dynamic environments to deploy your code for every branch](../review_apps/index.md) +- [Deploy Boards for your applications running on Kubernetes](../../user/project/deploy_boards.md) **(PREMIUM)** + +<!-- ## Troubleshooting + +Include any troubleshooting steps that you can foresee. If you know beforehand what issues +one might have when setting this up, or when something is changed, or on upgrading, it's +important to describe those, too. Think of things that may go wrong and include them here. +This is important to minimize requests for support, and to avoid doc comments with +questions that you know someone might ask. + +Each scenario can be a third-level heading, e.g. `### Getting error message X`. +If you have none to add when creating a doc, leave this section in place +but commented out to help encourage others to add to it in the future. --> |