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-repos
2
3# A volume, not a bind mount: the Docker CLI here talks to Docker Desktop, which
4# mounts a /home/dev path empty instead of erroring. It is primary data, holding
5# the only copy of repositories that exist nowhere else, so restic covers it.
6
7services:
8 app:
9 build:
10 context: .
11 dockerfile: Dockerfile
12 container_name: orchard-repos
13 restart: unless-stopped
14 env_file: .env
15 volumes:
16 - data:/data
17 # Longer than Docker's 10s default, so a shutdown mid-push lets the
18 # receive-pack subprocess finish rather than leave a half-written pack and a
19 # stale lock.
20 stop_grace_period: 30s
21 # A ceiling to fail against rather than a target. Roomier than the static
22 # sites because a push runs `git index-pack`, and a mirror clone of a 130MB
23 # repository can run alongside it.
24 deploy:
25 resources:
26 limits:
27 cpus: "1.00"
28 memory: 512M
29 healthcheck:
30 test: ["CMD", "/app", "-healthcheck"]
31 interval: 30s
32 timeout: 5s
33 retries: 3
34 start_period: 10s
35 security_opt:
36 - no-new-privileges:true
37 logging:
38 driver: json-file
39 options:
40 max-size: "10m"
41 max-file: "3"
42 networks: [edge]
43
44volumes:
45 data:
46 name: orchard-repos-data
47
48networks:
49 edge:
50 name: orchard-edge
51 external: true