"vault backup: 2026-03-08 13:41:28 from Flow"
This commit is contained in:
50
21-Server Reference/homelab/README.md
Normal file
50
21-Server Reference/homelab/README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Homelab Server Documentation
|
||||
|
||||
Living documentation for the `homelab` server. Goal: a new admin with zero prior context should be able to read this and understand everything about the server.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| Hostname | `homelab` |
|
||||
| LAN IP | `192.168.2.114` |
|
||||
| Tailscale IP | `100.72.0.62` |
|
||||
| OS | Ubuntu 25.10 (Questing Quokka) |
|
||||
| Kernel | 6.17.0-14-generic |
|
||||
| Docker Files | `/home/artanis/DockerFiles/` |
|
||||
| Docker Manager | [dockhand.bunny-wyvern.ts.net](https://dockhand.bunny-wyvern.ts.net) |
|
||||
|
||||
## Documentation Index
|
||||
|
||||
- [[hardware]] — CPU, RAM, storage
|
||||
- [[network]] — Interfaces, Tailscale, ports in use
|
||||
- [[environments]] — Dockhand-managed environments (Homelab + Pihole)
|
||||
- [[stacks/README]] — Overview of all Docker stacks
|
||||
|
||||
### Stacks
|
||||
| Stack | Purpose | Access |
|
||||
|---|---|---|
|
||||
| [[stacks/dockhand]] | Docker management UI | [dockhand.bunny-wyvern.ts.net](https://dockhand.bunny-wyvern.ts.net) |
|
||||
| [[stacks/minecraft]] | Minecraft server (TerraFirmaGreg) | `:25565` |
|
||||
| [[stacks/mealie]] | Recipe manager | [mealie.bunny-wyvern.ts.net](https://mealie.bunny-wyvern.ts.net) |
|
||||
| [[stacks/linkwarden]] | Bookmark manager | [linkwarden.bunny-wyvern.ts.net](https://linkwarden.bunny-wyvern.ts.net) |
|
||||
| [[stacks/gitea]] | Self-hosted Git | [gitea.bunny-wyvern.ts.net](https://gitea.bunny-wyvern.ts.net) |
|
||||
| [[stacks/matrix]] | Matrix homeserver + bridges | [matrix.bunny-wyvern.ts.net](https://matrix.bunny-wyvern.ts.net) |
|
||||
| [[stacks/homepage]] | Dashboard | [homepage.bunny-wyvern.ts.net](https://homepage.bunny-wyvern.ts.net) |
|
||||
| [[stacks/n8n]] | Workflow automation | [n8n.bunny-wyvern.ts.net](https://n8n.bunny-wyvern.ts.net) |
|
||||
| [[stacks/calibre]] | E-book library (STOPPED) | [calibre.bunny-wyvern.ts.net](https://calibre.bunny-wyvern.ts.net) |
|
||||
| [[stacks/gluetun]] | VPN gateway (Mullvad) | `:8001` (control) |
|
||||
| [[stacks/openproject]] | Project management | [openproject.bunny-wyvern.ts.net](https://openproject.bunny-wyvern.ts.net) |
|
||||
| [[stacks/melodix]] | Discord music bot | Internal only |
|
||||
|
||||
## Key Architectural Patterns
|
||||
|
||||
### Tailscale Sidecar
|
||||
Nearly every service uses a **Tailscale sidecar** pattern for remote access:
|
||||
- A `tailscale/tailscale` container runs alongside the main service container
|
||||
- It uses `network_mode: "service:[main]"` to share the main container's network namespace
|
||||
- This registers the main service as a Tailscale node (e.g. `mealie.bunny-wyvern.ts.net`)
|
||||
- Services are **not exposed to the public internet** — only accessible via Tailscale VPN
|
||||
|
||||
### Credentials
|
||||
Credentials (DB passwords, API keys, Tailscale auth keys) live in the compose files on disk at `/home/artanis/DockerFiles/`. They are redacted in this documentation. See individual stack files for variable names and the actual compose files for values.
|
||||
38
21-Server Reference/homelab/environments.md
Normal file
38
21-Server Reference/homelab/environments.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Dockhand Environments
|
||||
|
||||
Dockhand manages two Docker environments. Select an environment with the `?env=[id]` query parameter in the API.
|
||||
|
||||
## Environment 1 — Homelab
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| ID | `1` |
|
||||
| Name | Homelab |
|
||||
| Connection | Local Unix socket (`/var/run/docker.sock`) |
|
||||
| Public IP | `192.168.2.114` |
|
||||
| Timezone | America/Chicago |
|
||||
| Auto-update checks | Enabled (auto-apply: off) |
|
||||
| Image pruning | Enabled |
|
||||
| Activity collection | Enabled |
|
||||
| Metrics collection | Enabled |
|
||||
|
||||
This is the primary server. All stacks documented in [[stacks/README]] run here.
|
||||
|
||||
## Environment 2 — Pihole
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| ID | `2` |
|
||||
| Name | Pihole |
|
||||
| Connection | Hawser (remote agent) |
|
||||
| Host | `100.89.172.56` (Tailscale) |
|
||||
| Port | `2376` |
|
||||
| Timezone | America/Chicago |
|
||||
| Auto-update checks | Enabled (auto-apply: off) |
|
||||
| Image pruning | Enabled |
|
||||
| Activity collection | Enabled |
|
||||
| Metrics collection | Enabled |
|
||||
|
||||
A separate device running Pi-hole (network-wide ad blocker / DNS). Connected to Dockhand via the **Hawser** agent over Tailscale. Documentation for this environment is tracked separately.
|
||||
|
||||
> **Note:** The Hawser agent on the Pihole was last seen as disconnected at the time of this writing — `hawserLastSeen: null`. Hawser may need to be restarted on that device.
|
||||
32
21-Server Reference/homelab/hardware.md
Normal file
32
21-Server Reference/homelab/hardware.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Hardware
|
||||
|
||||
## CPU
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| Model | Intel Core i7-6700K |
|
||||
| Base Clock | 4.00 GHz |
|
||||
| Max Boost | 4.20 GHz |
|
||||
| Cores / Threads | 4 cores / 8 threads |
|
||||
| Socket | LGA1151 (single socket) |
|
||||
| Architecture | Skylake |
|
||||
|
||||
## Memory
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| Total RAM | 32 GB |
|
||||
| Swap | 8 GB |
|
||||
| Typical Usage | ~16 GB used at idle with all containers running |
|
||||
|
||||
## Storage
|
||||
|
||||
| Device | Type | Size | Mount | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `nvme0n1p2` | NVMe SSD | 931.5 GB | `/` (root) | Primary OS + Docker disk. ~149 GB used. |
|
||||
| `sda1` | HDD | 298.1 GB | `/mnt/300GBHDD` | Secondary disk. Nearly empty (2.1 MB used). |
|
||||
| `sdb`–`sde` | — | 0 B | — | Empty/unformatted slots (likely USB or unpopulated) |
|
||||
|
||||
### Storage Layout Notes
|
||||
- All Docker volumes live under `/var/lib/docker/volumes/` on the NVMe
|
||||
- Bind-mounted compose data lives under `/home/artanis/DockerFiles/` on the NVMe
|
||||
- Minecraft server data is at `/Minecraft_Server/` (root of NVMe)
|
||||
- The 300 GB HDD at `/mnt/300GBHDD` is currently unused by any container
|
||||
73
21-Server Reference/homelab/network.md
Normal file
73
21-Server Reference/homelab/network.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Network
|
||||
|
||||
## Physical / Host Interfaces
|
||||
|
||||
| Interface | IP | Notes |
|
||||
|---|---|---|
|
||||
| `enp0s31f6` | `192.168.2.114/24` | Primary LAN NIC |
|
||||
| `tailscale0` | `100.72.0.62/32` | Tailscale VPN interface |
|
||||
| `lo` | `127.0.0.1` | Loopback |
|
||||
|
||||
The server also has many `br-*` Docker bridge interfaces (172.x.x.x ranges) — one per Docker network. See the Docker Networks section below.
|
||||
|
||||
## Tailscale
|
||||
|
||||
The server is on the `bunny-wyvern.ts.net` Tailnet. Remote access to all services is done exclusively through Tailscale — no public port forwarding is configured.
|
||||
|
||||
Each major service registers itself as a separate Tailscale node via the sidecar pattern (see [[README#Key Architectural Patterns]]).
|
||||
|
||||
| Tailscale Hostname | Service |
|
||||
|---|---|
|
||||
| `dockhand.bunny-wyvern.ts.net` | Dockhand |
|
||||
| `mealie.bunny-wyvern.ts.net` | Mealie |
|
||||
| `linkwarden.bunny-wyvern.ts.net` | Linkwarden |
|
||||
| `gitea.bunny-wyvern.ts.net` | Gitea |
|
||||
| `matrix.bunny-wyvern.ts.net` | Matrix / Synapse |
|
||||
| `homepage.bunny-wyvern.ts.net` | Homepage |
|
||||
| `n8n.bunny-wyvern.ts.net` | n8n |
|
||||
| `calibre.bunny-wyvern.ts.net` | Calibre (inactive) |
|
||||
| `openproject.bunny-wyvern.ts.net` | OpenProject |
|
||||
|
||||
## Host Ports In Use
|
||||
|
||||
| Port | Protocol | Service |
|
||||
|---|---|---|
|
||||
| 22 | TCP | SSH (host) |
|
||||
| 139, 445 | TCP | Samba |
|
||||
| 631 | TCP | CUPS (printing) |
|
||||
| 2222 | TCP | Gitea SSH |
|
||||
| 3000 | TCP | Gitea web UI |
|
||||
| 5001 | TCP | Linkwarden |
|
||||
| 5010 | TCP | OpenProject |
|
||||
| 5100 | TCP | Python process (unknown) |
|
||||
| 5555 | TCP | Dockhand |
|
||||
| 5678 | TCP | n8n |
|
||||
| 8001 | TCP | Gluetun HTTP control server |
|
||||
| 8388 | TCP/UDP | Gluetun Shadowsocks |
|
||||
| 8888 | TCP | Gluetun HTTP proxy |
|
||||
| 9170 | TCP | system-bridge |
|
||||
| 25565 | TCP | Minecraft |
|
||||
| 24454 | UDP | Minecraft voice chat |
|
||||
| 35000 | TCP | Homepage |
|
||||
|
||||
## Docker Networks
|
||||
|
||||
| Network Name | Subnet | Connected Containers |
|
||||
|---|---|---|
|
||||
| `matrix_matrix-internal` | `172.25.0.0/16` | synapse, matrix-db, matrix-relay, mautrix-* |
|
||||
| `dockhand_default` | `172.23.0.0/16` | dockhand |
|
||||
| `docker_default` | `172.18.0.0/16` | melodix |
|
||||
| `gitea_default` | `172.20.0.0/16` | gitea, gitea_db |
|
||||
| `linkwarden_default` | `172.21.0.0/16` | linkwarden, linkwarden-db |
|
||||
| `mealie_default` | `172.22.0.0/16` | mealie |
|
||||
| `homepage_default` | `172.26.0.0/16` | homepage |
|
||||
| `n8n_default` | `172.29.0.0/16` | n8n |
|
||||
| `minecraft_server_default` | `172.24.0.0/16` | minecraft |
|
||||
| `open-project_default` | `172.30.0.0/16` | openproject |
|
||||
| `gluetun-qbittorent_default` | `172.19.0.0/16` | gluetun |
|
||||
| `calibre_default` | `172.28.0.0/16` | (empty — calibre stopped) |
|
||||
|
||||
## DNS
|
||||
|
||||
- `127.0.0.53` — systemd-resolved (stub resolver)
|
||||
- Gluetun is configured to use `192.168.2.112` as DNS (likely the Pihole on the LAN)
|
||||
41
21-Server Reference/homelab/stacks/README.md
Normal file
41
21-Server Reference/homelab/stacks/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Docker Stacks Overview
|
||||
|
||||
All stacks run on [[../environments#Environment 1 — Homelab]]. Compose files live at `/home/artanis/DockerFiles/` unless noted otherwise.
|
||||
|
||||
## Status Summary
|
||||
|
||||
| Stack | Status | Containers | Tailscale Node |
|
||||
|---|---|---|---|
|
||||
| [[dockhand]] | Running | 2 | `dockhand.bunny-wyvern.ts.net` |
|
||||
| [[minecraft]] | Running | 1 | None (LAN exposed) |
|
||||
| [[mealie]] | Running | 2 | `mealie.bunny-wyvern.ts.net` |
|
||||
| [[linkwarden]] | Running | 3 | `linkwarden.bunny-wyvern.ts.net` |
|
||||
| [[gitea]] | Running | 3 | `gitea.bunny-wyvern.ts.net` |
|
||||
| [[matrix]] | Running | 8 | `matrix.bunny-wyvern.ts.net` |
|
||||
| [[homepage]] | Running | 2 | `homepage.bunny-wyvern.ts.net` |
|
||||
| [[n8n]] | Running | 2 | `n8n.bunny-wyvern.ts.net` |
|
||||
| [[calibre]] | **Stopped** | 2 | `calibre.bunny-wyvern.ts.net` |
|
||||
| [[gluetun]] | Running | 1 | None |
|
||||
| [[openproject]] | Running | 2 | `openproject.bunny-wyvern.ts.net` |
|
||||
| [[melodix]] | Running | 1 | None |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Tailscale Sidecar
|
||||
Most stacks include a `tailscale/tailscale` sidecar that joins the Tailnet and makes the service accessible at `[name].bunny-wyvern.ts.net`. All sidecars share a single Tailscale auth key stored in the compose files.
|
||||
|
||||
### Bind Mounts vs Named Volumes
|
||||
- **Config/data that needs to be easily accessible** uses bind mounts into `/home/artanis/DockerFiles/[stack]/`
|
||||
- **Tailscale state** always uses named volumes (e.g. `stack_tailscale_state`) so node registration persists across restarts
|
||||
- **Dockhand vulnerability scanner caches** use named volumes (`dockhand-grype-db`, `dockhand-trivy-db`)
|
||||
|
||||
### Orphaned Volumes
|
||||
The following named volumes exist but are not attached to any running container — likely leftovers from deleted stacks:
|
||||
- `moltis_moltis-data`
|
||||
- `moltis_moltis-config`
|
||||
- `moltis_moltis-tailscale-state`
|
||||
- `portainer_data`
|
||||
- `open-project_open_project_tailscale_state`
|
||||
- `openproject_openproject_tailscale_state` (from an older `openproject` stack iteration)
|
||||
|
||||
> Orphaned networks (`blight_default`, old `openproject_default`) have been pruned.
|
||||
74
21-Server Reference/homelab/stacks/calibre.md
Normal file
74
21-Server Reference/homelab/stacks/calibre.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Calibre
|
||||
|
||||
Self-hosted e-book library manager (Calibre desktop server).
|
||||
|
||||
**Status: STOPPED** — The main `calibre` container is in `Created` state and the Tailscale sidecar exited with code 128. This stack is not currently running.
|
||||
|
||||
## Access (when running)
|
||||
- **Tailscale:** [calibre.bunny-wyvern.ts.net](https://calibre.bunny-wyvern.ts.net)
|
||||
- Web UI port: `8080` (mapped to host `8088`)
|
||||
- Content server port: `8081` (mapped to host `8089`)
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Status |
|
||||
|---|---|---|
|
||||
| `calibre` | `lscr.io/linuxserver/calibre:latest` | Created (never started) |
|
||||
| `calibre-tailscale-sidecar` | `tailscale/tailscale` (pinned image) | Exited (128) ~3 weeks ago |
|
||||
|
||||
> The Tailscale sidecar is running a pinned image hash (`sha256:1a2e759f...`) rather than `latest`. This may be why it failed — the image may be outdated or incompatible.
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/Calibre/docker-compose.yaml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
calibre:
|
||||
image: lscr.io/linuxserver/calibre:latest
|
||||
container_name: calibre
|
||||
pull_policy: always
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8088:8080"
|
||||
- "8089:8081"
|
||||
- "8181:8181"
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Calibre/server-config:/config
|
||||
- /home/artanis/DockerFiles/Calibre/books:/books
|
||||
environment:
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
TZ: America/Chicago
|
||||
|
||||
calibre-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: calibre-tailscale-sidecar
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- calibre_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=calibre
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:calibre"
|
||||
|
||||
volumes:
|
||||
calibre_tailscale_state:
|
||||
|
||||
# calibre-web service is commented out in compose
|
||||
```
|
||||
|
||||
## Data Layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `/home/artanis/DockerFiles/Calibre/server-config` | Calibre server configuration |
|
||||
| `/home/artanis/DockerFiles/Calibre/books` | E-book library files |
|
||||
|
||||
## Notes
|
||||
- A `calibre-web` service (separate lightweight web UI) is fully defined in the compose file but commented out
|
||||
- To restart this stack, the Tailscale sidecar image may need to be re-pulled (`pull_policy: always` is set on calibre but not the sidecar)
|
||||
59
21-Server Reference/homelab/stacks/dockhand.md
Normal file
59
21-Server Reference/homelab/stacks/dockhand.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Dockhand
|
||||
|
||||
Docker management UI. Used to manage all containers on the server. Also the tool used to generate this documentation.
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [dockhand.bunny-wyvern.ts.net](https://dockhand.bunny-wyvern.ts.net)
|
||||
- **LAN:** `http://192.168.2.114:5555`
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `dockhand` | `fnsys/dockhand:latest` | Main web UI |
|
||||
| `dockhand-tailscale-sidecar` | `tailscale/tailscale:latest` | Tailscale node |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/Dockhand/docker-compose.yaml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
dockhand:
|
||||
image: fnsys/dockhand:latest
|
||||
container_name: dockhand
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5555:3000
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /home/artanis/DockerFiles:/DockerFiles
|
||||
- /Minecraft_Server/docker-compose.yaml:/DockerFiles/Minecraft_Server/docker-compose.yaml
|
||||
- dockhand_data:/app/data
|
||||
|
||||
dockhand-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: dockhand-tailscale-sidecar
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- dockhand_tailscale_state:/var/lib/tailscale
|
||||
- /home/artanis/DockerFiles:/DockerFiles
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=dockhand
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:dockhand"
|
||||
|
||||
volumes:
|
||||
dockhand_data:
|
||||
dockhand_tailscale_state:
|
||||
```
|
||||
|
||||
## Notes
|
||||
- The entire `/home/artanis/DockerFiles` directory is mounted into the container at `/DockerFiles`, giving Dockhand read/write access to all compose files
|
||||
- The Minecraft compose file lives outside `DockerFiles` (`/Minecraft_Server/`) so it is explicitly bind-mounted in
|
||||
- `dockhand_data` is the named volume for Dockhand's internal state (environments, settings, user accounts)
|
||||
- Dockhand also manages vulnerability scanning with two cached databases: `dockhand-grype-db` and `dockhand-trivy-db`
|
||||
85
21-Server Reference/homelab/stacks/gitea.md
Normal file
85
21-Server Reference/homelab/stacks/gitea.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Gitea
|
||||
|
||||
Self-hosted Git service (GitHub alternative).
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [gitea.bunny-wyvern.ts.net](https://gitea.bunny-wyvern.ts.net)
|
||||
- **LAN Web:** `http://192.168.2.114:3000`
|
||||
- **LAN SSH:** `ssh://192.168.2.114:2222`
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `gitea` | `gitea/gitea:latest` | Web app + Git server |
|
||||
| `gitea_db` | `mysql:8` | MySQL database |
|
||||
| `gitea-tailscale-sidecar` | `tailscale/tailscale:latest` | Tailscale node |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/gitea/docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
gitea:
|
||||
image: gitea/gitea:latest
|
||||
container_name: gitea
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- GITEA__database__DB_TYPE=mysql
|
||||
- GITEA__database__HOST=db:3306
|
||||
- GITEA__database__NAME=gitea
|
||||
- GITEA__database__USER=gitea
|
||||
- GITEA__database__PASSWD=<redacted>
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/gitea/gitea_data:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:2222"
|
||||
|
||||
db:
|
||||
image: mysql:8
|
||||
container_name: gitea_db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=<redacted>
|
||||
- MYSQL_DATABASE=gitea
|
||||
- MYSQL_USER=gitea
|
||||
- MYSQL_PASSWORD=<redacted>
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/gitea/gitea_db_data:/var/lib/mysql
|
||||
|
||||
gitea-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: gitea-tailscale-sidecar
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- gitea_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=gitea
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:gitea"
|
||||
|
||||
volumes:
|
||||
gitea_tailscale_state:
|
||||
```
|
||||
|
||||
## Data Layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `/home/artanis/DockerFiles/gitea/gitea_data` | Gitea repos, config, attachments |
|
||||
| `/home/artanis/DockerFiles/gitea/gitea_db_data` | MySQL data directory |
|
||||
|
||||
## Notes
|
||||
- Database: MySQL 8 (separate container `gitea_db`)
|
||||
- Port 2222 is exposed for SSH-based Git operations (clone/push via `ssh://`)
|
||||
- Timezone files from the host are mounted read-only to keep Gitea's timestamps consistent
|
||||
60
21-Server Reference/homelab/stacks/gluetun.md
Normal file
60
21-Server Reference/homelab/stacks/gluetun.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Gluetun (VPN Gateway)
|
||||
|
||||
VPN gateway container using Mullvad via WireGuard. Acts as a network proxy for other containers or clients that need to route traffic through the VPN.
|
||||
|
||||
## Access
|
||||
- **HTTP Control Server:** `http://192.168.2.114:8001` (Gluetun management API)
|
||||
- **HTTP Proxy:** `http://192.168.2.114:8888`
|
||||
- **Shadowsocks:** `192.168.2.114:8388` (TCP + UDP)
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `gluetun` | `qmcgaw/gluetun:v3` | VPN gateway |
|
||||
|
||||
No Tailscale sidecar — this stack is accessed directly on the LAN.
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/gluetun-qbittorent/docker-compose.yaml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun:v3
|
||||
container_name: gluetun
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
ports:
|
||||
- 8001:8000/tcp # HTTP Control Server
|
||||
- 8888:8888/tcp # HTTP proxy
|
||||
- 8388:8388/tcp # Shadowsocks
|
||||
- 8388:8388/udp # Shadowsocks
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/ArrSuite/gluetun:/gluetun
|
||||
environment:
|
||||
- VPN_SERVICE_PROVIDER=mullvad
|
||||
- VPN_TYPE=wireguard
|
||||
- HTTPPROXY=on
|
||||
- WIREGUARD_PRIVATE_KEY=<redacted>
|
||||
- WIREGUARD_ADDRESSES=10.74.136.96/32
|
||||
- TZ=UTC-06
|
||||
- SERVER_COUNTRIES=Canada,USA
|
||||
- DNS_ADDRESS=192.168.2.112
|
||||
- HTTP_CONTROL_SERVER_ADDRESS=:8000
|
||||
- FIREWALL_OUTBOUND_SUBNETS=192.168.2.0/24
|
||||
- UPDATER_PERIOD=24h
|
||||
```
|
||||
|
||||
## Notes
|
||||
- **VPN Provider:** Mullvad, WireGuard protocol
|
||||
- **VPN IP:** `10.74.136.96/32` (assigned Mullvad address)
|
||||
- **Server regions:** Canada and USA
|
||||
- **DNS:** Routes DNS through `192.168.2.112` (likely the LAN Pihole)
|
||||
- `FIREWALL_OUTBOUND_SUBNETS=192.168.2.0/24` allows containers using Gluetun as their network to still reach the local LAN
|
||||
- `UPDATER_PERIOD=24h` — Gluetun automatically refreshes its Mullvad server list every 24 hours
|
||||
- The stack name is `gluetun-qbittorent`, suggesting qBittorrent was originally planned to run behind this VPN. The qBittorrent service is not currently deployed (only Gluetun is running)
|
||||
- Config data is bind-mounted to `/home/artanis/DockerFiles/ArrSuite/gluetun` (note: `ArrSuite` directory, suggesting future *arr apps may be planned)
|
||||
65
21-Server Reference/homelab/stacks/homepage.md
Normal file
65
21-Server Reference/homelab/stacks/homepage.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Homepage
|
||||
|
||||
Self-hosted dashboard (gethomepage.dev) for quick access to all services.
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [homepage.bunny-wyvern.ts.net](https://homepage.bunny-wyvern.ts.net)
|
||||
- **LAN:** `http://192.168.2.114:35000`
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `homepage` | `ghcr.io/gethomepage/homepage:latest` | Dashboard web app |
|
||||
| `homepage-tailscale-sidecar` | `tailscale/tailscale:latest` | Tailscale node |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/homepage/docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
homepage:
|
||||
image: ghcr.io/gethomepage/homepage:latest
|
||||
container_name: homepage
|
||||
restart: unless-stopped
|
||||
pull_policy: always
|
||||
ports:
|
||||
- 35000:3000
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/homepage/config:/app/config
|
||||
- /home/artanis/DockerFiles/homepage/images:/app/public/images
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
HOMEPAGE_ALLOWED_HOSTS: 192.168.2.114:35000,homelab:35000,100.72.0.62:35000,homepage.bunny-wyvern.ts.net
|
||||
|
||||
homepage-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: homepage-tailscale-sidecar
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- homepage_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=homepage
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:homepage"
|
||||
|
||||
volumes:
|
||||
homepage_tailscale_state:
|
||||
```
|
||||
|
||||
## Data Layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `/home/artanis/DockerFiles/homepage/config` | YAML config files (services, widgets, settings) |
|
||||
| `/home/artanis/DockerFiles/homepage/images` | Custom images for the dashboard |
|
||||
|
||||
## Notes
|
||||
- `HOMEPAGE_ALLOWED_HOSTS` must include all hostnames/IPs from which the dashboard will be accessed — required by Homepage as a CSRF protection measure
|
||||
- The Docker socket is mounted to enable Homepage's Docker integration (live container status widgets)
|
||||
- `pull_policy: always` ensures the latest image is pulled on every stack restart
|
||||
75
21-Server Reference/homelab/stacks/linkwarden.md
Normal file
75
21-Server Reference/homelab/stacks/linkwarden.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Linkwarden
|
||||
|
||||
Self-hosted bookmark manager with link archiving.
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [linkwarden.bunny-wyvern.ts.net](https://linkwarden.bunny-wyvern.ts.net)
|
||||
- **LAN:** `http://192.168.2.114:5001`
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `linkwarden` | `ghcr.io/linkwarden/linkwarden:latest` | Web app |
|
||||
| `linkwarden-db` | `postgres:16-alpine` | PostgreSQL database |
|
||||
| `linkwarden-tailscale-sidecar` | `tailscale/tailscale:latest` | Tailscale node |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/linkwarden/docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: linkwarden-db
|
||||
restart: always
|
||||
pull_policy: always
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/linkwarden/pgdata:/var/lib/postgresql/data
|
||||
|
||||
linkwarden:
|
||||
container_name: linkwarden
|
||||
image: ghcr.io/linkwarden/linkwarden:latest
|
||||
restart: always
|
||||
pull_policy: always
|
||||
ports:
|
||||
- 5001:3000
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/linkwarden/data:/data/data
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://postgres:<redacted>@postgres:5432/postgres
|
||||
- NEXTAUTH_URL=https://linkwarden.bunny-wyvern.ts.net/api/v1/auth
|
||||
- NEXTAUTH_SECRET=<redacted>
|
||||
depends_on:
|
||||
- postgres
|
||||
|
||||
linkwarden-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: linkwarden-tailscale-sidecar
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- linkwarden_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=linkwarden
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:linkwarden"
|
||||
|
||||
volumes:
|
||||
linkwarden_tailscale_state:
|
||||
```
|
||||
|
||||
## Data Layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `/home/artanis/DockerFiles/linkwarden/pgdata` | PostgreSQL data directory |
|
||||
| `/home/artanis/DockerFiles/linkwarden/data` | Linkwarden app data (archived pages, assets) |
|
||||
|
||||
## Notes
|
||||
- `NEXTAUTH_URL` must point to the Tailscale URL for auth to work correctly
|
||||
- A Meilisearch service was previously considered (commented out in compose) but not deployed
|
||||
150
21-Server Reference/homelab/stacks/matrix.md
Normal file
150
21-Server Reference/homelab/stacks/matrix.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Matrix
|
||||
|
||||
Self-hosted Matrix homeserver (Synapse) with multiple messaging bridges.
|
||||
|
||||
## Access
|
||||
- **Tailscale:** `matrix.bunny-wyvern.ts.net` (Synapse homeserver)
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `synapse` | `matrixdotorg/synapse:latest` | Matrix homeserver |
|
||||
| `matrix-db` | `postgres:16-alpine` | PostgreSQL database |
|
||||
| `matrix-tailscale` | `tailscale/tailscale:latest` | Tailscale node (shares synapse network) |
|
||||
| `mautrix-whatsapp` | `dock.mau.dev/mautrix/whatsapp:latest` | WhatsApp bridge |
|
||||
| `mautrix-gmessages` | `dock.mau.dev/mautrix/gmessages:latest` | Google Messages bridge |
|
||||
| `mautrix-slack` | `dock.mau.dev/mautrix/slack:latest` | Slack bridge |
|
||||
| `mautrix-discord` | `dock.mau.dev/mautrix/discord:latest` | Discord bridge |
|
||||
| `matrix-relay` | `matrix-matrix-relay` (local build) | Custom relay service |
|
||||
|
||||
## Network Architecture
|
||||
|
||||
All containers (except the Tailscale sidecar) communicate over a shared internal bridge network `matrix_matrix-internal` (`172.25.0.0/16`). No ports are exposed directly to the host — all external access goes through Tailscale on the `synapse` container.
|
||||
|
||||
| Container | Internal IP |
|
||||
|---|---|
|
||||
| `synapse` | `172.25.0.2` |
|
||||
| `mautrix-discord` | `172.25.0.3` |
|
||||
| `mautrix-whatsapp` | `172.25.0.4` |
|
||||
| `mautrix-gmessages` | `172.25.0.5` |
|
||||
| `matrix-db` | `172.25.0.6` |
|
||||
| `matrix-relay` | `172.25.0.7` |
|
||||
| `mautrix-slack` | `172.25.0.8` |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/Matrix/matrix/compose.yaml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
matrix-tailscale:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: matrix-tailscale
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- matrix_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=matrix
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:synapse"
|
||||
|
||||
matrix-db:
|
||||
image: postgres:16-alpine
|
||||
container_name: matrix-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: synapse
|
||||
POSTGRES_PASSWORD: <redacted>
|
||||
POSTGRES_DB: synapse
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Matrix/postgresdata:/var/lib/postgresql/data
|
||||
networks:
|
||||
- matrix-internal
|
||||
|
||||
synapse:
|
||||
image: matrixdotorg/synapse:latest
|
||||
container_name: synapse
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- matrix-db
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Matrix/synapsedata:/data
|
||||
networks:
|
||||
- matrix-internal
|
||||
|
||||
mautrix-whatsapp:
|
||||
image: dock.mau.dev/mautrix/whatsapp:latest
|
||||
container_name: mautrix-whatsapp
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Matrix/whatsappdata:/data
|
||||
networks:
|
||||
- matrix-internal
|
||||
|
||||
mautrix-gmessages:
|
||||
image: dock.mau.dev/mautrix/gmessages:latest
|
||||
container_name: mautrix-gmessages
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Matrix/gmessagesdata:/data
|
||||
networks:
|
||||
- matrix-internal
|
||||
|
||||
mautrix-slack:
|
||||
image: dock.mau.dev/mautrix/slack:latest
|
||||
container_name: mautrix-slack
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Matrix/slackdata:/data
|
||||
networks:
|
||||
- matrix-internal
|
||||
|
||||
mautrix-discord:
|
||||
image: dock.mau.dev/mautrix/discord:latest
|
||||
container_name: mautrix-discord
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Matrix/discorddata:/data
|
||||
networks:
|
||||
- matrix-internal
|
||||
depends_on:
|
||||
- matrix-db
|
||||
- synapse
|
||||
|
||||
matrix-relay:
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: matrix_relay.Dockerfile
|
||||
container_name: matrix-relay
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- matrix-internal
|
||||
|
||||
networks:
|
||||
matrix-internal:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
matrix_tailscale_state:
|
||||
```
|
||||
|
||||
## Data Layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `/home/artanis/DockerFiles/Matrix/postgresdata` | PostgreSQL data |
|
||||
| `/home/artanis/DockerFiles/Matrix/synapsedata` | Synapse config, media store |
|
||||
| `/home/artanis/DockerFiles/Matrix/whatsappdata` | WhatsApp bridge config/state |
|
||||
| `/home/artanis/DockerFiles/Matrix/gmessagesdata` | Google Messages bridge config/state |
|
||||
| `/home/artanis/DockerFiles/Matrix/slackdata` | Slack bridge config/state |
|
||||
| `/home/artanis/DockerFiles/Matrix/discorddata` | Discord bridge config/state |
|
||||
|
||||
## Notes
|
||||
- The `matrix-relay` container is built from a local `matrix_relay.Dockerfile` located one directory up from the compose file (`/home/artanis/DockerFiles/Matrix/`)
|
||||
- Synapse does not expose any ports to the host — it is only reachable via the `matrix_matrix-internal` network and through Tailscale
|
||||
- The Tailscale sidecar attaches to `synapse`'s network namespace, so Synapse's internal ports (8008, 8448) become accessible at `matrix.bunny-wyvern.ts.net`
|
||||
63
21-Server Reference/homelab/stacks/mealie.md
Normal file
63
21-Server Reference/homelab/stacks/mealie.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Mealie
|
||||
|
||||
Self-hosted recipe manager and meal planner.
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [mealie.bunny-wyvern.ts.net](https://mealie.bunny-wyvern.ts.net)
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `mealie` | `ghcr.io/mealie-recipes/mealie:latest` | Web app |
|
||||
| `mealie-tailscale-sidecar` | `tailscale/tailscale:latest` | Tailscale node |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/Mealie/docker-compose.yaml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
mealie:
|
||||
image: ghcr.io/mealie-recipes/mealie:latest
|
||||
container_name: mealie
|
||||
restart: always
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1000M
|
||||
volumes:
|
||||
- /home/artanis/DockerFiles/Mealie/data:/app/data/
|
||||
environment:
|
||||
ALLOW_SIGNUP: "false"
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
TZ: America/Chicago
|
||||
SECURITY_MAX_LOGIN_ATTEMPTS: 5
|
||||
SECURITY_USER_LOCKOUT_TIME: 1
|
||||
BASE_URL: https://mealie.bunny-wyvern.ts.net/
|
||||
|
||||
mealie-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: mealie-tailscale-sidecar
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- mealie_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=mealie
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:mealie"
|
||||
|
||||
volumes:
|
||||
mealie_tailscale_state:
|
||||
```
|
||||
|
||||
## Notes
|
||||
- Public signup is disabled — accounts must be created by an admin
|
||||
- Memory capped at 1 GB
|
||||
- Data is bind-mounted to `/home/artanis/DockerFiles/Mealie/data`
|
||||
- OpenAI/LLM integration was previously attempted (commented out in compose) — it was disabled because it was too resource-intensive and caused crashes
|
||||
58
21-Server Reference/homelab/stacks/melodix.md
Normal file
58
21-Server Reference/homelab/stacks/melodix.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Melodix
|
||||
|
||||
Discord music bot. Plays audio in Discord voice channels.
|
||||
|
||||
## Access
|
||||
Internal only — no web UI, no exposed ports. Controlled via Discord commands.
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `melodix` | `melodix-image` (local build) | Discord bot |
|
||||
|
||||
No Tailscale sidecar. The bot connects outbound to Discord's API.
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/melodix/melodix/docker/docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
melodix:
|
||||
container_name: melodix
|
||||
restart: always
|
||||
image: '${ALIAS}-image'
|
||||
volumes:
|
||||
- ./data/datastore.json:/usr/project/datastore.json
|
||||
- ./data/cache:/usr/project/cache
|
||||
environment:
|
||||
- DISCORD_TOKEN=${DISCORD_TOKEN}
|
||||
- ENCODE_VOLUME=${ENCODE_VOLUME}
|
||||
- ENCODE_CHANNELS=${ENCODE_CHANNELS}
|
||||
- ENCODE_FRAME_RATE=${ENCODE_FRAME_RATE}
|
||||
- ENCODE_FRAME_DURATION=${ENCODE_FRAME_DURATION}
|
||||
- ENCODE_BITRATE=${ENCODE_BITRATE}
|
||||
- ENCODE_COMPRESSION_LEVEL=${ENCODE_COMPRESSION_LEVEL}
|
||||
- ENCODE_PACKET_LOSS=${ENCODE_PACKET_LOSS}
|
||||
- ENCODE_BUFFERED_FRAMES=${ENCODE_BUFFERED_FRAMES}
|
||||
- ENCODE_VBR=${ENCODE_VBR}
|
||||
- ENCODE_VOLUME_FLOAT=${ENCODE_VOLUME_FLOAT}
|
||||
- ENCODE_RECONNECT_AT_EOF=${ENCODE_RECONNECT_AT_EOF}
|
||||
- ENCODE_RECONNECT_STREAMED=${ENCODE_RECONNECT_STREAMED}
|
||||
- ENCODE_RECONNECT_ON_NETWORK_ERROR=${ENCODE_RECONNECT_ON_NETWORK_ERROR}
|
||||
- ENCODE_RECONNECT_ON_HTTP_ERROR=${ENCODE_RECONNECT_ON_HTTP_ERROR}
|
||||
- ENCODE_RECONNECT_DELAY_MAX=${ENCODE_RECONNECT_DELAY_MAX}
|
||||
- ENCODE_FFMPEG_BINARY_PATH=${ENCODE_FFMPEG_BINARY_PATH}
|
||||
- ENCODE_ENCODING_LINE_LOG=${ENCODE_ENCODING_LINE_LOG}
|
||||
- ENCODE_USER_AGENT=${ENCODE_USER_AGENT}
|
||||
- ENCODE_RAW_OUTPUT=${ENCODE_RAW_OUTPUT}
|
||||
entrypoint: /usr/project/app
|
||||
```
|
||||
|
||||
## Notes
|
||||
- The image is built locally (`melodix-image`) — the build context and Dockerfile are in the parent directory of the compose file
|
||||
- All configuration comes from the `.env` file at `/home/artanis/DockerFiles/melodix/melodix/docker/.env`
|
||||
- `DISCORD_TOKEN` is the bot's Discord API token (in `.env`, redacted here)
|
||||
- The `ENCODE_*` variables control FFmpeg audio encoding settings for the voice stream
|
||||
- Data is stored via **relative bind mounts** (`./data/`) relative to the compose file directory — so at `/home/artanis/DockerFiles/melodix/melodix/docker/data/`
|
||||
- Dockhand shows this stack under the name `docker` (the stack name is derived from the compose working directory name)
|
||||
69
21-Server Reference/homelab/stacks/minecraft.md
Normal file
69
21-Server Reference/homelab/stacks/minecraft.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Minecraft Server
|
||||
|
||||
Self-hosted Minecraft server running the **TerraFirmaGreg: Modern** modpack.
|
||||
|
||||
## Access
|
||||
- **Host:** `192.168.2.114:25565` (LAN / Tailscale)
|
||||
- **Voice Chat:** `192.168.2.114:24454/udp`
|
||||
|
||||
No Tailscale sidecar — ports are exposed directly on the host.
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `minecraft` | `itzg/minecraft-server:latest` | Game server |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/Minecraft_Server/docker-compose.yaml`
|
||||
|
||||
> Note: This file lives outside the main `DockerFiles` directory. It is explicitly mounted into the Dockhand container so it can manage it.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server:latest
|
||||
container_name: minecraft
|
||||
mem_limit: 12g
|
||||
tty: true
|
||||
stdin_open: true
|
||||
ports:
|
||||
- 25565:25565
|
||||
- 24454:24454/udp # Voice Chat
|
||||
volumes:
|
||||
- /Minecraft_Server/Minecraft_Server/data:/data
|
||||
- /Minecraft_Server/Minecraft_Server/modpacks:/modpacks:ro
|
||||
- /Minecraft_Server/Minecraft_Server/downloads:/downloads
|
||||
environment:
|
||||
EULA: TRUE
|
||||
TYPE: AUTO_CURSEFORGE
|
||||
VERSION: 1.20.1
|
||||
CF_API_KEY: <redacted>
|
||||
CF_PAGE_URL: "https://www.curseforge.com/minecraft/modpacks/terrafirmagreg-modern/files/7665541"
|
||||
CF_BASE_DIR: /data
|
||||
INIT_MEMORY: 8G
|
||||
MAX_MEMORY: 12G
|
||||
ENABLE_AUTOPAUSE: true
|
||||
MAX_TICK_TIME: -1
|
||||
AUTOPAUSE_TIMEOUT_INIT: 600 # 10 min before pausing on empty server (init)
|
||||
AUTOPAUSE_TIMEOUT_EST: 1800 # 30 min before pausing (established)
|
||||
ENABLE_ROLLING_LOGS: true
|
||||
LOG_TIMESTAMP: true
|
||||
MOTD: "Why does Pingle sound like Pringle. Does Sam own Pringles?"
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## Data Layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `/Minecraft_Server/Minecraft_Server/data` | World saves, server config, plugins |
|
||||
| `/Minecraft_Server/Minecraft_Server/modpacks` | Modpack files (read-only) |
|
||||
| `/Minecraft_Server/Minecraft_Server/downloads` | CurseForge download cache |
|
||||
|
||||
## Notes
|
||||
- Uses `itzg/minecraft-server` with `AUTO_CURSEFORGE` type — it auto-downloads the modpack from CurseForge on startup if not already present
|
||||
- Modpack: **TerraFirmaGreg: Modern** (MC 1.20.1), pinned to a specific file ID (`7665541`)
|
||||
- Memory: 8 GB initial, 12 GB max (hard limit via `mem_limit: 12g`)
|
||||
- **Auto-pause** is enabled — server pauses after 30 minutes with no players, resumes on connection
|
||||
- `MAX_TICK_TIME: -1` disables the watchdog timer (prevents server shutdown if a tick takes too long, common with heavy modpacks)
|
||||
60
21-Server Reference/homelab/stacks/n8n.md
Normal file
60
21-Server Reference/homelab/stacks/n8n.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# n8n
|
||||
|
||||
Self-hosted workflow automation platform (similar to Zapier/Make).
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [n8n.bunny-wyvern.ts.net](https://n8n.bunny-wyvern.ts.net)
|
||||
- **LAN:** `http://192.168.2.114:5678`
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `n8n` | `docker.n8n.io/n8nio/n8n` | Web app + workflow engine |
|
||||
| `n8n-tailscale-sidecar` | `tailscale/tailscale:latest` | Tailscale node |
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/n8n/docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
n8n_storage:
|
||||
n8n_tailscale_state:
|
||||
|
||||
services:
|
||||
n8n:
|
||||
image: docker.n8n.io/n8nio/n8n
|
||||
restart: always
|
||||
pull_policy: always
|
||||
container_name: n8n
|
||||
environment:
|
||||
- DB_TYPE=sqlite
|
||||
- N8N_RUNNERS_ENABLED=true
|
||||
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
|
||||
ports:
|
||||
- 5678:5678
|
||||
volumes:
|
||||
- n8n_storage:/home/node/.n8n
|
||||
|
||||
n8n-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: n8n-tailscale-sidecar
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- n8n_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=n8n
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:n8n"
|
||||
```
|
||||
|
||||
## Notes
|
||||
- Database: SQLite (stored in the `n8n_storage` named volume)
|
||||
- `N8N_HOST` and `DOMAIN_NAME` are set via `.env` file at `/home/artanis/DockerFiles/n8n/.env`
|
||||
- `N8N_RUNNERS_ENABLED=true` enables the task runner mode for better workflow execution performance
|
||||
- `N8N_SECURE_COOKIE` is commented out — HTTPS is handled by Tailscale so cookies are secure by default
|
||||
62
21-Server Reference/homelab/stacks/openproject.md
Normal file
62
21-Server Reference/homelab/stacks/openproject.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# OpenProject
|
||||
|
||||
Self-hosted project management tool (tasks, timelines, wikis).
|
||||
|
||||
## Access
|
||||
- **Tailscale:** [openproject.bunny-wyvern.ts.net](https://openproject.bunny-wyvern.ts.net)
|
||||
- **LAN:** `http://192.168.2.114:5010`
|
||||
|
||||
## Containers
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `openproject` | `openproject/openproject:17` (pinned hash) | Web app (all-in-one) |
|
||||
| `openproject-tailscale-sidecar` | `tailscale/tailscale` (pinned hash) | Tailscale node |
|
||||
|
||||
> Both containers are running pinned image hashes rather than tags. This means they will not auto-update until the compose file is updated with a new image reference.
|
||||
|
||||
## Compose File
|
||||
**Path:** `/home/artanis/DockerFiles/openproject/docker-compose.yaml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
openproject:
|
||||
image: openproject/openproject:17
|
||||
container_name: openproject
|
||||
restart: always
|
||||
ports:
|
||||
- "5010:80"
|
||||
environment:
|
||||
- SECRET_KEY_BASE=<redacted>
|
||||
- OPENPROJECT_HOST__NAME=openproject.bunny-wyvern.ts.net
|
||||
- OPENPROJECT_HTTPS=true
|
||||
- OPENPROJECT_DEFAULT__LANGUAGE=en
|
||||
stdin_open: true
|
||||
tty: true
|
||||
|
||||
openproject-tailscale-sidecar:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: openproject-tailscale-sidecar
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- openproject_tailscale_state:/var/lib/tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY=<redacted>
|
||||
- TS_HOSTNAME=openproject
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
network_mode: "service:openproject"
|
||||
|
||||
volumes:
|
||||
openproject_tailscale_state:
|
||||
```
|
||||
|
||||
## Notes
|
||||
- Uses the **all-in-one** OpenProject image (includes database, worker, web server in a single container)
|
||||
- Version pinned to `17`
|
||||
- `OPENPROJECT_HTTPS=true` tells OpenProject it is behind HTTPS (needed for correct URL generation even though TLS is terminated by Tailscale, not OpenProject itself)
|
||||
- Data is stored in two **anonymous volumes** (auto-generated hashes) — this means data is not trivially accessible on the host filesystem. Use `docker volume inspect` or the Dockhand volume browser to locate them
|
||||
- There are orphaned volumes from earlier OpenProject stack iterations: `open-project_open_project_tailscale_state`, `open-project_openproject_tailscale_state`, and `openproject_openproject_tailscale_state`
|
||||
Reference in New Issue
Block a user