docs: README neu strukturiert — vollständiger Katalog, Pattern, Security-Konventionen, PR-Pflicht
This commit is contained in:
@@ -1,35 +1,65 @@
|
|||||||
# luki-net / proxmox-scripts
|
# luki-net / proxmox-scripts
|
||||||
|
|
||||||
Community-script-style installers for LXC services in my Proxmox VE homelab. Each script creates an unprivileged Debian 12 LXC and installs one specific app, with sensible defaults and interactive prompts.
|
Community-script-style installers for LXC services in the luki-net Proxmox VE homelab. Each script creates an unprivileged Debian 12 LXC and installs one specific app — sensible defaults, interactive prompts, env-overridable for non-interactive runs.
|
||||||
|
|
||||||
Inspired by [community-scripts/ProxmoxVE](https://github.com/community-scripts/ProxmoxVE), but minimal, self-hosted and tailored to my stack.
|
Inspired by [community-scripts/ProxmoxVE](https://github.com/community-scripts/ProxmoxVE), but minimal, self-hosted and tailored to this stack.
|
||||||
|
|
||||||
## Available scripts
|
## Script catalog
|
||||||
|
|
||||||
| App | Description | One-liner |
|
| App | What it provisions | Status |
|
||||||
|-----|-------------|-----------|
|
|-----|--------------------|--------|
|
||||||
| [devpi](ct/devpi.sh) | Private PyPI cache / mirror — saves time on CUDA/torch rebuilds | `bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/devpi.sh)"` |
|
| [devpi](ct/devpi.sh) | Private PyPI cache/mirror — saves time on CUDA/torch rebuilds | ✅ stable |
|
||||||
| [webapp](ct/webapp.sh) | Next.js site with deploy-as-code via a self-hosted Gitea Actions runner (host mode, no inbound port) | `bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/webapp.sh)"` |
|
| [webapp](ct/webapp.sh) | Next.js site with deploy-as-code via a repo-scoped Gitea Actions runner (host mode, no inbound port) | ✅ stable |
|
||||||
|
| [nexus](ct/nexus.sh) | App LXC for [nexus](https://gitea.luki-net.org/l.kirchner/nexus-hub) (Family Knowledge Hub): host-mode runner (label `nexus`, CI + deploy), service skeleton, `/opt/nexus` layout. Runtime is provisioned/extended via [`install/nexus-runtime.sh`](install/nexus-runtime.sh) (idempotent, re-runnable) | ✅ in production |
|
||||||
|
| [nexus-db](ct/nexus-db.sh) | PostgreSQL 16 + pgvector for nexus — least-privilege role, pg_hba allowlist (only the nexus LXC), DSN handed over via credentials file | ✅ in production |
|
||||||
|
| [authentik](ct/authentik.sh) | Central homelab IdP (official Docker Compose via LXC nesting) — headless bootstrap admin **and** API token for agent-driven blueprint configuration, blueprints mount, permanent auth domain (WebAuthn RP-ID) | ✅ in production |
|
||||||
|
| [runner](ct/runner.sh) | General **instance-wide** Gitea Actions runner (label `homelab`) — Docker for throwaway CI test containers, deliberately **no** sudoers/deploy rights | 🔄 in review ([PR #6](https://gitea.luki-net.org/luki-net/proxmox-scripts/pulls/6)) |
|
||||||
|
|
||||||
|
Run any one-liner on a Proxmox VE host as root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/<app>.sh)"
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Run any one-liner on a Proxmox VE host as root (Web UI → Node → Shell works fine). You'll be prompted for CTID, hostname, disk, RAM, CPU, bridge, storage and IP. Defaults are sane.
|
Interactive prompts cover CTID, hostname, disk, RAM, CPU, bridge/VLAN, storage, IP/gateway/DNS — plus app-specific values. Defaults are sane. Non-interactive override via env vars:
|
||||||
|
|
||||||
Non-interactive override via env vars:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
CTID=200 HOSTNAME=devpi DISK_SIZE=30 RAM=4096 CORES=4 IPCFG=dhcp \
|
CTID=200 HOSTNAME=devpi DISK_SIZE=30 RAM=4096 CORES=4 IPCFG=dhcp \
|
||||||
bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/devpi.sh)"
|
bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/devpi.sh)"
|
||||||
```
|
```
|
||||||
|
|
||||||
All defaults (`DEFAULT_HOSTNAME`, `DEFAULT_DISK`, …) are settable per-call via env vars as well.
|
All defaults (`DEFAULT_HOSTNAME`, `DEFAULT_DISK`, …) and app config values are settable per call via env vars.
|
||||||
|
|
||||||
|
## The pattern
|
||||||
|
|
||||||
|
Two files per app, both sourcing the shared libs via `curl`:
|
||||||
|
|
||||||
|
- **`ct/<app>.sh`** runs on the PVE host: prompts → unprivileged LXC → pushes a config env file into the container → bootstraps the installer. Apps that need Docker (authentik, runner) enable `nesting+keyctl` automatically.
|
||||||
|
- **`install/<app>-install.sh`** runs inside the LXC: packages, unprivileged app user, secrets generated on-host (never printed), systemd units, a `/root/<app>.credentials` notes file — then shreds the bootstrap env. Idempotent where it matters: re-runs skip what exists.
|
||||||
|
|
||||||
|
Shared libs: [`lib/build.func`](lib/build.func) (host-side: prompts, LXC create, bootstrap) and [`lib/install.func`](lib/install.func) (in-container: apt, users, systemd, http-wait).
|
||||||
|
|
||||||
|
## Security conventions
|
||||||
|
|
||||||
|
- Unprivileged LXCs only; app processes run as dedicated system users.
|
||||||
|
- Least privilege everywhere: narrow sudoers (exact-match commands — sudoers compares **verbatim incl. arguments**), DB allowlists, LAN-only binds for inference ports.
|
||||||
|
- Secrets are generated on the target host and live in `0600` files — never in the repo, the wiki or chat logs.
|
||||||
|
- **Runner separation:** the nexus runner is repo-scoped and lives on the production LXC *because* it holds deploy rights; the general `runner` LXC is instance-wide *because* it holds none. Don't mix these scopes.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
**All changes go through a pull request with cross-review** (Claude Code ↔ Codex, or a human) — no direct pushes to `main`. This rule exists because of two real incidents where an un-reviewed script shipped a missing `source build.func` (see wiki → Lessons). CI (`bash -n`, source-check, validation suite) is being introduced with [PR #5](https://gitea.luki-net.org/luki-net/proxmox-scripts/pulls/5) and runs on the `homelab` runner.
|
||||||
|
|
||||||
|
How to add a script: [docs/adding-a-script.md](docs/adding-a-script.md).
|
||||||
|
|
||||||
## Repo layout
|
## Repo layout
|
||||||
|
|
||||||
```
|
```
|
||||||
.
|
.
|
||||||
├── ct/ # Host-side scripts, one per app
|
├── ct/ # Host-side scripts, one per app
|
||||||
├── install/ # In-container installers, one per app
|
├── install/ # In-container installers (+ nexus-runtime.sh re-provisioner)
|
||||||
├── lib/
|
├── lib/
|
||||||
│ ├── build.func # Shared host-side helpers (prompts, LXC create, bootstrap)
|
│ ├── build.func # Shared host-side helpers (prompts, LXC create, bootstrap)
|
||||||
│ └── install.func # Shared in-container helpers (apt, systemd, users, http-wait)
|
│ └── install.func # Shared in-container helpers (apt, systemd, users, http-wait)
|
||||||
@@ -39,9 +69,10 @@ All defaults (`DEFAULT_HOSTNAME`, `DEFAULT_DISK`, …) are settable per-call via
|
|||||||
└── LICENSE
|
└── LICENSE
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding a new script
|
## Related
|
||||||
|
|
||||||
See [docs/adding-a-script.md](docs/adding-a-script.md). Two files per app, both source the shared libs via `curl`.
|
- [nexus-hub](https://gitea.luki-net.org/l.kirchner/nexus-hub) — Family Knowledge Hub (main consumer of nexus/nexus-db/authentik/runner)
|
||||||
|
- [Wiki](https://gitea.luki-net.org/luki-net/proxmox-scripts/wiki) — per-app runbook pointers, conventions, lessons learned
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user