environments.md 27,7 КБ
Newer Older
Marcia Ramos's avatar
Marcia Ramos включено в состав коммита
1
2
3
4
---
type: reference
---

Evan Read's avatar
Evan Read включено в состав коммита
5
# Environments and deployments
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
6

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
7
> Introduced in GitLab 8.9.
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
8

Evan Read's avatar
Evan Read включено в состав коммита
9
10
Environments allow control of the continuous deployment of your software,
all within GitLab.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
11

Evan Read's avatar
Evan Read включено в состав коммита
12
13
14
15
16
17
18
19
20
21
22
## 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.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
23
This helps find bugs in your software, and also in the deployment process as well.
Evan Read's avatar
Evan Read включено в состав коммита
24
25

GitLab CI/CD is capable of not only testing or building your projects, but also
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
26
deploying them in your infrastructure, with the added benefit of giving you a
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
27
way to track your deployments. In other words, you will always know what is
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
28
currently being deployed or has been deployed on your servers.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
29

Evan Read's avatar
Evan Read включено в состав коммита
30
It's important to know that:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
31

Evan Read's avatar
Evan Read включено в состав коммита
32
33
34
- 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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
35

Evan Read's avatar
Evan Read включено в состав коммита
36
37
GitLab:

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
38
- Provides a full history of your deployments for each environment.
Evan Read's avatar
Evan Read включено в состав коммита
39
40
41
42
- 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)
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
43
associated with your project, you can use it to assist with your deployments, and
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
44
can even access a [web terminal](#web-terminals) for your environment from within GitLab!
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
45

Evan Read's avatar
Evan Read включено в состав коммита
46
47
48
49
50
51
## Configuring environments

Configuring environments involves:

1. Understanding how [pipelines](pipelines.md) work.
1. Defining environments in your project's [`.gitlab-ci.yml`](yaml/README.md) file.
GitLab Bot's avatar
GitLab Bot включено в состав коммита
52
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).
Evan Read's avatar
Evan Read включено в состав коммита
53

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
54
55
The rest of this section illustrates how to configure environments and deployments using
an example scenario. It assumes you have already:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
56

Evan Read's avatar
Evan Read включено в состав коммита
57
58
- Created a [project](../gitlab-basics/create-project.md) in GitLab.
- Set up [a Runner](runners/README.md).
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
59

Evan Read's avatar
Evan Read включено в состав коммита
60
In the scenario:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
61

Evan Read's avatar
Evan Read включено в состав коммита
62
63
64
65
66
67
- 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
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
68

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
69
Let's consider the following `.gitlab-ci.yml` example:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
70

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
71
72
73
74
75
```yaml
stages:
  - test
  - build
  - deploy
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
76

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
77
78
79
test:
  stage: test
  script: echo "Running tests"
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
80

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
81
82
83
build:
  stage: build
  script: echo "Building the app"
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
84

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
85
86
87
deploy_staging:
  stage: deploy
  script:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
88
    - echo "Deploy to staging server"
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
89
  environment:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
90
91
    name: staging
    url: https://staging.example.com
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
92
93
94
  only:
  - master
```
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
95

