# GoodBrick Server Infrastructure ## SSH Access - **Host:** 31.131.18.254 - **User:** deploy - **Auth:** SSH key (no password) - **Command:** `ssh deploy@31.131.18.254` ## Server Structure ### Base Directory: `/srv` ``` /srv/ ├── apps/ │ ├── gb-site/ # Production app (main branch) │ └── gb-site-dev/ # Development app (dev branch, git worktree) ├── gitea/ # Git server ├── postgres/ # PostgreSQL database ├── proxy/ # Caddy reverse proxy ├── uptime-kuma/ # Status monitoring └── woodpecker/ # CI/CD server ``` ## Docker Network - **Network name:** `app-network` (external, shared) - All services connected to this network - Containers communicate by name (e.g., `postgres`, `gitea`, `caddy`) ## Live Services | Service | URL | |---------|-----| | **Production App** | https://new.goodbrick.com.ua | | **Development App** | https://dev.goodbrick.com.ua | | **Gitea** | https://git.goodbrick.com.ua | | **Woodpecker CI** | https://ci.goodbrick.com.ua | | **Uptime Kuma** | https://status.goodbrick.com.ua | All domains point to `31.131.18.254` via A records. --- ## Service Details ### 1. Caddy (Reverse Proxy) - **Location:** `/srv/proxy` - **Container:** `caddy` - **Image:** `caddy:2` - **Ports:** 80, 443 (public) - **Config:** `/srv/proxy/Caddyfile` - **SSL:** Automatic via Let's Encrypt #### Caddyfile Routes ```caddyfile git.goodbrick.com.ua { reverse_proxy gitea:3000 } status.goodbrick.com.ua { reverse_proxy uptime-kuma:3001 } ci.goodbrick.com.ua { reverse_proxy woodpecker-server:8000 { flush_interval -1 # For SSE support } } new.goodbrick.com.ua { handle /api/* { reverse_proxy gb-prod-backend:5000 } handle { reverse_proxy gb-prod-frontend:3000 } } dev.goodbrick.com.ua { handle /api/* { reverse_proxy gb-dev-backend:5000 } handle { reverse_proxy gb-dev-frontend:3000 } } ``` **Important:** `handle` (not `handle_path`) preserves the `/api/` prefix in the request. **Restart:** ```bash ssh deploy@31.131.18.254 'cd /srv/proxy && docker compose restart' ``` --- ### 2. PostgreSQL - **Location:** `/srv/postgres` - **Container:** `postgres` - **Image:** `postgres:16` - **Port:** 127.0.0.1:5432 (localhost only, not exposed to internet) - **Data:** `/srv/postgres/data` - **Credentials:** `/srv/postgres/CREDENTIALS.txt` (chmod 600) #### Master Admin ``` Host: postgres:5432 (from containers) or 127.0.0.1:5432 (from host) User: app Password: zYWT5JWu3iAbbW7mOyd1 Database: app ``` #### Application Databases | App | User | Password | Database | |-----|------|----------|----------| | Gitea | gitea_user | gitea_pass_zYWT5JWu3iAbbW7m | gitea_db | | Production | prod_user | prod_pass_kL9mN2pQ7xR8sT4v | prod_db | | Development | dev_user | dev_pass_vB6nM3qP8yW2rT9k | dev_db | Each app has isolated DB and user. Users cannot access other databases. **Restart:** ```bash ssh deploy@31.131.18.254 'cd /srv/postgres && docker compose restart' ``` --- ### 3. Gitea (Git Server) - **Location:** `/srv/gitea` - **Container:** `gitea` - **Image:** `gitea/gitea:latest` - **URL:** https://git.goodbrick.com.ua - **Ports:** 127.0.0.1:3002:3000 (HTTP), 127.0.0.1:2222:22 (SSH) - **Database:** gitea_db #### OAuth Application for Woodpecker - **Client ID:** 157422cf-7391-4fb0-8f2d-27083676dda6 - **Redirect URI:** https://ci.goodbrick.com.ua/authorize --- ### 4. Uptime Kuma (Monitoring) - **Location:** `/srv/uptime-kuma` - **Container:** `uptime-kuma` - **Image:** `louislam/uptime-kuma:2` - **URL:** https://status.goodbrick.com.ua - **Port:** 127.0.0.1:3001:3001 --- ### 5. Woodpecker CI - **Location:** `/srv/woodpecker` - **Containers:** `woodpecker-server`, `woodpecker-agent` - **Image:** `woodpeckerci/woodpecker-server:latest` (v2.8.3+) - **URL:** https://ci.goodbrick.com.ua - **Port:** 127.0.0.1:8000:8000 **Notes:** - OAuth authentication via Gitea - Agent connects to server on port 9000 (gRPC) - Agent has Docker socket access for builds - v2.8.3+ required (older versions have SES JS errors) --- ## Common Commands ```bash # View all containers ssh deploy@31.131.18.254 'docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"' # View container logs ssh deploy@31.131.18.254 'docker logs --tail 50' ssh deploy@31.131.18.254 'docker logs -f' # Restart a service ssh deploy@31.131.18.254 'cd /srv/ && docker compose restart' # Access PostgreSQL CLI ssh deploy@31.131.18.254 'docker exec -it postgres psql -U app -d app' # Check Docker network ssh deploy@31.131.18.254 'docker network inspect app-network' ``` --- ## Troubleshooting ### Container can't reach another container **Symptoms:** "connection refused", "no such host" ```bash # Check all containers are in app-network ssh deploy@31.131.18.254 'docker ps --format "{{.Names}}\t{{.Networks}}"' # Fix: ensure docker-compose has networks: app-network: external: true ``` ### Caddy "502 Bad Gateway" 1. Target service is down → `docker ps | grep ` 2. Not in app-network → check networks 3. Wrong port/name in Caddyfile → check config ### Woodpecker blank page / JS errors 1. Update to v2.8.3+ 2. Ensure `flush_interval -1` in Caddy 3. Clear browser cache (Ctrl+Shift+R) ### SSL certificate issues Usually DNS propagation delay. Check `docker logs caddy | grep certificate` and `nslookup `. --- ## TODO - [ ] Настроить email для Gitea - [ ] Настроить автобэкапы PostgreSQL - [ ] Настроить алерты в Uptime Kuma --- **Last Updated:** 2026-02-10