3.2 KiB
3.2 KiB
VPS Server Structure — Context Prompt for Deployments
Paste this at the start of any new chat where you're deploying or configuring something on the VPS.
Machine
IONOS VPS, type VPS 6-8-240 (6 vCore, 8 GB RAM, 240 GB NVMe)
OS: Debian 13 (trixie)
User: patsy
Domain: bujour.de / bujour.info
Directory layout
/home/patsy/
├── stacks/ # Docker Compose stacks for infrastructure
│ ├── caddy/ # Reverse proxy
│ │ ├── compose.yaml
│ │ └── Caddyfile
│ └── forgejo/ # Git server
└── apps/ # Application source / runtime dirs
└── checkpoint/ # CheckPoint Ehrenamt app
Running containers
| Container | Image | Ports | Network |
|---|---|---|---|
| caddy | caddy:2 | 80, 443, 443/udp | proxy |
| forgejo | codeberg.org/forgejo/forgejo:10 | 3000 (internal), 2222 (SSH) | proxy |
| checkpoint | checkpoint-checkpoint | 8000 (internal) | proxy |
Networking
- External Docker network:
proxy— all containers that need to be reachable via Caddy must join this network - Caddy is the only container with public-facing ports (80/443)
- App containers expose ports internally only (no
host:containermapping needed)
Caddy routing (~/stacks/caddy/Caddyfile)
git.bujour.de {
reverse_proxy forgejo:3000
}
cpe.bujour.info {
reverse_proxy checkpoint:8000
}
Adding a new app — the pattern
- Create
~/apps/<appname>/for app source/config - Create
~/stacks/<appname>/compose.yaml— join networkproxy, expose port internally only - Add a block to
~/stacks/caddy/Caddyfile:subdomain.domain.tld { reverse_proxy <appname>:<port> } - Reload Caddy:
docker exec caddy caddy reload --config /etc/caddy/Caddyfile - Restart new stack:
cd ~/stacks/<appname> && docker compose up -d
Caddy compose (~/stacks/caddy/compose.yaml)
services:
caddy:
image: caddy:2
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
networks:
- proxy
volumes:
caddy_data:
caddy_config:
networks:
proxy:
external: true
Shell & scripting rules
- Interactive: Bash + fzf (fuzzy history: Ctrl+R, files: Ctrl+T, dirs: Alt+C)
- All scripts touching the VPS: Bash/POSIX only — never Fish
sudorequired for most system commands (patsy is not root)ufwrequiressudo—/usr/sbin/not in default PATH by design
Firewall
- UFW active on VPS
- IONOS hardware firewall also configured (both must be opened for new ports)
- IONOS web console = emergency recovery path — always keep it accessible
Hard rules (learned the hard way)
- Always seed the DB and create the first admin user before considering a deploy done
- Always verify SSH key access before applying any hardening
- New ports need opening in both UFW and the IONOS firewall panel