Evan Read's avatar
Evan Read включено в состав коммита
96
We have defined three [stages](yaml/README.md#stages):
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
97

Evan Read's avatar
Evan Read включено в состав коммита
98
99
100
- `test`
- `build`
- `deploy`
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
101

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
102
103
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.
Evan Read's avatar
Evan Read включено в состав коммита
104
105
106
107
108
109
110

In our case:

- The `test` job will run first.
- Then the `build` job.
- Lastly the `deploy_staging` job.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
111
With this configuration, we:
Evan Read's avatar
Evan Read включено в состав коммита
112

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
113
114
- Check that the tests pass.
- Ensure that our app is able to be built successfully.
Evan Read's avatar
Evan Read включено в состав коммита
115
- Lastly we deploy to the staging server.
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
116

Evan Read's avatar
Evan Read включено в состав коммита
117
NOTE: **Note:**
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
118
The `environment` keyword is just a hint for GitLab that this job actually
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
119
deploys to the `name` environment. It can also have a `url` that is
Evan Read's avatar
Evan Read включено в состав коммита
120
121
exposed in various places within GitLab. Each time a job that
has an environment specified succeeds, a deployment is recorded, storing
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
122
123
the Git SHA and environment name.

Evan Read's avatar
Evan Read включено в состав коммита
124
125
126
127
128
129
130
131
132
133
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`.

GitLab Bot's avatar
GitLab Bot включено в состав коммита
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#### 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`.
Lin Jen-Shin's avatar
Lin Jen-Shin включено в состав коммита
155

Evan Read's avatar
Evan Read включено в состав коммита
156
### Configuring manual deployments
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
157

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
158
159
Adding `when: manual` to an automatically executed job's configuration converts it to
a job requiring manual action.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
160

Evan Read's avatar
Evan Read включено в состав коммита
161
162
163
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
164

Evan Read's avatar
Evan Read включено в состав коммита
165
The `.gitlab-ci.yml` file for this is as follows:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
166

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
```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
```

Evan Read's avatar
Evan Read включено в состав коммита
203
204
The `when: manual` action:

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
205
- Exposes a "play" button in GitLab's UI for that job.
Evan Read's avatar
Evan Read включено в состав коммита
206
- Means the `deploy_prod` job will only be triggered when the "play" button is clicked.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
207

Evan Read's avatar
Evan Read включено в состав коммита
208
You can find the "play" button in the pipelines, environments, deployments, and jobs views.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
209

Evan Read's avatar
Evan Read включено в состав коммита
210
211
212
213
214
215
216
217
| 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)               |

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
218
219
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`.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
220

Evan Read's avatar
Evan Read включено в состав коммита
221
222
NOTE: **Note:**
If your environment's name is `production` (all lowercase),
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
223
224
it will get recorded in [Cycle Analytics](../user/project/cycle_analytics.md).

Evan Read's avatar
Evan Read включено в состав коммита
225
### Configuring dynamic environments
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
226

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
227
Regular environments are good when deploying to "stable" environments like staging or production.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
228

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
229
230
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
Evan Read's avatar
Evan Read включено в состав коммита
231
232
declaring their names dynamically in `.gitlab-ci.yml`.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
233
Dynamic environments are a fundamental part of [Review apps](review_apps/index.md).
Evan Read's avatar
Evan Read включено в состав коммита
234
235
236
237
238
239
240

#### 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)
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
241
- [Project and group variables](variables/README.md#gitlab-cicd-environment-variables)
Evan Read's avatar
Evan Read включено в состав коммита
242
243
244
245
246
247
248
249
250
251
252
253
- [`.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

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
254
GitLab Runner exposes various [environment variables](variables/README.md) when a job runs, so
Evan Read's avatar
Evan Read включено в состав коммита
255
256
you can use them as environment names.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
257
In the following example, the job will deploy to all branches except `master`:
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
258

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
259
260
261
262
263
264
```yaml
deploy_review:
  stage: deploy
  script:
    - echo "Deploy a review app"
  environment:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
265
    name: review/$CI_COMMIT_REF_NAME
Vincent Tunru's avatar
Vincent Tunru включено в состав коммита
266
    url: https://$CI_ENVIRONMENT_SLUG.example.com
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
267
268
269
270
  only:
    - branches
  except:
    - master
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
271
```
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
272

Evan Read's avatar
Evan Read включено в состав коммита
273
274
275
276
277
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
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
278
279
280
  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`.
Evan Read's avatar
Evan Read включено в состав коммита
281
282
283
284

For the value of:

- `environment:name`, the first part is `review`, followed by a `/` and then `$CI_COMMIT_REF_NAME`,
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
285
286
287
  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,
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
288
  so we use `$CI_ENVIRONMENT_SLUG` to guarantee that we get a valid URL.
Evan Read's avatar
Evan Read включено в состав коммита
289
290
291
292
293

  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.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
294
295
296
297
298
299
  We have used `$CI_ENVIRONMENT_SLUG` here because it is guaranteed to be unique. If
  you're using a workflow like [GitLab Flow](../workflow/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_SLUG` in `environment:url` in
  the example above: `https://$CI_COMMIT_REF_SLUG.example.com`, which would give a URL
  of `https://100-do-the-thing.example.com`.
Evan Read's avatar
Evan Read включено в состав коммита
300
301

NOTE: **Note:**
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
302
303
304
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.
Evan Read's avatar
Evan Read включено в состав коммита
305
306
307
308
309
310
311
312
313

### 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.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
314
- Finally, able to be manually deployed to the production server.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
315

Evan Read's avatar
Evan Read включено в состав коммита
316
317
318
319
320
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

```yaml
stages:
  - test
  - build
  - deploy

test:
  stage: test
  script: echo "Running tests"

build:
  stage: build
  script: echo "Building the app"

deploy_review:
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
337
  stage: deploy
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
338
  script:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
339
    - echo "Deploy a review app"
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
340
  environment:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
341
    name: review/$CI_COMMIT_REF_NAME
Nick Thomas's avatar
Nick Thomas включено в состав коммита
342
    url: https://$CI_ENVIRONMENT_SLUG.example.com
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  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
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
368
369
```

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
370
A more realistic example would also include copying files to a location where a
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
371
webserver (for example, NGINX) could then access and serve them.
Evan Read's avatar
Evan Read включено в состав коммита
372
373

