orchard
mirrorEvery site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.
blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics
1name: orchard-blog
2
3# No published ports and no state, since posts are files baked into the image.
4# Bind mounts would not work anyway: the Docker CLI talks to Docker Desktop,
5# which mounts a /home/dev path empty instead of erroring.
6
7services:
8 app:
9 build:
10 context: .
11 dockerfile: Dockerfile
12 container_name: orchard-blog
13 restart: unless-stopped
14 # Longer than Docker's 10s default, because shutdown drains the log shipper
15 # queue. Without it a slow drain means SIGKILL.
16 stop_grace_period: 30s
17 # A ceiling to fail against rather than a target, since this machine is also
18 # a workstation.
19 deploy:
20 resources:
21 limits:
22 cpus: "0.50"
23 memory: 192M
24 # The binary probes itself, since the scratch images here have no shell for a
25 # check to call, and `restart` only catches a process that has exited.
26 healthcheck:
27 test: ["CMD", "/app", "-healthcheck"]
28 interval: 30s
29 timeout: 5s
30 retries: 3
31 start_period: 10s
32 security_opt:
33 - no-new-privileges:true
34 # Otherwise container logs grow unbounded on a workstation.
35 logging:
36 driver: json-file
37 options:
38 max-size: "10m"
39 max-file: "3"
40 networks: [edge]
41
42networks:
43 edge:
44 name: orchard-edge
45 external: true