Migrate from raspen prototype to heron live VPS

- Replace raspen references with heron in AGENTS.md
- Update nginx config for live domains (qmoln.se)
- Switch SSL certs to Let's Encrypt paths
- Update WireGuard config with heron's keys and passive listen
- WireGuard direction: agge connects out to heron
- Remove old ssl volume mount, mount /etc/letsencrypt instead
This commit is contained in:
2026-05-28 05:49:05 +02:00
parent 915cab05b9
commit c13bcb3efa
4 changed files with 38 additions and 30 deletions
+21 -13
View File
@@ -6,42 +6,50 @@
|------|------|----|--------|-------|----------| |------|------|----|--------|-------|----------|
| hector | Dev machine (this one) | Linux Mint Mate | — | — | — | | hector | Dev machine (this one) | Linux Mint Mate | — | — | — |
| agge | Backend server | Ubuntu Server | 192.168.1.188 | 10.0.0.2 | tebarbi | | agge | Backend server | Ubuntu Server | 192.168.1.188 | 10.0.0.2 | tebarbi |
| raspen | VPS / reverse proxy | Raspberry Pi OS Lite | 192.168.1.187 | 10.0.0.1 | rasput | | heron | VPS / reverse proxy | Ubuntu Server | 82.197.73.238 | 10.0.0.1 | qbert |
## Architecture ## Architecture
All traffic goes through **raspen** (single entry point): All traffic goes through **heron** (single entry point, public IP `82.197.73.238`):
- nginx in Docker (`vps/docker-compose.yml`) terminates SSL and reverse proxies - nginx in Docker (`vps/docker-compose.yml`) terminates SSL (Let's Encrypt) and reverse proxies
- WireGuard sidecar container encrypts traffic to agge - WireGuard sidecar container encrypts traffic to agge
- agge connects *out* to heron (agge is behind residential NAT, heron listens passively)
- All backend services bind to `10.0.0.2` only (tunnel-only access) - All backend services bind to `10.0.0.2` only (tunnel-only access)
## Services ## Services
| Domain | Service | Backend | Via raspen | | Domain | Service | Backend | Via heron |
|--------|---------|---------|------------| |--------|---------|---------|-----------|
| git.home | Gitea | agge:10.0.0.2:3000 (HTTP), :2222 (SSH) | HTTPS :443, TCP :2222 | | git.qmoln.se | Gitea | agge:10.0.0.2:3000 (HTTP), :2222 (SSH) | HTTPS :443, TCP :2222 |
| nc.home | Nextcloud | agge:10.0.0.2:8080 | HTTPS :443 | | nc.qmoln.se | Nextcloud | agge:10.0.0.2:8080 | HTTPS :443 |
| pg.home | PostgreSQL | agge:10.0.0.2:5432 | TCP :5432 | | pg.qmoln.se | PostgreSQL | agge:10.0.0.2:5432 | TCP :5432 |
| raspen.home | Static page | Served directly by nginx | HTTP/HTTPS | | qmoln.se | Static page | Served directly by nginx | HTTP/HTTPS |
## Repo structure ## Repo structure
- `backend/docker-compose.yml` — agge stack (postgres, nextcloud, gitea, postgres_remote) - `backend/docker-compose.yml` — agge stack (postgres, nextcloud, gitea, postgres_remote)
- `vps/docker-compose.yml`raspen stack (wireguard sidecar + nginx) - `vps/docker-compose.yml`heron stack (wireguard sidecar + nginx)
- `vps/nginx/conf.d/` — HTTP/HTTPS proxy configs - `vps/nginx/conf.d/` — HTTP/HTTPS proxy configs
- `vps/nginx/stream.d/` — TCP stream proxy configs (postgres, gitea ssh) - `vps/nginx/stream.d/` — TCP stream proxy configs (postgres, gitea ssh)
- `vps/wireguard/wg_confs/` — WireGuard tunnel config - `vps/wireguard/wg_confs/` — WireGuard tunnel config
- `.env.example` — template for secrets (real `.env` is gitignored) - `.env.example` — template for secrets (real `.env` is gitignored)
## Git remote ## WireGuard keys
- agge public key: `02k4BaH3iZTQnPZe7zifcaS9n8xxrwCLyIOLTBWLdgk=`
- heron public key: `4BtJlUWOzBtvrRu3llQbD0GPvlXgTwLq79iBth3uOSo=`
- agge connects out to heron at `82.197.73.238:51820`
- heron's WG private key is in `vps/wireguard/wg_confs/wg0.conf`
## Git remote (via tunnel — only reachable when tunnel is up)
``` ```
ssh://git@git.home:2222/scoot/selfhosted2.git ssh://git@git.qmoln.se:2222/scoot/selfhosted2.git
``` ```
## Conventions ## Conventions
- The machines `agge` and `raspen` require `sudo` for most commands. Do **not** attempt to execute commands requiring sudo via SSH — present the command to the user and let them run it manually. - The machines `agge` and `heron` require `sudo` for most commands. Do **not** attempt to execute commands requiring sudo via SSH — present the command to the user and let them run it manually.
## Password management ## Password management
+1 -1
View File
@@ -26,6 +26,6 @@ services:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/stream.d:/etc/nginx/stream.d:ro - ./nginx/stream.d:/etc/nginx/stream.d:ro
- ./ssl:/etc/nginx/certs:ro - /etc/letsencrypt:/etc/letsencrypt:ro
- ./html:/usr/share/nginx/html:ro - ./html:/usr/share/nginx/html:ro
restart: unless-stopped restart: unless-stopped
+14 -14
View File
@@ -8,19 +8,19 @@ upstream gitea {
server { server {
listen 80; listen 80;
server_name nc.home; server_name nc.qmoln.se;
return 301 https://nc.home$request_uri; return 301 https://nc.qmoln.se$request_uri;
} }
server { server {
listen 80; listen 80;
server_name git.home; server_name git.qmoln.se;
return 301 https://git.home$request_uri; return 301 https://git.qmoln.se$request_uri;
} }
server { server {
listen 80; listen 80;
server_name raspen.home; server_name qmoln.se;
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html; index index.html;
@@ -37,10 +37,10 @@ server {
server { server {
listen 443 ssl; listen 443 ssl;
server_name nc.home; server_name nc.qmoln.se;
ssl_certificate /etc/nginx/certs/ssl.crt; ssl_certificate /etc/letsencrypt/live/qmoln.se/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/ssl.key; ssl_certificate_key /etc/letsencrypt/live/qmoln.se/privkey.pem;
client_max_body_size 10G; client_max_body_size 10G;
client_body_timeout 3600s; client_body_timeout 3600s;
@@ -63,10 +63,10 @@ server {
server { server {
listen 443 ssl; listen 443 ssl;
server_name git.home; server_name git.qmoln.se;
ssl_certificate /etc/nginx/certs/ssl.crt; ssl_certificate /etc/letsencrypt/live/qmoln.se/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/ssl.key; ssl_certificate_key /etc/letsencrypt/live/qmoln.se/privkey.pem;
location / { location / {
proxy_pass http://gitea; proxy_pass http://gitea;
@@ -82,10 +82,10 @@ server {
server { server {
listen 443 ssl; listen 443 ssl;
server_name raspen.home; server_name qmoln.se;
ssl_certificate /etc/nginx/certs/ssl.crt; ssl_certificate /etc/letsencrypt/live/qmoln.se/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/ssl.key; ssl_certificate_key /etc/letsencrypt/live/qmoln.se/privkey.pem;
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html; index index.html;
+2 -2
View File
@@ -1,9 +1,9 @@
[Interface] [Interface]
Address = 10.0.0.1/30 Address = 10.0.0.1/30
PrivateKey = 0Junydsr+YBVFgkHbDEEmWAXAhR7JCpSWyT1yzSzjFU= PrivateKey = EFp3S6XsMQEEM8o6KJBNv5gybTfS28xnO/XwWSLue2k=
ListenPort = 51820
[Peer] [Peer]
PublicKey = 02k4BaH3iZTQnPZe7zifcaS9n8xxrwCLyIOLTBWLdgk= PublicKey = 02k4BaH3iZTQnPZe7zifcaS9n8xxrwCLyIOLTBWLdgk=
Endpoint = 192.168.1.188:51820
AllowedIPs = 10.0.0.2/32 AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25 PersistentKeepalive = 25