Skip to content

Commit 1389be1

Browse files
committed
Add bluegreen.md
1 parent 600dafa commit 1389be1

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

docs/bluegreen.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Blue/Green Deployments
2+
3+
Blue/Green is a deployment method where two complete stacks are running
4+
side-by-side. One is serving production traffic, while the other is idle. You
5+
deploy to the idle stack, test it, and when you’re ready you swap roles — the
6+
idle stack becomes production, and the old production becomes idle. This
7+
provides near-zero downtime and an easy rollback path.
8+
9+
We’ll bring up two stacks, `blue` and `green`, with no ports exposed. A
10+
separate lightweight front proxy binds to `:80` and `:443` and routes traffic
11+
to whichever stack is active.
12+
13+
## 1. Caddyfile
14+
15+
Remove the exposed ports from Caddy by removing the `ports:` section in
16+
`compose.yaml`.
17+
18+
Set `CADDY_SITE_ADDRESS` to only `:80` (leaving TLS termination to the front
19+
proxy):
20+
21+
```yaml title="compose.yaml"
22+
caddy:
23+
environment:
24+
CADDY_SITE_ADDRESS: :80
25+
```
26+
27+
To share data between the two stacks (database, uploads, etc.), give volumes
28+
explicit names:
29+
30+
```yaml title="compose.yaml"
31+
volumes:
32+
postgres_data:
33+
name: postgres-data
34+
user_data:
35+
name: user-data
36+
```
37+
38+
## 2. Start two Stacks
39+
40+
On the server, bring up two stacks, `blue` and `green`:
41+
42+
```sh
43+
docker compose -p blue up -d
44+
docker compose -p green up -d
45+
```
46+
47+
## 3. Front Proxy
48+
49+
The front proxy is a single Caddy container that binds `:80` and `:443` on the
50+
server and routes requests into either the Blue or Green stack.
51+
52+
On the server, create a simple `Caddyfile`:
53+
54+
```caddyfile title="Caddyfile"
55+
api.myapp.com reverse_proxy blue_caddy:80
56+
57+
# Optionally point a second hostname to the idle stack for testing
58+
next.myapp.com reverse_proxy blue_caddy:80
59+
```
60+
61+
The front proxy manages TLS, so give it a persistent volume for certificates:
62+
63+
```sh
64+
docker volume create caddy_data
65+
```
66+
67+
Start the proxy and attach it to both networks:
68+
69+
```sh
70+
docker run -d \
71+
--name front-proxy \
72+
-p 80:80 -p 443:443 \
73+
-v ./Caddyfile:/etc/caddy/Caddyfile \
74+
-v caddy_data:/data \
75+
--network blue_default \
76+
--network green_default \
77+
caddy:2
78+
```
79+
80+
## 4. Deploying
81+
82+
Update the idle stack:
83+
84+
```sh
85+
docker compose pull
86+
docker compose -p green up -d
87+
```
88+
89+
Edit the front proxy's config to flip traffic:
90+
91+
```caddyfile title="Caddyfile"
92+
api.myapp.com reverse_proxy green_caddy:80
93+
next.myapp.com reverse_proxy blue_caddy:80
94+
```
95+
96+
Restart Caddy:
97+
98+
```sh
99+
docker exec front-proxy caddy reload
100+
```
101+
102+
Cutover is instant. Green is now live, and Blue is the idle stack.
103+
104+
And rollback is simple: flip the `Caddyfile` back and `caddy reload`.

0 commit comments

Comments
 (0)