Files
go-fishing/README.md
T
2026-09-16 09:31:28 -05:00

241 lines
3.8 KiB
Markdown

# 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@<vps>
```
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.