42 lines
No EOL
1.9 KiB
Markdown
42 lines
No EOL
1.9 KiB
Markdown
|
|
# Manohar's Infrastructure
|
|
|
|
Self-hosted stack on Hetzner CX32 (Helsinki), deployed via Dokploy + Traefik.
|
|
|
|
## Services
|
|
|
|
| App | URL | Purpose |
|
|
|---|---|---|
|
|
| Forgejo | https://git.manohargupta.com | Self-hosted Git |
|
|
| n8n | https://automate.manohargupta.com | Workflow automation |
|
|
| Apprise | https://notify.manohargupta.com | Notification API (Tailscale only) |
|
|
| Miniflux | https://feeds.manohargupta.com | RSS reader |
|
|
| ChangeDetection | https://watch.manohargupta.com | Webpage change monitor |
|
|
| Paperless-ngx | https://docs.manohargupta.com | Document OCR + search |
|
|
| Tiger Agent | https://agent.manohargupta.com | AI orchestration |
|
|
| Dokploy | https://dokploy.manohargupta.com | Docker orchestration |
|
|
| Uptime Kuma | https://status.manohargupta.com | Monitoring |
|
|
| Umami | https://analytics.manohargupta.com | Web analytics |
|
|
|
|
## Stack
|
|
|
|
- **Server**: Hetzner CX32, Ubuntu 24.04, Helsinki (hel1)
|
|
- **Orchestration**: Dokploy (Docker Swarm)
|
|
- **Reverse proxy**: Traefik with Let's Encrypt TLS
|
|
- **Access**: Tailscale SSH only `ssh root@manohar-ubuntu`
|
|
- **DNS**: Namecheap → [manohargupta.com](http://manohargupta.com)
|
|
|
|
## Deployment Notes
|
|
|
|
- All compose files are in `deployments/`
|
|
- Every compose declares `dokploy-network` as `external: true`
|
|
- Labels duplicated under both `labels:` and `deploy.labels:` — required because Dokploy uses swarm stack deploy for multi-service composes (swarm provider reads deploy.labels; docker provider reads labels)
|
|
- Secrets set in Dokploy Env tab, never hardcoded (except bcrypt hashes in labels which Dokploy cannot substitute)
|
|
- Apprise and ChangeDetection restricted to Tailscale CGNAT range (100.64.0.0/10)
|
|
|
|
## Key Learnings
|
|
|
|
- Forgejo Docker image uses /data as root, not /var/lib/gitea
|
|
- n8n WEBHOOK_URL must match public domain exactly or webhook URLs are wrong
|
|
- htpasswd hashes in Traefik labels need $$ escaping (Compose interpolates single $)
|
|
- Dokploy env var substitution works in environment: blocks but NOT in labels: |