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:
git.hat.fish
Traffic
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:
go-fishing
postgres
The application image is:
git.hat.fish/jaron/go-fishing:latest
PostgreSQL uses:
postgres:18-alpine
PostgreSQL data is stored in a Docker volume.
The database is only accessible through the Docker network.
go-fishing -> db:5432
There is no reason to expose PostgreSQL publicly.
HTTP
The Go application exposes an HTTP server on:
9900
It is not intended to be accessed directly.
Nginx proxies HTTPS traffic to it:
https://fishing.jp.wtf
-> nginx :443
-> 127.0.0.1:9900
A minimal Nginx configuration looks like:
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:
/etc/letsencrypt/live/fishing.jp.wtf/
The important files are:
fullchain.pem
privkey.pem
The certificate was created with:
sudo certbot --nginx -d fishing.jp.wtf
Renewal is handled automatically by Certbot.
Check it with:
systemctl status certbot.timer
Test renewal with:
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:
ssh user@fishing.jp.wtf
The VPS itself is administered with:
ssh -p 2222 user@<vps>
Nginx and the TLS certificate are unrelated to SSH.
Configuration
Secrets and environment-specific configuration live in .env on the VPS.
Example:
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:
# 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:
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:
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.