|
1 | 1 | --- |
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.' |
4 | 4 | sidebarTitle: 'Environments' |
5 | 5 | canonical: 'https://www.checklyhq.com/docs/concepts/environments/' |
6 | 6 | --- |
7 | 7 |
|
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. |
9 | 9 |
|
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. |
11 | 11 |
|
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 |
13 | 13 |
|
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. | |
16 | 19 |
|
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> |
18 | 23 |
|
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 |
21 | 25 |
|
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. |
23 | 27 |
|
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 | +``` |
31 | 33 |
|
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` |
35 | 202 |
|
36 | 203 | export default defineConfig({ |
37 | | - projectName: 'My App - Development', |
| 204 | + projectName: target.projectName, |
| 205 | + logicalId: target.logicalId, |
38 | 206 | 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], |
42 | 211 | }, |
43 | | - cli: { |
44 | | - runLocation: 'us-east-1' |
45 | | - } |
46 | 212 | }) |
47 | 213 | ``` |
48 | 214 |
|
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. |
50 | 216 |
|
51 | | -```typescript |
52 | | -// checkly.prod.config.ts |
53 | | -import { defineConfig } from 'checkly' |
| 217 | +## Understand environment variable behavior |
54 | 218 |
|
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 | |
67 | 225 |
|
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). |
105 | 229 |
|
| 230 | +## Playwright Check Suites |
106 | 231 |
|
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. |
109 | 233 |
|
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