local docker dev + starting on gameplay
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user