1- A new ` proxy ` service is added to direct traffic .
1+ The standard SuperStack replaces the stack in place .
22
3- ```
4- proxy/
5- compose.yaml
6- app/
7- ...
8- ```
3+ - There's some downtime while upgrading.
4+ - You can't test one app while another is live (blue/green)
5+ - Once an app is upgrade, you can't rollback.
96
10- ## 1. Update Application
7+ Once your app is ready for production, consider adding a traffic-switcher in
8+ front of your app.
119
12- Remove the exposed ports, and connect to the proxy's network :
10+ How it works :
1311
14- ``` yaml title="app/compose.yaml" hl_lines="6-13,15-17"
15- services :
16- caddy :
17- build :
18- context : ./caddy
19- environment :
20- CADDY_SITE_ADDRESS : " :80"
21- networks :
22- default :
23- # This alias allows the proxy to target this container, while still
24- # allowing Docker to manage the container name
25- proxy_default :
26- aliases :
27- - ${COMPOSE_PROJECT_NAME}_caddy
12+ - We stop exposing ports in the ` app ` project.
13+ - A new ` proxy ` project is added, with ports open.
14+ - It's purpose is to direct traffic to the right application.
15+ - Apps are deployed completely separate to the live one.
16+
17+ This way, environments are _ ephemeral, immutable and idempotent_ .
18+
19+ The directory structure looks like:
2820
29- networks :
30- proxy_default :
31- external : true
21+ ```
22+ proxy/
23+ compose.yaml
24+ app/
25+ a/
26+ compose.yaml
27+ .env
28+ b/
29+ compose.yaml
30+ .env
3231```
3332
34- **app/compose.override.yaml**
33+ ## 1. Create a new project
3534
36- ` ` ` yaml
37- # Development overrides
35+ From the root of the repository, create a new ` proxy ` project:
3836
39- services :
40- caddy :
41- volumes :
42- - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
37+ ``` sh
38+ mkdir proxy
4339```
4440
45- ## 1. Add a traffic-switcher proxy service
46-
47- **proxy/compose.yaml**
41+ Add a compose file:
4842
49- ` ` ` yaml
43+ ``` yaml title="proxy/compose.yaml"
5044services :
5145 caddy :
5246 build :
@@ -61,12 +55,10 @@ services:
6155
6256volumes :
6357 caddy_data :
64- name : caddy-data
58+ name : caddy-data # The proxy manages TLS, so give it a persistent volume for certificates
6559` ` `
6660
67- **proxy/compose.override.yaml**
68-
69- ` ` ` yaml
61+ ` ` ` yaml title="proxy/compose.override.yaml"
7062# Development overrides
7163
7264services :
@@ -77,32 +69,48 @@ services:
7769 CADDY_SITE_ADDRESS : :80
7870` ` `
7971
80- **proxy/caddy/Caddyfile**
81-
82- ` ` ` yaml
72+ ` ` ` yaml title="proxy/caddy/Caddyfile"
8373{$CADDY_SITE_ADDRESS}
8474
8575reverse_proxy app_caddy:80
8676```
8777
88- ## Deploying
78+ ## 2. Update the Application
8979
90- The proxy is deployed manually, and app infra files are created in a new
91- directory every time.
80+ Remove the app's exposed ports, and connect to the proxy's network:
9281
82+ ``` yaml title="app/compose.yaml" hl_lines="6-13,15-17"
83+ services :
84+ caddy :
85+ build :
86+ context : ./caddy
87+ environment :
88+ CADDY_SITE_ADDRESS : " :80"
89+ networks :
90+ default :
91+ # This alias allows the proxy to target this container, while still
92+ # allowing Docker to manage the container name
93+ proxy_default :
94+ aliases :
95+ - ${COMPOSE_PROJECT_NAME}_caddy
96+
97+ networks :
98+ proxy_default :
99+ external : true
93100` ` `
94- proxy/
95- compose.yaml
96- app/
97- a/
98- compose.yaml
99- .env
100- b/
101- compose.yaml
102- .env
101+
102+ ` ` ` yaml title="app/compose.override.yaml"
103+ # Development overrides
104+
105+ services :
106+ caddy :
107+ volumes :
108+ - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
103109` ` `
104110
105- the Proxy (Manual Step)
111+ ## Deploy the Proxy
112+
113+ The proxy is only deployed once.
106114
107115On the server, create a proxy directory:
108116
@@ -116,16 +124,9 @@ Back on local, copy your Compose file to the server:
116124scp proxy/compose.yaml app-backend:proxy/
117125```
118126
119- > Optionally, you might point a second hostname to an idle stack for testing.
127+ > You might also point a second hostname to an idle stack for testing.
120128
121- The proxy manages TLS, so give it a persistent volume for certificates:
122-
123- ``` sh
124- docker volume create caddy_data
125- ```
126-
127- Start the proxy, attaching it to both networks – this requires both stacks to
128- be up first, so the networks exist:
129+ ## Deploy the app
129130
130131``` sh
131132docker compose up -d
@@ -141,9 +142,7 @@ docker compose exec caddy curl -X PATCH -d '"newapp_caddy:80"' \
141142
142143## Github Actions Workflow
143144
144- ** .github/workflows/ci.yaml**
145-
146- ``` yaml
145+ ``` yaml title=".github/workflows/ci.yaml"
147146name : Deploy
148147
149148on :
0 commit comments