The example below will copy the `public` directory to `/srv/nginx/$CI_COMMIT_REF_SLUG/public`:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
374
375
376
377
378

```yaml
review_app:
  stage: deploy
  script:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
379
    - rsync -av --delete public /srv/nginx/$CI_COMMIT_REF_SLUG
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
380
  environment:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
381
382
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_COMMIT_REF_SLUG.example.com
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
383
384
```

Evan Read's avatar
Evan Read включено в состав коммита
385
386
387
This example requires that NGINX and GitLab Runner are set up on the server this job will run on.

NOTE: **Note:**
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
388
389
See the [limitations](#limitations) section for some edge cases regarding the naming of
your branches and Review Apps.
Evan Read's avatar
Evan Read включено в состав коммита
390

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
391
The complete example provides the following workflow to developers:
Evan Read's avatar
Evan Read включено в состав коммита
392
393

- Create a branch locally.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
394
- Make changes and commit them.
Evan Read's avatar
Evan Read включено в состав коммита
395
396
397
- Push the branch to GitLab.
- Create a merge request.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
398
Behind the scenes, GitLab Runner will:
Evan Read's avatar
Evan Read включено в состав коммита
399
400
401
402
403

- 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.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
404
  - If the build succeeds, the app is deployed to an environment with a name specific to the
Evan Read's avatar
Evan Read включено в состав коммита
405
406
407
408
409
    branch.

So now, every branch:

- Gets its own environment.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
410
- Is deployed to its own unique location, with the added benefit of:
Evan Read's avatar
Evan Read включено в состав коммита
411
412
413
  - Having a [history of deployments](#viewing-deployment-history).
  - Being able to [rollback changes](#retrying-and-rolling-back) if needed.

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
414
For more information, see [Using the environment URL](#using-the-environment-url).
Evan Read's avatar
Evan Read включено в состав коммита
415
416
417
418
419
420
421
422
423

### Protected environments

Environments can be "protected", restricting access to them.

For more information, see [Protected environments](environments/protected_environments.md).

## Working with environments

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
424
425
Once environments are configured, GitLab provides many features for working with them,
as documented below.
Evan Read's avatar
Evan Read включено в состав коммита
426
427
428

### Viewing environments and deployments

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
429
A list of environments and deployment statuses is available on each project's **Operations > Environments** page.
Evan Read's avatar
Evan Read включено в состав коммита
430
431
432
433
434
435
436
437
438
439

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.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
440
- The commit information of the last deployment, such as who committed it, to what
Evan Read's avatar
Evan Read включено в состав коммита
441
442
  branch, and the Git SHA of the commit.
- The exact time the last deployment was performed.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
443
444
- A button that takes you to the URL that you defined under the `environment` keyword
  in `.gitlab-ci.yml`.
Evan Read's avatar
Evan Read включено в состав коммита
445
446
447
448
449
450
451
452
453
454
455
- 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.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
456
457
> - 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).
Evan Read's avatar
Evan Read включено в состав коммита
458
459
460
461
462
463
464
465
> - 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.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
466
- Can have the full history of your deployments for every environment.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
467

Evan Read's avatar
Evan Read включено в состав коммита
468
469
Clicking on an environment shows the history of its deployments. Here's an example **Environments** page
with multiple deployments:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
470

Evan Read's avatar
Evan Read включено в состав коммита
471
472
473
474
![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).
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
475

Evan Read's avatar
Evan Read включено в состав коммита
476
### Retrying and rolling back
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
477

Evan Read's avatar
Evan Read включено в состав коммита
478
If there is a problem with a deployment, you can retry it or roll it back.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
479

Evan Read's avatar
Evan Read включено в состав коммита
480
To retry or rollback a deployment:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
481

Evan Read's avatar
Evan Read включено в состав коммита
482
483
1. Navigate to **Operations > Environments**.
1. Click on the environment.
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
484
485
486
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
487

Evan Read's avatar
Evan Read включено в состав коммита
488
489
NOTE: **Note:**
The defined deployment process in the job's `script` determines whether the rollback succeeds or not.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
490

Evan Read's avatar
Evan Read включено в состав коммита
491
### Using the environment URL
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
492

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
493
The [environment URL](yaml/README.md#environmenturl) is exposed in a few
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
494
places within GitLab:
Evan Read's avatar
Evan Read включено в состав коммита
495
496
497
498
499
500
501

- 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)
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
502

Evan Read's avatar
Evan Read включено в состав коммита
503
504
505
506
507
508
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:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
509
510
511

![Environment URLs in merge request](img/environments_link_url_mr.png)

Evan Read's avatar
Evan Read включено в состав коммита
512
#### Going from source files to public pages
Douwe Maan's avatar
Douwe Maan включено в состав коммита
513

Marcia Ramos's avatar
Marcia Ramos включено в состав коммита
514
With GitLab's [Route Maps](review_apps/index.md#route-maps) you can go directly
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
515
from source files to public pages in the environment set for Review Apps.
Marcia Ramos's avatar
Marcia Ramos включено в состав коммита
516

Evan Read's avatar
Evan Read включено в состав коммита
517
### Stopping an environment
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
518

Evan Read's avatar
Evan Read включено в состав коммита
519
Stopping an environment:
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
520

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
521
522
- Moves it from the list of **Available** environments to the list of **Stopped**
  environments on the [**Environments** page](#viewing-environments-and-deployments).
Evan Read's avatar
Evan Read включено в состав коммита
523
- Executes an [`on_stop` action](yaml/README.md#environmenton_stop), if defined.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
524

Evan Read's avatar
Evan Read включено в состав коммита
525
526
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
527

Evan Read's avatar
Evan Read включено в состав коммита
528
NOTE: **Note:**
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
529
Starting with GitLab 8.14, dynamic environments are stopped automatically
Evan Read's avatar
Evan Read включено в состав коммита
530
531
532
533
534
when their associated branch is deleted.

#### Automatically stopping an environment

Environments can be stopped automatically using special configuration.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
535

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
536
Consider the following example where the `deploy_review` job calls `stop_review`
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
537
538
539
540
to clean up and stop the environment:

```yaml
deploy_review:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
541
542
  stage: deploy
  script:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
543
    - echo "Deploy a review app"
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
544
  environment:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
545
    name: review/$CI_COMMIT_REF_NAME
Nick Thomas's avatar
Nick Thomas включено в состав коммита
546
    url: https://$CI_ENVIRONMENT_SLUG.example.com
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
547
    on_stop: stop_review
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
548
549
550
551
  only:
    - branches
  except:
    - master
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
552
553

stop_review:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
554
  stage: deploy
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
555
556
  variables:
    GIT_STRATEGY: none
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
557
558
  script:
    - echo "Remove review app"
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
559
560
  when: manual
  environment:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
561
    name: review/$CI_COMMIT_REF_NAME
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
562
563
    action: stop
```
Mark Pundsack's avatar
Mark Pundsack включено в состав коммита
564

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
565
566
567
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
568

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
569
When you have an environment that has a stop action defined (typically when
Evan Read's avatar
Evan Read включено в состав коммита
570
the environment describes a Review App), GitLab will automatically trigger a
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
571
stop action when the associated branch is deleted. The `stop_review` job must
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
572
be in the same `stage` as the `deploy_review` job in order for the environment
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
573
to automatically stop.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
574

Evan Read's avatar
Evan Read включено в состав коммита
575
You can read more in the [`.gitlab-ci.yml` reference](yaml/README.md#environmenton_stop).
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
576

Evan Read's avatar
Evan Read включено в состав коммита
577
### Grouping similar environments
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
578

GitLab Bot's avatar
GitLab Bot включено в состав коммита
579
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/7015) in GitLab 8.14.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
580

Evan Read's avatar
Evan Read включено в состав коммита
581
582
583
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
584

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
585
586
In short, environments that are named like `type/foo` are all presented under the same
group, named `type`.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
587

Evan Read's avatar
Evan Read включено в состав коммита
588
589
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:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
590
591
592
593
594
595
596

```yaml
deploy_review:
  stage: deploy
  script:
    - echo "Deploy a review app"
  environment:
Z.J. van de Weg's avatar
Z.J. van de Weg включено в состав коммита
597
    name: review/$CI_COMMIT_REF_NAME
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
598
599
```

Evan Read's avatar
Evan Read включено в состав коммита
600
In this case, if you visit the **Environments** page and the branches
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
601
602
603
exist, you should see something like:

![Environment groups](img/environments_dynamic_groups.png)
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
604

Evan Read's avatar
Evan Read включено в состав коммита
605
### Monitoring environments
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
606

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
607
If you have enabled [Prometheus for monitoring system and response metrics](../user/project/integrations/prometheus.md),
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
608
609
610
611
612
613
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
614

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
615
616
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
Evan Read's avatar
Evan Read включено в состав коммита
617
successfully retrieved, a **Monitoring** button will appear for each environment.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
618

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
619
![Environment Detail with Metrics](img/deployments_view.png)
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
620

Evan Read's avatar
Evan Read включено в состав коммита
621
Clicking on the **Monitoring** button will display a new page showing up to the last
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
622
623
624
8 hours of performance data. It may take a minute or two for data to appear
after initial deployment.

Evan Read's avatar
Evan Read включено в состав коммита
625
All deployments to an environment are shown directly on the monitoring dashboard,
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
626
627
which allows easy correlation between any changes in performance and new
versions of the app, all without leaving GitLab.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
628
629
630

![Monitoring dashboard](img/environments_monitoring.png)

Reuben Pereira's avatar
Reuben Pereira включено в состав коммита
631
632
633
634
#### 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.

Tristan Read's avatar
Tristan Read включено в состав коммита
635
636
637
638
#### 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.

Evan Read's avatar
Evan Read включено в состав коммита
639
640
641
### Web terminals

> Web terminals were added in GitLab 8.15 and are only available to project Maintainers and Owners.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
642

Evan Read's avatar
Evan Read включено в состав коммита
643
644
645
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
646

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
647
648
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
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
649
documentation.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
650
651
652
653
654
655
656
657
658
659
660
661
662
663

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)

Evan Read's avatar
Evan Read включено в состав коммита
664
665
This works just like any other terminal. You'll be in the container created
by your deployment so you can:
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
666

Evan Read's avatar
Evan Read включено в состав коммита
667
668
669
- Run shell commands and get responses in real time.
- Check the logs.
- Try out configuration or code tweaks etc.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
670

Evan Read's avatar
Evan Read включено в состав коммита
671
672
You can open multiple terminals to the same environment, they each get their own shell
session and even a multiplexer like `screen` or `tmux`.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
673

Evan Read's avatar
Evan Read включено в состав коммита
674
675
676
677
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
678

Evan Read's avatar
Evan Read включено в состав коммита
679
### Check out deployments locally
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
680

Evan Read's avatar
Evan Read включено в состав коммита
681
Since GitLab 8.13, a reference in the Git repository is saved for each deployment, so
Nick Thomas's avatar
Nick Thomas включено в состав коммита
682
knowing the state of your current environments is only a `git fetch` away.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
683

Evan Read's avatar
Evan Read включено в состав коммита
684
In your Git configuration, append the `[remote "<your-remote>"]` block with an extra
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
685
686
fetch line:

Evan Read's avatar
Evan Read включено в состав коммита
687
```text
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
688
689
690
fetch = +refs/environments/*:refs/remotes/origin/environments/*
```

Nicolas Borderes's avatar
Nicolas Borderes включено в состав коммита
691
### Scoping environments with specs
Evan Read's avatar
Evan Read включено в состав коммита
692

GitLab Bot's avatar
GitLab Bot включено в состав коммита
693
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/2112) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.4.
GitLab Bot's avatar
GitLab Bot включено в состав коммита
694
> - [Scoping for environment variables was moved to Core](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/30779) to Core in GitLab 12.2.
Marcia Ramos's avatar
Marcia Ramos включено в состав коммита
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710

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
Hordur Freyr Yngvason's avatar
Hordur Freyr Yngvason включено в состав коммита
711
[create a secret variable to be injected only into a production environment](variables/README.md#limiting-environment-scopes-of-environment-variables).
Evan Read's avatar
Evan Read включено в состав коммита
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734

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,
Marcia Ramos's avatar
Marcia Ramos включено в состав коммита
735
such as [Review Apps](review_apps/index.md) (`review/*`).
Evan Read's avatar
Evan Read включено в состав коммита
736
737
738
739
740

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.

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
741
742
## Limitations

Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
743
744
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.
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
745

Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
746
747
748
749
750
751
## 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/2016/08/26/ci-deployment-and-environments/)
Achilleas Pipinellis's avatar
Achilleas Pipinellis включено в состав коммита
752
- [Review Apps - Use dynamic environments to deploy your code for every branch](review_apps/index.md)
Marcel Amirault's avatar
Marcel Amirault включено в состав коммита
753
- [Deploy Boards for your applications running on Kubernetes](../user/project/deploy_boards.md) **(PREMIUM)**
Marcia Ramos's avatar
Marcia Ramos включено в состав коммита
754
755
756
757
758
759
760
761
762
763
764
765

<!-- ## 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. -->