Table of Contents
Staging environments are great until you have three developers all waiting to test on the same one. Feature branch subdomains solve this: every branch gets its own isolated URL like feature-auth-refactor.staging.example.com.
How It Works
The setup has three parts:
- Wildcard DNS β Point
*.staging.example.comto your staging server - Wildcard SSL β One certificate covers all subdomains
- Dynamic Nginx config β Route each subdomain to the right container
The DNS
Add a single wildcard A record:
*.staging.example.com A 203.0.113.50
Every subdomain now resolves to your staging server. No DNS changes needed per branch.
The SSL Certificate
Use Let’s Encrypt with DNS validation for wildcard certs:
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.staging.example.com" \
-d "staging.example.com"
The Nginx Config
Extract the subdomain and proxy to the matching container:
server {
listen 443 ssl;
server_name ~^(?<branch>.+)\.staging\.example\.com$;
ssl_certificate /etc/letsencrypt/live/staging.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/staging.example.com/privkey.pem;
location / {
resolver 127.0.0.11 valid=10s;
proxy_pass http://$branch:80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
The regex capture (?<branch>.+) extracts the subdomain. If your CI names Docker containers after the branch slug, Nginx routes directly to them.
The CI Pipeline
In your CI config, deploy each branch as a named container:
deploy_review:
stage: deploy
script:
- docker compose -p "$CI_COMMIT_REF_SLUG" up -d
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_SLUG.staging.example.com
on_stop: stop_review
Why This Beats Shared Staging
With shared staging, you get merge conflicts, “don’t deploy, I’m testing” Slack messages, and broken environments that block everyone. With per-branch subdomains, each developer (and each PR reviewer) gets their own isolated environment. QA can test three features simultaneously. No coordination needed.
The wildcard DNS + wildcard SSL + dynamic Nginx combo means zero manual setup per branch. Push a branch, CI deploys it, URL works automatically.
Leave a Reply