feat: add nexus container (CT 117) and document Tailscale LXC setup

- Create nexus LXC (Ubuntu 24.04, 4 cores, 4GB RAM, 40GB, 10.5.0.17)
- Configure Tailscale with SSH on nexus (100.126.46.74)
- Document standard Tailscale-on-LXC procedure in CLAUDE.md (TUN device,
  SSH port 2222, socket activation override)
- Add Obsidian/CouchDB stack, Stalwart mail helper, and other doc updates
- Add dns-services, obsidian, pve-homelab-kit, stalwart config dirs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikkel Georgsen 2026-02-13 01:35:00 +00:00
parent 639e4f58e0
commit 147434e20b
6 changed files with 121 additions and 5 deletions

View file

@ -118,6 +118,24 @@ The `~/bin/kuma` script manages Uptime Kuma monitors:
~/bin/kuma resume <id> # Resume monitor ~/bin/kuma resume <id> # Resume monitor
``` ```
## Stalwart Mail Server
The `~/bin/mail` script manages Stalwart Mail Server (VM 200, 65.108.14.164):
```bash
~/bin/mail list # List all mail accounts
~/bin/mail info <email> # Show account details
~/bin/mail create <email> <password> [name] # Create new mail account
~/bin/mail delete <email> # Delete mail account
~/bin/mail passwd <email> <password> # Change account password
~/bin/mail domains # List configured domains
~/bin/mail status # Show server status/version
```
**Active domain:** datalos.dk
**Admin UI:** https://mail.georgsen.dk
**Webmail:** https://webmail.georgsen.dk (Snappymail on Dockge)
**Credentials:** `~/homelab/stalwart/credentials`
## Service Updates ## Service Updates
The `~/bin/updates` script checks for and applies updates across all homelab services: The `~/bin/updates` script checks for and applies updates across all homelab services:
@ -126,7 +144,7 @@ The `~/bin/updates` script checks for and applies updates across all homelab ser
~/bin/updates update <name|all> [-y] # Update one or more services ~/bin/updates update <name|all> [-y] # Update one or more services
``` ```
**Tracked services:** dragonfly, beszel, uptime-kuma, snappymail, dockge, npm, forgejo, dns, pbs **Tracked services:** dragonfly, beszel, uptime-kuma, snappymail, stalwart, dockge, npm, forgejo, dns, pbs
Checks Docker image versions (Dockge + NPM), LXC service binaries (Forgejo, Technitium DNS), and apt packages (PBS) against GitHub/Codeberg releases. Checks Docker image versions (Dockge + NPM), LXC service binaries (Forgejo, Technitium DNS), and apt packages (PBS) against GitHub/Codeberg releases.
@ -230,6 +248,41 @@ ssh root@10.5.0.254 'pct exec <vmid> -- setcap cap_net_raw+ep /bin/ping'
Note: Must be re-applied after `iputils-ping` package upgrades. Note: Must be re-applied after `iputils-ping` package upgrades.
**Tailscale on LXC containers:**
When setting up Tailscale with `--ssh` on an unprivileged LXC container:
1. Stop the container and add TUN device access to `/etc/pve/lxc/<vmid>.conf` on the PVE host:
```
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
```
2. Start the container, install and enable Tailscale:
```bash
curl -fsSL https://tailscale.com/install.sh | sh
systemctl start tailscaled
tailscale up --ssh
```
3. Move local SSH to port 2222 (Tailscale SSH takes port 22):
```bash
# Update sshd_config
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
# Override ssh.socket (Ubuntu 24.04 uses socket activation)
mkdir -p /etc/systemd/system/ssh.socket.d
cat > /etc/systemd/system/ssh.socket.d/override.conf << EOF
[Socket]
ListenStream=
ListenStream=2222
EOF
systemctl daemon-reload
systemctl restart ssh.socket ssh.service
```
After setup: local SSH via `ssh -p 2222 user@<ip>`, Tailscale SSH via `ssh user@<hostname>`.
## CRITICAL: Software Versions ## CRITICAL: Software Versions
**NEVER use version numbers from training data.** Always fetch the latest version dynamically: **NEVER use version numbers from training data.** Always fetch the latest version dynamically:

2
dns-services/credentials Normal file
View file

@ -0,0 +1,2 @@
DNS_SERVICES_USER='msgeorgsen@gmail.com'
DNS_SERVICES_PASS='Vy7aWzQeS&pg3Du#MXcKQCi!'

