Files
2026-09-16 09:31:28 -05:00

3.8 KiB

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.