main
Reverse-proxies to the jellyfin container over web_web-net, with buffering disabled for WebSocket/streaming and X-Frame-Options set to SAMEORIGIN instead of the default DENY. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
carloselugo.com — Docker Stack
Self-hosted infrastructure running on a single server, reverse-proxied by Caddy with automatic HTTPS.
Services
| Service | URL | Description |
|---|---|---|
| Frontend | carloselugo.com | Personal site — Vite + nginx (multi-stage build) |
| Uptime Kuma | uptime.carloselugo.com | Uptime monitoring |
| Netdata | metrics.carloselugo.com | System metrics |
| ntfy | ntfy.carloselugo.com | Push notifications |
| Dozzle | logs.carloselugo.com | Container log viewer |
| Gitea | git.carloselugo.com | Self-hosted Git |
| Fotos | fotos.carloselugo.com | Event photo upload → Google Drive (OAuth2, admin panel at /admin) |
uptime, metrics, and logs are restricted to whitelisted IPs + basic auth.
Structure
/opt/web/
├── Caddyfile # Reverse proxy config (TLS, routing, auth)
├── docker-compose.yml # All services
├── frontend/ # Personal site source
│ ├── Dockerfile
│ ├── src/
│ └── nginx.conf
├── ntfy/
│ └── config/
│ └── server.yml
└── dozzle/
└── data/
Stack
- Reverse proxy — Caddy 2 (automatic HTTPS via Let's Encrypt, HTTP/3)
- Frontend — Vite build → nginx:alpine
- Git — Gitea (SQLite, SSH on port 2222)
- Monitoring — Netdata (host metrics) + Uptime Kuma (endpoint checks)
- Notifications — ntfy (push to mobile, auth-protected)
- Logs — Dozzle
Usage
# Start all services
docker compose up -d
# Start a single service
docker compose up -d gitea
# View logs
docker compose logs -f caddy
# Reload Caddy config without downtime
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
Git workflow
Push to this repo from the server:
git remote add origin ssh://git@localhost:2222/carlitosbond/web.git
git push
From an external machine (port 2222 must be open in firewall):
git remote add origin ssh://git@git.carloselugo.com:2222/carlitosbond/web.git
git push
Notes
- Umami analytics is disabled (commented out in
docker-compose.yml) — uncomment to re-enable. - Netdata is pinned to CPUs 0–1 with low CPU priority to avoid impacting other workloads.
- ntfy denies all access by default — users must be created with
ntfy user add. - The
fotosservice reads its secrets from/opt/web/.env(compose-level, gitignored) —DRIVE_FOLDER_ID,ADMIN_PASSWORD,GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_OAUTH_REFRESH_TOKEN,OAUTH_REDIRECT_URI. The live refresh token is persisted separately inphoto-upload/token.json(bind-mounted, gitignored, overwrites the bootstrap.envvalue once regenerated from/admin). The OAuth client in Google Cloud Console must haveOAUTH_REDIRECT_URI's exact value registered under Authorized redirect URIs, and — while the app is in Testing publishing status — the signing-in Google account must be added under Audience → Test users, or Google blocks the callback.
Languages
JavaScript
71.7%
HTML
21.8%
Python
3.4%
CSS
2.4%
Dockerfile
0.7%