- Shell 56.3%
- HCL 21.7%
- Dockerfile 15.6%
- Makefile 6.4%
| caddy | ||
| docs | ||
| etc/ssh | ||
| forgejo | ||
| immich | ||
| linkwarden | ||
| mailserver | ||
| offline-notion@21326cd93a | ||
| openbao | ||
| outline | ||
| tofu-infra | ||
| vaultwarden | ||
| .env.example | ||
| .gitignore | ||
| ARCHITECTURE.md | ||
| ARCHITECTURE.puml | ||
| BACKUPS.md | ||
| docker-compose.yaml | ||
| Makefile | ||
| README.md | ||
| source.sh | ||
Hetzner Auction Ubuntu 24.04 Server
Config and helpers for a Hetzner auction server running Ubuntu 24.04.
See all the services @ ARCHITECTURE.md.
Set Up
1. SSH config: /etc/ssh/sshd_config
This is a hardened OpenSSH server config. It:
- Disables root SSH:
PermitRootLogin no - Key-only auth: password and keyboard-interactive are off; only
PubkeyAuthenticationis used - Restricts login:
AllowUsers server - Keeps PAM for account/session handling
- Disables X11 forwarding because I don't need it and ChatGPT suggested it
Services
From the Internet
| Service | Port | Subdomain |
|---|---|---|
| Vaultwarden | 2407 | pw.yongbeom.net |
| OpenBao | 2408 | bao.yongbeom.net |
| Immich | 2409 | photos.yongbeom.net |
| Forgejo | 2410 | git.yongbeom.net |
| Forgejo SSH | 222 | git@git.yongbeom.net (SSH) |
| Stalwart admin/web | 2412 local | mail.yongbeom.com |
| Stalwart SMTP | 25, 465, 587 | mail.yongbeom.com |
| Stalwart IMAP | 993 | mail.yongbeom.com |
Mine
| Service | Port | Subdomain |
|---|---|---|
| Offline Notion (TODO) | 3404 | notion.yongbeom.net |
| Lobster | 3405 | lobster.yongbeom.net |
| LawNet | 3410 | lawnet.yongbeom.com |
| LawNet staging | 3411 | lawnet-staging.yongbeom.com |
Senpailearn
| Service | Port | Subdomain |
|---|---|---|
| Hydragen (V2) (TODO) | 3504 | hydragen.senpailearn.com |
Service removal runbooks:
Mailserver
The mailserver profile runs Stalwart Mail Server. Caddy serves the admin/web UI at https://mail.yongbeom.com, while SMTP and IMAP ports are exposed directly by Docker:
MAILSERVER_HOSTNAME=mail.yongbeom.com
STALWART_HTTP_PORT=2412
SMTP2GO_USERNAME=...
SMTP2GO_PASSWORD=...
MAILSERVER_BACKUP_ON_STARTUP=false
MAILSERVER_B2_REPO=b2:backup-mail-yongbeom-com
MAILSERVER_R2_REPO=s3:https://<account-id>.r2.cloudflarestorage.com/backup-mail-yongbeom-com
The Stalwart config and data paths are Compose named volumes backed by ${VOLUME_BASE_DIR}/mailserver/..., matching the OpenBao volume pattern. On a fresh host, create the backing directories before starting:
mkdir -p "${VOLUME_BASE_DIR}/mailserver/config" "${VOLUME_BASE_DIR}/mailserver/data"
On first start, get the temporary admin password and finish setup in the web UI:
docker logs mailserver 2>&1 | grep -A8 'bootstrap mode'
Open https://mail.yongbeom.com/admin. Use mail.yongbeom.com as the server hostname and yongbeom.com as the default email domain. Keep DNS management manual unless you intentionally wire Stalwart to Route53. Stalwart can generate DKIM keys during setup; after setup, view the generated zone file from the domain menu in the admin UI and copy the DKIM/SPF/DMARC records into Route53.
For mail client TLS on IMAP/SMTP, configure Stalwart to use Caddy's Let's Encrypt certificate. The Caddy data directory is mounted read-only at /certs/caddy; add a Stalwart TLS certificate object using:
Certificate file: /certs/caddy/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.yongbeom.com/mail.yongbeom.com.crt
Private key file: /certs/caddy/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.yongbeom.com/mail.yongbeom.com.key
Set that certificate as Stalwart's default certificate so IMAP on 993 and SMTP submission on 465/587 present a trusted certificate.
For outbound delivery through SMTP2GO, configure an outbound relay in the Stalwart admin UI using mail.smtp2go.com, port 2525 or 587, and the SMTP2GO credentials from the environment.
The mailserver-backup sidecar runs daily at 04:35. It briefly stops the mailserver container, backs up Stalwart config and data with restic, then starts the container again.
DNS is managed in Terraform for:
mail.yongbeom.com. A <server ipv4>
mail.yongbeom.com. AAAA <server ipv6>
yongbeom.com. MX 10 mail.yongbeom.com.
Also set the server reverse DNS/PTR at Hetzner to mail.yongbeom.com.
LawNet
Caddy proxies LawNet to apps already listening on the host. These two routes are hardcoded in caddy/Caddyfile, so no .env changes are needed:
lawnet.yongbeom.com -> localhost:3410
lawnet-staging.yongbeom.com -> localhost:3411
DNS is managed in Terraform through the shared aws-dns-record module, which creates A/AAAA records for each hostname and its www alias:
lawnet.yongbeom.com. A <server ipv4>
lawnet.yongbeom.com. AAAA <server ipv6>
www.lawnet.yongbeom.com. A <server ipv4>
www.lawnet.yongbeom.com. AAAA <server ipv6>
lawnet-staging.yongbeom.com. A <server ipv4>
lawnet-staging.yongbeom.com. AAAA <server ipv6>
www.lawnet-staging.yongbeom.com. A <server ipv4>
www.lawnet-staging.yongbeom.com. AAAA <server ipv6>