You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Publish Mast as a Proxmox LXC template so a user can launch it on their homelab with a one-liner. The LXC bootstraps itself as Mast's first managed server + release on first boot, so a fresh install already has something live on the dashboard.
Why this shape
Proxmox is the primary deployment target for the maintainer's homelab.
The community-scripts ecosystem (post-tteck) is where Proxmox homelabbers actually look for new apps; standing alongside that catalog is the path of least friction.
Mast manages Linux boxes running Elixir releases. The LXC is one. Self-managing it on first boot doubles as a smoke test and a built-in demo.
Build approach
Tool: `distrobuilder` (LXC's own image builder, YAML def).
Produces a `rootfs.tar.zst` from a Debian base + provisioning steps.
Packer's Proxmox plugin targets VMs, not LXC. Skip it.
Alternative for later: `nixos-generators -f proxmox-lxc` if/when the Nix track matures (see companion issue).
Create `mast` system user, narrow sudoers entry for `/usr/bin/apt` only
Disable Postgres listener on TCP, keep unix socket only
Distribution
Two paths, both worth doing:
Prebuilt rootfs on GitHub Releases: `mast--lxc.tar.zst`. User runs `pveam` import or drops it in `/var/lib/vz/template/cache/` and `pct create`s from it.
community-scripts/ProxmoxVE PR (later): `ct/mast.sh` + `install/mast-install.sh`. Their convention runs on a fresh Debian CT and apt-installs Mast. Higher reach, more support surface — do after Inline 'paste new key' form in Add System modal #1 is stable.
Self-managing first server
The defining feature. A `mast-bootstrap.service` (oneshot, `Wants=mast.service`, `After=mast.service postgresql.service`) runs once on first boot:
Generates an Ed25519 keypair at `/var/lib/mast/self.key` (mode 0600, owner `mast`).
Appends the pubkey to the `mast` user's `~/.ssh/authorized_keys`.
Build script: `scripts/build-lxc.sh` that produces `rootfs.tar.zst` and ships SHA256.
`Mast.Bootstrap` module with `self_enroll!/0`, idempotent.
`mast-bootstrap.service` + `mast.service` unit files in `rel/lxc/`.
README section: "Install on Proxmox" with the `pveam`/`pct create` commands.
GitHub Actions workflow that builds the rootfs on tag push.
Out:
community-scripts PR (separate follow-up).
Multi-arch (x86_64 only for v1; aarch64 once anyone asks).
LXC -> VM migration tooling.
Open questions
Postgres bundled vs Postgres-on-another-CT: bundled for v1 (one-click). Note the override path in docs.
Mast user privileges: `sudo -n apt` only, no general sudo. Confirm the patch worker still works with this narrowing (it should — patches.ex already prefixes `sudo -n`).
Self-enrolled server's SSH key: stored encrypted via `Mast.Vault` like any other, but the plaintext is on the same box. Document this in the LXC README so operators understand the trust model (compromising the CT compromises that key — but that key only grants access to the CT itself, so the blast radius is the CT, not the fleet).
LXC template versioning: tie to app version (`mast-0.6.0-lxc.tar.zst`) or rolling (`mast-lxc-latest.tar.zst`)? Probably both — latest + versioned.
Related
Companion issue: Nix flake distribution.
ADR 0005 (no host agent) — unchanged. The self-managed first server uses the existing SSH path, not an agent.
ADR 0006 (SSH key storage) — applies to the self-enrolled key.
Summary
Publish Mast as a Proxmox LXC template so a user can launch it on their homelab with a one-liner. The LXC bootstraps itself as Mast's first managed server + release on first boot, so a fresh install already has something live on the dashboard.
Why this shape
Build approach
Tool: `distrobuilder` (LXC's own image builder, YAML def).
Provisioning steps inside the image build:
Distribution
Two paths, both worth doing:
Self-managing first server
The defining feature. A `mast-bootstrap.service` (oneshot, `Wants=mast.service`, `After=mast.service postgresql.service`) runs once on first boot:
Gating:
Secret bootstrap
Generated at install time, not baked into the image:
```
/opt/mast/.env (mode 0600, owner mast)
SECRET_KEY_BASE=<openssl rand -base64 48>
DATABASE_URL=postgresql:///mast?host=/var/run/postgresql
PHX_HOST=<hostname -f>
MAST_SELF_MANAGE=true
```
Systemd: `EnvironmentFile=/opt/mast/.env`.
Admin user: created on first web visit (existing `setup_live` flow if present, or first registration becomes admin).
Systemd units to ship
Scope
In:
Out:
Open questions
Related