View file

@ -123,10 +123,11 @@ Saved with: `netfilter-persistent save`
| Type | VM (KVM) | | Type | VM (KVM) |
| IP | 65.108.14.164 (dedicated public IP) | | IP | 65.108.14.164 (dedicated public IP) |
| Bridge | vmbr0 (direct) | | Bridge | vmbr0 (direct) |
| Software | Stalwart Mail Server | | Software | Stalwart Mail Server 0.15.4 |
| Disk | 32GB |
| Webmail | Snappymail (via dockge) | | Webmail | Snappymail (via dockge) |
**Current domains:** dataloes.dk (building reputation before adding more) **Active domain:** datalos.dk
**Planned domains:** georgsen.dk, microsux.dk, dataloes.dk **Planned domains:** georgsen.dk, microsux.dk, dataloes.dk
@ -154,6 +155,7 @@ Saved with: `netfilter-persistent save`
| 114 | forgejo | 10.5.0.14 | Git server (Forgejo) | Running | | 114 | forgejo | 10.5.0.14 | Git server (Forgejo) | Running |
| 115 | dns | 10.5.0.2 | DNS server (Technitium) | Running | | 115 | dns | 10.5.0.2 | DNS server (Technitium) | Running |
| 116 | lisotex | 10.5.0.116 | lisotex.dk website | Running | | 116 | lisotex | 10.5.0.116 | lisotex.dk website | Running |
| 117 | nexus | 10.5.0.17 | Nexus (Tailscale SSH) | Running |
| 120 | debate-builder | 10.5.0.171 | Debate builder app (KVM) | Running | | 120 | debate-builder | 10.5.0.171 | Debate builder app (KVM) | Running |
| 1000 | tailscale | 10.5.0.134 + 10.9.1.10 | Tailscale relay | Running | | 1000 | tailscale | 10.5.0.134 + 10.9.1.10 | Tailscale relay | Running |
@ -189,6 +191,9 @@ cd /opt/npm && docker compose pull && docker compose up -d
| status.georgsen.dk | http://10.5.0.10:3001 | Let's Encrypt | | status.georgsen.dk | http://10.5.0.10:3001 | Let's Encrypt |
| webmail.georgsen.dk | http://10.5.0.10:8888 | Let's Encrypt | | webmail.georgsen.dk | http://10.5.0.10:8888 | Let's Encrypt |
| dashboard.georgsen.dk | http://10.5.0.10:8090 | Let's Encrypt | | dashboard.georgsen.dk | http://10.5.0.10:8090 | Let's Encrypt |
| obsidian.georgsen.dk | http://10.5.0.10:8280 | Let's Encrypt |
| obs.georgsen.dk | http://10.5.0.10:8280 | Let's Encrypt |
| obsidian-sync.georgsen.dk | http://10.5.0.10:5984 | Let's Encrypt |
#### 101: Dockge #### 101: Dockge
@ -248,6 +253,27 @@ services:
command: ["--requirepass", "nUq/IfoIQJf/kouckKHRQOk7vV0NwCuI"] command: ["--requirepass", "nUq/IfoIQJf/kouckKHRQOk7vV0NwCuI"]
# Password: nUq/IfoIQJf/kouckKHRQOk7vV0NwCuI # Password: nUq/IfoIQJf/kouckKHRQOk7vV0NwCuI
# Connect: redis-cli -h 10.5.0.10 -p 6379 -a 'nUq/IfoIQJf/kouckKHRQOk7vV0NwCuI' # Connect: redis-cli -h 10.5.0.10 -p 6379 -a 'nUq/IfoIQJf/kouckKHRQOk7vV0NwCuI'
# Obsidian (web-based editor + LiveSync)
services:
obsidian:
image: lscr.io/linuxserver/obsidian:latest
container_name: obsidian
ports:
- 8280:3000
- 8281:3001
volumes:
- ./obsidian-config:/config
couchdb:
image: couchdb:latest
container_name: couchdb-livesync
ports:
- 5984:5984
volumes:
- ./couchdb-data:/opt/couchdb/data
- ./couchdb-etc:/opt/couchdb/etc/local.d
# CouchDB credentials: ~/homelab/obsidian/credentials
# LiveSync database: obsidian-livesync
``` ```
#### 105: Sentry (Defense Intelligence) #### 105: Sentry (Defense Intelligence)
@ -424,6 +450,7 @@ Requires=mnt-synology.mount
| xanderryzen | 100.71.118.78 | | | xanderryzen | 100.71.118.78 | |
| nvr01 | 100.118.17.103 | Exit node | | nvr01 | 100.118.17.103 | Exit node |
| tailscalemg | 100.115.101.65 | Exit node | | tailscalemg | 100.115.101.65 | Exit node |
| nexus | 100.126.46.74 | |
**Tailscale config:** SSH enabled on all devices where possible **Tailscale config:** SSH enabled on all devices where possible
@ -457,6 +484,7 @@ Requires=mnt-synology.mount
| dockge | 10.5.0.10 | | dockge | 10.5.0.10 |
| forgejo | 10.5.0.14 | | forgejo | 10.5.0.14 |
| git | 10.5.0.14 | | git | 10.5.0.14 |
| nexus | 10.5.0.17 |
| mgmt | 10.5.0.108 | | mgmt | 10.5.0.108 |
| postgresql01 | 10.5.0.109 | | postgresql01 | 10.5.0.109 |
| pve-scripts | 10.5.0.110 | | pve-scripts | 10.5.0.110 |
@ -467,6 +495,9 @@ Requires=mnt-synology.mount
| sentry | 10.5.0.168 | | sentry | 10.5.0.168 |
| debate-builder | 10.5.0.171 | | debate-builder | 10.5.0.171 |
| jukebox | 10.5.0.184 | | jukebox | 10.5.0.184 |
| obsidian | 10.5.0.10 |
| obs | 10.5.0.10 |
| obsidian-sync | 10.5.0.10 |
--- ---
@ -520,6 +551,23 @@ chown -R mikkel:georgsen /home/mikkel/.ssh
setcap cap_net_raw+ep /bin/ping setcap cap_net_raw+ep /bin/ping
``` ```
### Tailscale in LXC Containers
Unprivileged LXC containers need TUN device access for Tailscale. Add to the container config on the PVE host (`/etc/pve/lxc/<vmid>.conf`):
```
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
```
Container must be stopped before adding these lines. Then inside the container:
```bash
curl -fsSL https://tailscale.com/install.sh | sh
systemctl start tailscaled
tailscale up --ssh
```
--- ---
## Projects ## Projects
@ -560,7 +608,7 @@ Personal company website
| ID | Name | IPs | Applied To | | ID | Name | IPs | Applied To |
|----|------|-----|------------| |----|------|-----|------------|
| 1 | home_only | 83.89.248.247 | dns.georgsen.dk, dockge.georgsen.dk, pbs.georgsen.dk | | 1 | home_only | 83.89.248.247 | dns.georgsen.dk, dockge.georgsen.dk, pbs.georgsen.dk, obsidian.georgsen.dk, obs.georgsen.dk, obsidian-sync.georgsen.dk |
### Fail2ban ### Fail2ban
@ -616,6 +664,8 @@ Personal company website
| Webmail | https://webmail.georgsen.dk | | Webmail | https://webmail.georgsen.dk |
| JukeBox | https://jukebox.georgsen.dk | | JukeBox | https://jukebox.georgsen.dk |
| Dashboard | https://dashboard.georgsen.dk or http://10.5.0.10:8090 | | Dashboard | https://dashboard.georgsen.dk or http://10.5.0.10:8090 |
| Obsidian | https://obsidian.georgsen.dk or http://10.5.0.10:8280 |
| Obsidian Sync | https://obsidian-sync.georgsen.dk or http://10.5.0.10:5984 |
### Important IPs ### Important IPs
@ -743,4 +793,4 @@ Personal company website
--- ---
*Last updated: 2026-01-28* *Last updated: 2026-02-12*

7
obsidian/credentials Normal file
View file

@ -0,0 +1,7 @@
CouchDB LiveSync Credentials
=============================
URL: http://10.5.0.10:5984
Public URL: https://obsidian-sync.georgsen.dk
Database: obsidian-livesync
Username: obsidian
Password: nmJdWsRCPY49lPWl4NVKuKeF

1
pve-homelab-kit Submodule

@ -0,0 +1 @@
Subproject commit 96dc1eb4994ef12ac538782f0da1aa736d7dfb27

3
stalwart/credentials Normal file
View file

@ -0,0 +1,3 @@
STALWART_URL=https://mail.georgsen.dk
STALWART_ADMIN_USER=admin
STALWART_ADMIN_PASS=NfDB1p7rxqVGH8nPTPmK