Skip to content

Commit 1d6e737

Browse files
Clarify multi-environment monitoring guidance (#454)
* docs: clarify multi-environment monitoring * docs: address environment guide review
1 parent 687fb1b commit 1d6e737

2 files changed

Lines changed: 212 additions & 85 deletions

File tree

cli/environment-variables.mdx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ a check executes on the Checkly cloud.
6565

6666
### Using the `-e` flag
6767

68+
<Note>
69+
Values passed to `checkly test` with `--env` or `--env-file` apply only to that test session. They do not update variables used by scheduled monitors. To continuously monitor more than one long-lived environment, deploy a separate CLI project for each environment and define its runtime values at the check or group level. See [Monitor multiple environments](/concepts/environments).
70+
</Note>
71+
6872
Here is an example of a Playwright script using an `ENVIRONMENT_URL` variable to define the page to visit. We also added
6973
a fallback value in case that variable is not defined for some reason.
7074

@@ -171,4 +175,3 @@ files to your `.gitignore` file.
171175
3. For remote variables, store sensitive data as secrets in Checkly. For more information on how to manage secrets in Checkly see [variables and secrets](/platform/variables).
172176

173177
All variables are stored encrypted at rest and in transfer.
174-

concepts/environments.mdx

Lines changed: 208 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,234 @@
11
---
2-
title: 'Environments in Checkly'
3-
description: 'Learn about the environments of Checkly'
2+
title: 'Monitor multiple environments'
3+
description: 'Choose how to test and continuously monitor development, staging, and production environments with Checkly.'
44
sidebarTitle: 'Environments'
55
canonical: 'https://www.checklyhq.com/docs/concepts/environments/'
66
---
77

8-
**Environments** in Checkly represent the different stages and contexts where your applications run—from development and staging to production and beyond. Using the CLI, you can run your commands from your CI/CD pipeline and target different environments like staging and production.
8+
Checkly does not create a separate Environment resource. Instead, you combine CLI projects, environment variables, and your CI/CD pipeline to target each application environment.
99

10-
Think of **Environments** as the different places your application lives throughout its lifecycle. Each **Environment** represents a distinct deployment context with its own domain, configurations, database connections, and operational characteristics. Checkly's approach to environments ensures that your monitoring strategy adapts seamlessly as your code moves from development through to production.
10+
Use a separate Checkly CLI project for every long-lived environment that you want to monitor continuously. Use `checkly test` without deploying a project when you only need to validate an ephemeral environment, such as a pull request preview.
1111

12-
The power of Checkly lies in consistency with flexibility—you can define the same monitoring logic once and apply it across multiple **Environments**, while still allowing for environment-specific customizations like different URLS, assertions, authentication credentials, or performance thresholds.
12+
## Choose an approach
1313

14-
## In Practice
15-
For instance, we can infer the hostname by setting the ENVIRONMENT_URL to determine the staging or production hostname. This approach allows you to write monitoring code that automatically adapts to different environments without requiring separate configurations for each deployment stage.
14+
| What you want to do | Recommended approach |
15+
|---|---|
16+
| Test an ephemeral preview deployment | Run `checkly test` with temporary environment variables. Do not deploy it as a scheduled monitor. |
17+
| Continuously monitor the same checks in development, staging, and production | Deploy the same check code as a separate CLI project for each environment. Give every project a unique, stable `logicalId`. |
18+
| Continuously monitor different checks in each environment | Use a separate project for each environment and select shared and environment-specific check files in the project configuration. |
1619

17-
You test your checks locally, or inside your CI/CD pipeline to make sure they run reliably against your staging and production environments. You deploy your checks to Checkly, so we can run them around the clock as monitors and alert you when things break.
20+
<Note>
21+
A Checkly CLI project is a deployment boundary, not the same thing as a Git branch or application environment. Your pipeline decides which branch deploys which project.
22+
</Note>
1823

19-
## Configuration Management Across Environments
20-
<Note>Checkly supports **environment variables** to manage configuration differences between environments. You can define environment variables in the Checkly dashboard and reference them in your test scripts.</Note>
24+
## Test an ephemeral environment
2125

22-
Environment management in Checkly integrates with modern development practices. This is very powerful when combined with passing environment variables using one of the flags --env or --env-file as you can target staging, test and preview environment with specific URLs, credentials and other common variables that differ between environments.
26+
Pass runtime values to `checkly test` with `--env` (`-e`) or `--env-file`. The values apply only to that test session and do not update your scheduled monitors.
2327

24-
You can maintain separate configuration files for different environments, allowing the same monitoring code to behave appropriately whether it's testing your local development setup, validating a staging deployment, or monitoring production services.
25-
26-
## Real-World Environment Examples
27-
Here's how you might structure monitoring across environments:
28-
29-
30-
### Development Environment Example:
28+
```bash Terminal
29+
npx checkly test \
30+
--env ENVIRONMENT_URL="https://preview-123.example.com" \
31+
--env API_TOKEN="$PREVIEW_API_TOKEN"
32+
```
3133

32-
```typescript
33-
// checkly.dev.config.ts
34-
import { defineConfig } from 'checkly'
34+
This approach works well for pull request previews and other short-lived deployments. See [CI/CD](/integrations/ci-cd/overview) for the recommended test-before-deploy workflow.
35+
36+
## Continuously monitor multiple environments
37+
38+
The following example deploys one shared API check to development, staging, and production. Each deployment has:
39+
40+
- A unique project identity and separate deployment history
41+
- The same project-scoped check and group logical IDs
42+
- Its own URL and secret API token
43+
- Its own schedule, locations, and tags
44+
45+
<Accordion title="Prerequisites">
46+
- A Checkly account and a Checkly CLI project
47+
- `CHECKLY_API_KEY` and `CHECKLY_ACCOUNT_ID` configured in your CI provider
48+
- A persistent deployment URL and credentials for each environment
49+
- A CI branch or deployment event that identifies the target environment
50+
</Accordion>
51+
52+
<Steps>
53+
<Step title="Define a stable project identity for each environment">
54+
Read the target environment from your CI pipeline and map it to a unique project `logicalId`.
55+
56+
```typescript checkly.config.ts
57+
import { defineConfig } from "checkly"
58+
import { Frequency } from "checkly/constructs"
59+
60+
type Environment = "development" | "staging" | "production"
61+
62+
const environments: Record<Environment, {
63+
projectName: string
64+
logicalId: string
65+
frequency: Frequency
66+
locations: string[]
67+
}> = {
68+
development: {
69+
projectName: "My app - Development",
70+
logicalId: "my-app-development",
71+
frequency: Frequency.EVERY_30M,
72+
locations: ["us-east-1"],
73+
},
74+
staging: {
75+
projectName: "My app - Staging",
76+
logicalId: "my-app-staging",
77+
frequency: Frequency.EVERY_10M,
78+
locations: ["us-east-1"],
79+
},
80+
production: {
81+
projectName: "My app - Production",
82+
logicalId: "my-app-production",
83+
frequency: Frequency.EVERY_5M,
84+
locations: ["us-east-1", "eu-west-1"],
85+
},
86+
}
87+
88+
const environment = process.env.CHECKLY_ENVIRONMENT as Environment | undefined
89+
90+
if (!environment || !environments[environment]) {
91+
throw new Error(
92+
"Set CHECKLY_ENVIRONMENT to development, staging, or production"
93+
)
94+
}
95+
96+
const target = environments[environment]
97+
98+
export default defineConfig({
99+
projectName: target.projectName,
100+
logicalId: target.logicalId,
101+
checks: {
102+
activated: true,
103+
checkMatch: "**/__checks__/**/*.check.ts",
104+
frequency: target.frequency,
105+
locations: target.locations,
106+
tags: [environment],
107+
},
108+
})
109+
```
110+
111+
Keep each project `logicalId` stable. Changing it creates a different project instead of updating the existing environment's monitors.
112+
</Step>
113+
114+
<Step title="Store environment-specific runtime values with the checks">
115+
Define values on a check or group when scheduled runs need them. In this example, the CLI reads the values from CI while deploying and stores them on the environment's check group.
116+
117+
```typescript __checks__/api.check.ts
118+
import {
119+
ApiCheck,
120+
AssertionBuilder,
121+
CheckGroupV2,
122+
} from "checkly/constructs"
123+
124+
const environment = process.env.CHECKLY_ENVIRONMENT
125+
const environmentUrl = process.env.ENVIRONMENT_URL
126+
const apiToken = process.env.API_TOKEN
127+
128+
if (!environment || !environmentUrl || !apiToken) {
129+
throw new Error(
130+
"Set CHECKLY_ENVIRONMENT, ENVIRONMENT_URL, and API_TOKEN"
131+
)
132+
}
133+
134+
const environmentGroup = new CheckGroupV2("application", {
135+
name: `My app - ${environment}`,
136+
tags: [environment],
137+
environmentVariables: [
138+
{ key: "ENVIRONMENT_URL", value: environmentUrl },
139+
{ key: "API_TOKEN", value: apiToken, secret: true },
140+
],
141+
})
142+
143+
new ApiCheck("api-health", {
144+
name: `API health - ${environment}`,
145+
group: environmentGroup,
146+
request: {
147+
method: "GET",
148+
url: "{{{ENVIRONMENT_URL}}}/health",
149+
headers: [
150+
{ key: "Authorization", value: "Bearer {{{API_TOKEN}}}" },
151+
],
152+
assertions: [AssertionBuilder.statusCode().equals(200)],
153+
},
154+
})
155+
```
156+
157+
The `application` and `api-health` logical IDs can stay the same because resource logical IDs are scoped to their CLI project. Setting `secret: true` prevents Checkly from exposing the token after it is saved.
158+
</Step>
159+
160+
<Step title="Deploy the project that matches the application environment">
161+
Map each persistent application environment to one Checkly project in your pipeline. Run the matching command after that environment's application deployment succeeds.
162+
163+
| Application branch | `CHECKLY_ENVIRONMENT` | Checkly project `logicalId` |
164+
|---|---|---|
165+
| `develop` | `development` | `my-app-development` |
166+
| `staging` | `staging` | `my-app-staging` |
167+
| `main` | `production` | `my-app-production` |
168+
169+
For example, the staging deployment job would run:
170+
171+
```bash Terminal
172+
CHECKLY_ENVIRONMENT=staging \
173+
ENVIRONMENT_URL="https://staging-api.example.com" \
174+
API_TOKEN="$STAGING_API_TOKEN" \
175+
npx checkly deploy
176+
```
177+
178+
The production job uses the same source files but supplies production values:
179+
180+
```bash Terminal
181+
CHECKLY_ENVIRONMENT=production \
182+
ENVIRONMENT_URL="https://api.example.com" \
183+
API_TOKEN="$PRODUCTION_API_TOKEN" \
184+
npx checkly deploy
185+
```
186+
187+
Review the deployment changes before confirming them. After you have verified the mapping, a non-interactive CI job can use `--force` to skip the confirmation prompt.
188+
</Step>
189+
</Steps>
190+
191+
<Warning>
192+
A deploy reconciles only the project selected by its `logicalId`, but resources removed from that project are deleted by default. Run [`checkly deploy --preview`](/cli/checkly-deploy#command-options) when changing branch mappings or environment-specific check selection.
193+
</Warning>
194+
195+
## Run different checks in each environment
196+
197+
When an environment needs additional or different checks, keep shared checks in one directory and select the environment-specific directory from your configuration:
198+
199+
```typescript checkly.config.ts
200+
const sharedChecks = "**/__checks__/shared/**/*.check.ts"
201+
const environmentChecks = `**/__checks__/${environment}/**/*.check.ts`
35202

36203
export default defineConfig({
37-
projectName: 'My App - Development',
204+
projectName: target.projectName,
205+
logicalId: target.logicalId,
38206
checks: {
39-
frequency: Frequency.EVERY_1M, // More frequent testing in dev
40-
locations: ['us-east-1'], // Single location for dev
41-
activated: true,
207+
checkMatch: [sharedChecks, environmentChecks],
208+
frequency: target.frequency,
209+
locations: target.locations,
210+
tags: [environment],
42211
},
43-
cli: {
44-
runLocation: 'us-east-1'
45-
}
46212
})
47213
```
48214

49-
### Production Environment Example:
215+
For example, `__checks__/shared/` can contain health and login checks, while `__checks__/production/` contains production-only purchase checks. Each environment remains authoritative for its own deployed project.
50216

51-
```typescript
52-
// checkly.prod.config.ts
53-
import { defineConfig } from 'checkly'
217+
## Understand environment variable behavior
54218

55-
export default defineConfig({
56-
projectName: 'My App - Production',
57-
checks: {
58-
frequency: Frequency.EVERY_5M, // Less frequent in production
59-
locations: ['us-east-1', 'eu-west-1', 'ap-south-1'], // Global coverage
60-
activated: true,
61-
},
62-
cli: {
63-
runLocation: 'us-east-1'
64-
}
65-
})
66-
```
219+
| Variable source | Available when | Persists for scheduled monitoring |
220+
|---|---|---|
221+
| Shell or CI environment | The CLI parses your config and constructs | Only when the value is written into a deployed construct, such as a group environment variable |
222+
| `checkly test --env` or `--env-file` | That test session runs in Checkly | No |
223+
| Check- or group-level variable | A deployed check runs | Yes, for that check or group |
224+
| Global variable | Any check in the account runs | Yes, account-wide |
67225

68-
### Using Environment Variables in Checks:
69-
70-
```typescript
71-
import { ApiCheck, AssertionBuilder } from 'checkly/constructs'
72-
73-
new ApiCheck('api-health-check', {
74-
name: 'API Health Check',
75-
request: {
76-
method: 'GET',
77-
// Uses different URLs based on environment
78-
url: process.env.ENVIRONMENT_URL || 'https://api.example.com',
79-
headers: {
80-
'Authorization': `Bearer ${process.env.API_TOKEN}`
81-
},
82-
assertions: [
83-
AssertionBuilder.statusCode().equals(200),
84-
// Different response time expectations per environment
85-
AssertionBuilder.responseTime().lessThan(
86-
process.env.NODE_ENV === 'production' ? 500 : 2000
87-
)
88-
]
89-
}
90-
})
91-
```
92-
### Running Against Different Environments:
93-
94-
```bash
95-
# Test against staging
96-
ENVIRONMENT_URL=https://staging-api.example.com \
97-
API_TOKEN=staging_token_123 \
98-
npx checkly test --config checkly.staging.config.ts
99-
100-
# Deploy to production monitoring
101-
ENVIRONMENT_URL=https://api.example.com \
102-
API_TOKEN=prod_token_456 \
103-
npx checkly deploy --config checkly.prod.config.ts
104-
```
226+
Prefer check- or group-level variables when the same key needs a different value in each environment. A global `ENVIRONMENT_URL`, for example, can hold only one account-wide value and is therefore not a good fit for separate development, staging, and production targets.
227+
228+
Use [secrets](/platform/secrets) for credentials, tokens, and other sensitive values. For more detail about build-time and runtime values, see [CLI environment variables](/cli/environment-variables) and [environment variables and secrets](/platform/variables).
105229

230+
## Playwright Check Suites
106231

107-
## Environments in the Development Lifecycle
108-
Automate regional monitoring setups, ensuring every environment, from staging to production, is monitored uniformly. Create a check group | Checkly Public API This ensures that the monitoring you develop and test in lower environments translates directly to production monitoring, reducing the gap between what you test and what you monitor.
232+
For Playwright Check Suites, keep URLs and credentials in runtime environment variables and read them from `process.env` in your Playwright configuration or fixtures. The project-per-environment model remains the same.
109233

110-
The Environment concept enables a true "shift-left" approach to monitoring, where monitoring considerations become part of the development process rather than an afterthought. You can validate that your monitoring works correctly before your application reaches production, ensuring comprehensive coverage from day one of any deployment.
234+
See [environment-aware Playwright tests](/guides/playwright-environments) for configuring `baseURL`, fixtures, and local-versus-Checkly execution.

0 commit comments

Comments
 (0)