feat: initialize serverAppConfigs with podman stacks for Dankserver and Dankclaw
- Dankserver stack: RomM, Copyparty, Calibre-Web, node-exporter - Dankclaw stack: Gluetun VPN (SearXNG tunnel), SearXNG+Valkey, ComfyUI (CPU backend), OpenWebUI, Hermes, Gitea+Postgres (migrated), Caddy reverse proxy, Grafana+Prometheus+Loki+Alloy observability - Caddyfiles with .local hostname convention and basicauth homepage - bind-mount storage policy, no named volumes - deploy.sh mirroring vllmScripts git workflow (push -> pull -> restart -> health) - docs/ Obsidian vault: per-service docs from frank-default-small research subagents (promtail EOL -> Alloy; gitea SECRET_KEY preservation; ComfyUI --cpu) - bats test suite at 6 seams — 22 tests green
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# Deployment Flow
|
||||
|
||||
Deployment mirrors the `vllmScripts` repository: git is the single source of truth, and a `deploy.sh` script moves committed changes to the target hosts over SSH.
|
||||
|
||||
## Workflow
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Edit in this repo] --> B[Commit]
|
||||
B --> C[Push to origin]
|
||||
C --> D[deploy.sh: pull on target]
|
||||
D --> E[restart stack]
|
||||
E --> F[health check]
|
||||
```
|
||||
|
||||
1. Edit files locally in this repository.
|
||||
2. Commit and push.
|
||||
3. Run `./scripts/deploy.sh <dankclaw|dankserver>`.
|
||||
4. The script pulls the repo on the target and restarts the podman stack.
|
||||
5. It verifies service health after restart.
|
||||
|
||||
## Deploy Script
|
||||
|
||||
```
|
||||
./scripts/deploy.sh dankclaw # pull + restart on Dankclaw
|
||||
./scripts/deploy.sh dankserver # pull + restart on Dankserver
|
||||
./scripts/deploy.sh dankclaw --dry-run
|
||||
```
|
||||
|
||||
SSH uses the existing key pair (`dank@dankclaw`, `dank@dankserver`). No passwords are stored or documented in this repo. If sudo is needed, use the interactive sudo on the target — never commit a password.
|
||||
|
||||
## Targets
|
||||
|
||||
| Target | Host | Stack |
|
||||
|--------|------|-------|
|
||||
| dankclaw | dank@dankclaw (192.168.0.143) | `dankclaw/` |
|
||||
| dankserver | dank@dankserver (192.168.0.235) | `dankserver/` |
|
||||
|
||||
## Health Verification
|
||||
|
||||
The deploy script polls the health endpoint of each service after restart. Service healthchecks are defined in each compose file. A service that fails its healthcheck is reported, not hidden.
|
||||
|
||||
## Tests
|
||||
|
||||
Run the test suite before pushing:
|
||||
|
||||
```
|
||||
./tests/run.sh
|
||||
```
|
||||
|
||||
The suite validates compose YAML, env consistency, Caddyfiles, docs completeness, and script syntax. See [[Testing Policy]].
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Storage Policy]]
|
||||
- [[Testing Policy]]
|
||||
- [vllmScripts deployment docs](../../../vllmScripts/docs/deployment.md) — the model this follows
|
||||
@@ -0,0 +1,54 @@
|
||||
# Network Architecture
|
||||
|
||||
Both hosts run Caddy as the single entry point. Every service is reachable by hostname; the router firewall governs external access. On Dankclaw, SearXNG's outbound traffic exits through the Gluetun VPN container.
|
||||
|
||||
## Topology
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph WAN[Router 192.168.0.1 firewall]
|
||||
EXT[Internet]
|
||||
end
|
||||
EXT -->|port forward| DS[Caddy Dankserver]
|
||||
EXT -->|port forward| DC[Caddy Dankclaw]
|
||||
subgraph Dankserver[192.168.0.235]
|
||||
DS --> R[RomM :8085]
|
||||
DS --> P[Copyparty :3923]
|
||||
DS --> W[Calibre-Web :8083]
|
||||
end
|
||||
subgraph Dankclaw[192.168.0.143]
|
||||
DC --> O[OpenWebUI :3000]
|
||||
DC --> G[Gitea :3001]
|
||||
DC --> F[ComfyUI :8188]
|
||||
DC --> GR[Grafana :3002]
|
||||
DC --> PR[Prometheus :9090]
|
||||
DC --> SE[SearXNG :8081]
|
||||
SE -->|network_mode service| GL[Gluetun VPN]
|
||||
GL -->|tunnel| EXT
|
||||
end
|
||||
```
|
||||
|
||||
## Hostnames
|
||||
|
||||
| Host | Convention |
|
||||
|------|------------|
|
||||
| Dankserver | `*.dankserver.local` → Caddy → service |
|
||||
| Dankclaw | `*.dankclaw.local` → Caddy → service |
|
||||
|
||||
Users never type ports; Caddy maps names to upstreams.
|
||||
|
||||
## Gluetun Path (SearXNG only)
|
||||
|
||||
SearXNG attaches to the Gluetun network namespace (`network_mode: service:gluetun`). Only SearXNG shares the tunnel. Everything else on Dankclaw uses the normal LAN route. This matches KB Pattern 2 in [[VPN Routing for SearXNG]].
|
||||
|
||||
## Access Policy
|
||||
|
||||
- All services assume external access is possible; the **router firewall** governs what the WAN can reach.
|
||||
- Caddy adds HTTP basic auth on the homepage and on sensitive services.
|
||||
- LAN subnet: `192.168.0.0/24`.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Dankserver Stack]], [[Dankclaw Stack]]
|
||||
- [[Caddy]], [[Gluetun]]
|
||||
- Knowledge base: [[VPN Routing for SearXNG]], [[SearXNG Tuning]]
|
||||
@@ -0,0 +1,40 @@
|
||||
# Storage Policy
|
||||
|
||||
All persistent data uses **bind mounts**: a host directory mapped directly into the container. No named volumes. This matches the preference of this repo and the existing Gitea stack on Dankclaw.
|
||||
|
||||
## Why Bind Mounts
|
||||
|
||||
- The exact host location of every byte is visible and controllable.
|
||||
- Backups are a simple `tar` of known host directories.
|
||||
- The data survives container recreation and `podman-compose down`.
|
||||
- Ownership is explicit: everything runs as UID 1000 (`dank`) so host tools can read it.
|
||||
|
||||
## Conventions
|
||||
|
||||
| Stack | Host root |
|
||||
|-------|-----------|
|
||||
| Dankserver | `/opt/<service>/...` |
|
||||
| Dankclaw | `/opt/<service>/...` (Gitea keeps `/opt/gitea/data/...`) |
|
||||
|
||||
## Ownership
|
||||
|
||||
Containers run as `PUID=1000` / `PGID=1000`. Host directories must be owned by `dank`:
|
||||
|
||||
```bash
|
||||
sudo chown -R 1000:1000 /opt/<service>
|
||||
```
|
||||
|
||||
## Secrets
|
||||
|
||||
Secrets never live in bind-mounted configs that get committed. They are:
|
||||
|
||||
1. Set in `.env` files on the host (git-ignored, `.env.example` committed as template), or
|
||||
2. Injected as environment variables from the deploy script.
|
||||
|
||||
The live Gitea database password exists only in `.env` on Dankclaw. A test enforces that it never appears in this repo.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Deployment Flow]]
|
||||
- [[Gitea]] — the existing bind-mount stack being migrated
|
||||
- [[Backblaze Integration]] — future backup target for these mounts
|
||||
@@ -0,0 +1,23 @@
|
||||
# Testing Policy
|
||||
|
||||
This repository tests its configuration at defined seams. The tests run with `bats`; run them with `./tests/run.sh` before every push.
|
||||
|
||||
## Seams Under Test
|
||||
|
||||
| Seam | File | What it asserts |
|
||||
|------|------|-----------------|
|
||||
| Compose validity | `tests/compose_validity.bats` | YAML parses, services have images, no named volumes |
|
||||
| Env consistency | `tests/env_consistency.bats` | every `${VAR}` is defined in `.env.example`; no real secrets; the live gitea password never appears |
|
||||
| Caddyfile validity | `tests/caddyfile.bats` | per-host Caddyfile, `.local` convention, balanced braces, basic auth present |
|
||||
| Docs completeness | `tests/docs_completeness.bats` | every compose service has a docs page; index links every page |
|
||||
| Script syntax | `tests/scripts_syntax.bats` | `bash -n` clean, executable bits, shellcheck when available |
|
||||
| Deployment flow | `tests/deployment_flow.bats` | deploy.sh exists, targets known, SSH reachable (skips offline) |
|
||||
|
||||
## Red-Green
|
||||
|
||||
Tests are written first. A failing test means the seam is not satisfied; the config change that makes it pass is the only acceptable fix. No `--no-verify`, no deleting tests without approval.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Deployment Flow]]
|
||||
- [[index]]
|
||||
Reference in New Issue
Block a user