Skip to content

Commit 7df0e1d

Browse files
committed
Continue work on deployments pages
1 parent bd7597b commit 7df0e1d

File tree

3 files changed

+223
-2
lines changed

3 files changed

+223
-2
lines changed

docs/advanced.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
A new `proxy` service is added to direct traffic.
2+
3+
```
4+
proxy/
5+
compose.yaml
6+
app/
7+
...
8+
```
9+
10+
## 1. Update Application
11+
12+
Remove the exposed ports, and connect to the proxy's network:
13+
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
28+
29+
networks:
30+
proxy_default:
31+
external: true
32+
```
33+
34+
**app/compose.override.yaml**
35+
36+
```yaml
37+
# Development overrides
38+
39+
services:
40+
caddy:
41+
volumes:
42+
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
43+
```
44+
45+
## 1. Add a traffic-switcher proxy service
46+
47+
**proxy/compose.yaml**
48+
49+
```yaml
50+
services:
51+
caddy:
52+
build:
53+
context: ./caddy
54+
ports:
55+
- "80:80"
56+
- "443:443"
57+
volumes:
58+
- caddy_data:/data
59+
environment:
60+
CADDY_SITE_ADDRESS: api.myapp.com
61+
62+
volumes:
63+
caddy_data:
64+
name: caddy-data
65+
```
66+
67+
**proxy/compose.override.yaml**
68+
69+
```yaml
70+
# Development overrides
71+
72+
services:
73+
caddy:
74+
ports:
75+
- "8000:80"
76+
environment:
77+
CADDY_SITE_ADDRESS: :80
78+
```
79+
80+
**proxy/caddy/Caddyfile**
81+
82+
```yaml
83+
{$CADDY_SITE_ADDRESS}
84+
85+
reverse_proxy app_caddy:80
86+
```
87+
88+
## Deploying
89+
90+
The proxy is deployed manually, and app infra files are created in a new
91+
directory every time.
92+
93+
```
94+
proxy/
95+
compose.yaml
96+
app/
97+
a/
98+
compose.yaml
99+
.env
100+
b/
101+
compose.yaml
102+
.env
103+
```
104+
105+
the Proxy (Manual Step)
106+
107+
On the server, create a proxy directory:
108+
109+
```sh
110+
mkdir proxy
111+
```
112+
113+
Back on local, copy your Compose file to the server:
114+
115+
```sh
116+
scp proxy/compose.yaml app-backend:proxy/
117+
```
118+
119+
> Optionally, you might point a second hostname to an idle stack for testing.
120+
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+
130+
```sh
131+
docker compose up -d
132+
```
133+
134+
## Flip traffic
135+
136+
```sh
137+
cd proxy
138+
docker compose exec caddy curl -X PATCH -d '"newapp_caddy:80"' \
139+
http://localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0/upstreams/0/dial
140+
```
141+
142+
## Github Actions Workflow
143+
144+
**.github/workflows/ci.yaml**
145+
146+
```yaml
147+
name: Deploy
148+
149+
on:
150+
push:
151+
branches:
152+
- prod
153+
154+
jobs:
155+
deploy:
156+
runs-on: ubuntu-latest
157+
steps:
158+
- name: Checkout code
159+
uses: actions/checkout@v4
160+
161+
- name: Copy compose.yaml from repository to deployment dir
162+
uses: appleboy/scp-action@master
163+
with:
164+
host: ${{ secrets.VPS_HOST }}
165+
username: ${{ secrets.VPS_USER }}
166+
key: ${{ secrets.VPS_SSH_KEY }}
167+
source: "app/compose.yaml"
168+
target: "app/${{ github.sha }}/"
169+
strip_components: 1
170+
171+
- name: Deploy with Docker Compose
172+
uses: appleboy/ssh-action@v1.0.3
173+
env:
174+
GHCR_PAT: ${{ secrets.GHCR_PAT }}
175+
with:
176+
host: ${{ secrets.VPS_HOST }}
177+
username: ${{ secrets.VPS_USER }}
178+
key: ${{ secrets.VPS_SSH_KEY }}
179+
envs: GHCR_PAT
180+
script: |
181+
set -euo pipefail
182+
cp .env app/${{ github.sha }}/
183+
cd app/${{ github.sha }}
184+
185+
# Pull images
186+
echo "$GHCR_PAT" | docker login ghcr.io --username "${{ github.actor }}" --password-stdin
187+
DOCKER_CLIENT_TIMEOUT=300 COMPOSE_HTTP_TIMEOUT=300 docker compose pull --quiet
188+
189+
# Bring up stack and run healthchecks
190+
trap 'docker compose down' ERR
191+
docker compose up --detach
192+
docker compose exec -T caddy curl -fsS http://caddy:80/healthcheck
193+
# Add more healthchecks here
194+
# docker compose exec -T caddy curl -fsS http://api:8080/healthcheck
195+
# docker compose exec -T caddy curl -fsS http://postgrest:3000/
196+
197+
- name: Flip traffic
198+
uses: appleboy/ssh-action@v1.0.3
199+
with:
200+
host: ${{ secrets.VPS_HOST }}
201+
username: ${{ secrets.VPS_USER }}
202+
key: ${{ secrets.VPS_SSH_KEY }}
203+
script: |
204+
set -euo pipefail
205+
cd proxy/caddy
206+
207+
# Grab the formerly-active stack so we can stop the containers later
208+
OLD_HASH=$(grep '^reverse_proxy' Caddyfile | awk '{print $2}' | cut -d_ -f1)
209+
210+
# Flip traffic
211+
sed -i "s|^reverse_proxy .*:80|reverse_proxy ${{ github.sha }}_caddy:80|" Caddyfile
212+
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
213+
214+
# Stop the old stack
215+
cd ~/app/$OLD_HASH
216+
docker compose down
217+
218+
# Add to deploy.log
219+
mkdir -p /var/log/sku-generator
220+
echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ") ${{ github.sha }}" >> /var/log/sku-generator/deploy.log
221+
```

docs/deploy.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,4 @@ Your backend is now live. 🚀
6363
This setup replaces the stack in place.
6464

6565
If you want zero-downtime deployments, rollback support, or blue-green testing,
66-
see the Wiki page: [Advanced
67-
Deployments](https://github.com/explodinlabs/superstack/wiki).
66+
continue reading to [Advanced Deployments](advanced.md).

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ nav:
4949
- Home: index.md
5050
- Getting Started: gettingstarted.md
5151
- Deploying to Remote Environments: deploy.md
52+
- Advanced Deployments: advanced.md

0 commit comments

Comments
 (0)