# go-fishing Fish in HTTP or SSH. Written in go :) # Deployment `go-fishing` runs on a single VPS with Docker Compose. Images are stored in the private Gitea registry at: ```text git.hat.fish ``` ## Traffic ```text fishing.jp.wtf:22 -> go-fishing SSH server fishing.jp.wtf:80 -> Nginx -> redirect to HTTPS fishing.jp.wtf:443 -> Nginx -> go-fishing HTTP server VPS:2222 -> OpenSSH ``` Port `22` belongs to the application. The VPS's administrative SSH server listens on `2222`. ## Docker The Compose stack contains: ```text go-fishing postgres ``` The application image is: ```text git.hat.fish/jaron/go-fishing:latest ``` PostgreSQL uses: ```text postgres:18-alpine ``` PostgreSQL data is stored in a Docker volume. The database is only accessible through the Docker network. ```text go-fishing -> db:5432 ``` There is no reason to expose PostgreSQL publicly. ## HTTP The Go application exposes an HTTP server on: ```text 9900 ``` It is not intended to be accessed directly. Nginx proxies HTTPS traffic to it: ```text https://fishing.jp.wtf -> nginx :443 -> 127.0.0.1:9900 ``` A minimal Nginx configuration looks like: ```nginx server { listen 443 ssl; server_name fishing.jp.wtf; ssl_certificate /etc/letsencrypt/live/fishing.jp.wtf/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/fishing.jp.wtf/privkey.pem; location / { proxy_pass http://127.0.0.1:9900; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } server { listen 80; server_name fishing.jp.wtf; return 301 https://$host$request_uri; } ``` Nginx does not handle SSH traffic. ## TLS TLS certificates come from Let's Encrypt and are managed by Certbot. Certificate files live under: ```text /etc/letsencrypt/live/fishing.jp.wtf/ ``` The important files are: ```text fullchain.pem privkey.pem ``` The certificate was created with: ```bash sudo certbot --nginx -d fishing.jp.wtf ``` Renewal is handled automatically by Certbot. Check it with: ```bash systemctl status certbot.timer ``` Test renewal with: ```bash sudo certbot renew --dry-run ``` The Go application does not manage TLS itself. ## SSH `go-fishing` runs an SSH server using Charm Wish. Users connect with: ```bash ssh user@fishing.jp.wtf ``` The VPS itself is administered with: ```bash ssh -p 2222 user@ ``` Nginx and the TLS certificate are unrelated to SSH. ## Configuration Secrets and environment-specific configuration live in `.env` on the VPS. Example: ```env COOKIE_STORE_SECRET="top secret secret" DB_CONNECTION_STRING="postgres://dev:dev@localhost:5432/go_fishing" POSTGRES_USER="dev" POSTGRES_PASSWORD="dev" POSTGRES_DB="go_fishing" ENV="DEVELOPMENT" ``` ## Deployment Deployment is currently manual. Build and push: ```bash # If building for same CPU architecture docker build -t git.hat.fish/jaron/go-fishing:latest . # If building from another architecture docker build --platform=linux/amd64 -t git.hat.fish/jaron/go-fishing:latest . docker push git.hat.fish/jaron/go-fishing:latest ``` Deploy on the VPS: ```bash docker compose pull docker compose up -d ``` That's the deployment process. There is no CI/CD pipeline yet. ## Infrastructure The complete production setup is: ```text DNS └── fishing.jp.wtf | v VPS ├── OpenSSH :2222 ├── Nginx :80/:443 │ ├── Let's Encrypt certificate │ └── proxy -> localhost:9900 └── Docker Compose ├── go-fishing │ └── SSH :22 └── PostgreSQL └── Docker volume Gitea └── container registry ``` There is no Kubernetes, managed database, load balancer, deployment platform, or other infrastructure layer. None is currently needed.