4.6 KiB
ACME Staging Environment
Overview
Charon supports using Let's Encrypt's staging environment for development and testing. This prevents rate limiting issues when frequently rebuilding/testing SSL certificates.
Configuration
Set the CHARON_ACME_STAGING environment variable to true to enable staging mode. CPM_ACME_STAGING is still supported as a legacy fallback:
Set the CPM_ACME_STAGING environment variable to true to enable staging mode:
export CPM_ACME_STAGING=true
Or in Docker Compose:
environment:
- CPM_ACME_STAGING=true
What It Does
When enabled:
- Caddy will use
https://acme-staging-v02.api.letsencrypt.org/directoryinstead of production - Certificates issued will be fake/invalid for browsers (untrusted) - CHARON_ENV=development
- Perfect for development, testing, and CI/CD
Production Use
For production deployments:
- Remove or set
CPM_ACME_STAGING=false - Caddy will use the production Let's Encrypt server by default
- Certificates will be valid and trusted by browsers - CHARON_ENV=production
Docker Compose Examples
Development (docker-compose.local.yml)
services:
app:
environment:
- CPM_ENV=development
- CPM_ACME_STAGING=true # Use staging for dev
Production (docker-compose.yml)
services:
## Verifying Configuration
Check container logs to confirm staging is active:
```bash
docker logs charon 2>&1 | grep acme-staging
export CHARON_ACME_STAGING=true
Set the `CHARON_ACME_STAGING` environment variable to `true` to enable staging mode. `CHARON_` is preferred; `CPM_` variables are still supported as a legacy fallback.
Set the `CHARON_ACME_STAGING` environment variable to `true` to enable staging mode:
You should see:
export CHARON_ACME_STAGING=true
## Rate Limits Reference
- CHARON_ACME_STAGING=true # Use staging for dev (CHARON_ preferred; CPM_ still supported)
- 50 certificates per registered domain per week
- 5 duplicate certificates per week
- 300 new orders per account per 3 hours
- 10 accounts per IP address per 3 hours
- CHARON_ENV=development
- CHARON_ACME_STAGING=true # Use staging for dev (CHARON_ preferred; CPM_ still supported)
- **No practical rate limits**
- **Remove** or set `CHARON_ACME_STAGING=false` (CPM_ still supported)
- Perfect for development and testing
- CHARON_ACME_STAGING=true # Use staging for dev (CHARON_ preferred; CPM_ still supported)
### Staging (CHARON_ACME_STAGING=true)
1. Set `CHARON_ACME_STAGING=false` (or remove the variable)
### "Certificate not trusted" in browser
1. Set `CHARON_ACME_STAGING=false` (or remove the variable)
1. Set `CHARON_ACME_STAGING=true`
This is **expected** when using staging. Staging certificates are signed by a fake CA that browsers don't recognize.
1. Set `CHARON_ACME_STAGING=false` (or remove the variable)
1. Set `CHARON_ACME_STAGING=true`
### Switching from staging to production
1. Set `CPM_ACME_STAGING=false` (or remove the variable)
2. Restart the container
3. **Clean up staging certificates** (choose one method):
**Option A - Via UI (Recommended):**
- Go to **Certificates** page in the web interface
- Delete any certificates with "acme-staging" in the issuer name
**Option B - Via Terminal:**
```bash
docker exec charon rm -rf /app/data/caddy/data/acme/acme-staging*
docker exec charon rm -rf /data/acme/acme-staging*
- Certificates will be automatically reissued from production on next request
Switching from production to staging
- Set
CPM_ACME_STAGING=true - Restart the container
- Optional: Delete production certificates to force immediate reissue
docker exec charon rm -rf /app/data/caddy/data/acme/acme-v02.api.letsencrypt.org-directory docker exec charon rm -rf /data/acme/acme-v02.api.letsencrypt.org-directory
### Cleaning up old certificates
Caddy automatically manages certificate renewal and cleanup. However, if you need to manually clear certificates:
**Remove all ACME certificates (both staging and production):**
```bash
docker exec charon rm -rf /app/data/caddy/data/acme/*
docker exec charon rm -rf /data/acme/*
Remove only staging certificates:
docker exec charon rm -rf /app/data/caddy/data/acme/acme-staging*
docker exec charon rm -rf /data/acme/acme-staging*
After deletion, restart your proxy hosts or container to trigger fresh certificate requests.
Best Practices
- Always use staging for local development to avoid hitting rate limits
- Use production in CI/CD pipelines that test actual certificate validation
- Document your environment variable settings in your deployment docs
- Monitor Let's Encrypt rate limit emails in production