feat(tools): ansipa-proxmox-lxc.sh — pre-configured full-stack ansipa Proxmox LXC
Generate everything needed to run the complete ansipa stack (FreeIPA + CheckMK
+ Keycloak + PostgreSQL + nginx gateway) inside a single Proxmox LXC container.
Unlike freeipa-image.sh's proxmox-lxc target (which exports a FreeIPA-only CT
rootfs), this runs the tested docker-compose stack inside a privileged,
nesting-enabled CT ("Docker-in-LXC"), so it is the whole management plane in
one container.
Prompts for domain/realm/VMID/resources, generates all service secrets, and
emits: pct-create-<vmid>.sh, ansipa-<vmid>.conf (nesting=1,keyctl=1,fuse=1 +
the cgroup/apparmor allowances FreeIPA's systemd and Docker overlay2 need), a
first-boot provisioner that installs Docker and brings the stack up via run.sh,
a filled-in .env (mode 600), and a DEPLOY guide. Verified the generator emits
correct, syntactically-valid artifacts. Documented in the ansipa Setup Guide.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MUhrcFU8J1Hnf7vNqNxZNi
feat/astal-menu
parent
a73bc7cb93
commit
baf5e73cc1
|
|
@ -192,6 +192,35 @@ container-internal `172.30.0.12`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Deploying as a Proxmox LXC container
|
||||||
|
|
||||||
|
To run the whole stack as a single Proxmox container, use the generator:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash setup/tools/ansipa-proxmox-lxc.sh [OUT_DIR] # default ~/ansipa-lxc-out
|
||||||
|
```
|
||||||
|
|
||||||
|
It prompts for domain/realm/VMID/resources, generates all secrets, and writes:
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `pct-create-<vmid>.sh` | `pct create` command — run on the Proxmox host |
|
||||||
|
| `ansipa-<vmid>.conf` | LXC options to append to `/etc/pve/lxc/<vmid>.conf` |
|
||||||
|
| `ansipa-provision.sh` | first-boot provisioner (installs Docker, brings the stack up) |
|
||||||
|
| `.env` | filled-in stack environment (generated passwords — mode 600) |
|
||||||
|
| `DEPLOY-<vmid>.md` | step-by-step guide |
|
||||||
|
|
||||||
|
The container is **privileged** with `nesting=1,keyctl=1,fuse=1` — required for
|
||||||
|
FreeIPA's systemd + Kerberos keyrings and Docker's overlay2. It runs the same
|
||||||
|
tested docker-compose stack inside the CT ("Docker-in-LXC"), so it is the full
|
||||||
|
ansipa deployment in one Proxmox container. Size it ≥6 GB RAM.
|
||||||
|
|
||||||
|
> `setup/tools/freeipa-image.sh` has a separate `proxmox-lxc` target that
|
||||||
|
> exports a **FreeIPA-only** CT rootfs (no CheckMK/Keycloak/nginx) — use that if
|
||||||
|
> you want just the identity server; use `ansipa-proxmox-lxc.sh` for the full stack.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Client enrollment
|
## Client enrollment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,8 @@ Dotfiles/
|
||||||
│ │ ├── wds-deploy.sh # package netboot artifacts for WDS/PXE
|
│ │ ├── wds-deploy.sh # package netboot artifacts for WDS/PXE
|
||||||
│ │ ├── write-usb.sh # write the ISO to a USB stick
|
│ │ ├── write-usb.sh # write the ISO to a USB stick
|
||||||
│ │ ├── generate-answerfile.sh # dry-run to produce answerfile.json
|
│ │ ├── generate-answerfile.sh # dry-run to produce answerfile.json
|
||||||
│ │ ├── proxmox-lxc-gen.sh # Proxmox LXC container generator (TUI)
|
│ │ ├── proxmox-lxc-gen.sh # generic Proxmox LXC container generator (TUI)
|
||||||
|
│ │ ├── ansipa-proxmox-lxc.sh # pre-configured full ansipa stack as a Proxmox LXC
|
||||||
│ │ └── freeipa-image.sh # build the ansipa FreeIPA container image
|
│ │ └── freeipa-image.sh # build the ansipa FreeIPA container image
|
||||||
│ └── modules/ # Modular install scripts
|
│ └── modules/ # Modular install scripts
|
||||||
├── desktopenvs/hyprlua/ # HyprLua (Lua-based Hyprland) configs
|
├── desktopenvs/hyprlua/ # HyprLua (Lua-based Hyprland) configs
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,241 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# =============================================================================
|
||||||
|
# ansipa-proxmox-lxc.sh — generate a pre-configured ansipa Proxmox LXC container
|
||||||
|
#
|
||||||
|
# Produces everything needed to stand up the FULL ansipa stack (FreeIPA +
|
||||||
|
# CheckMK + Keycloak + PostgreSQL + nginx gateway) inside a single Proxmox LXC
|
||||||
|
# container, using the tested docker-compose deployment run inside the CT
|
||||||
|
# ("Docker-in-LXC"). This is the whole management plane in one container, unlike
|
||||||
|
# freeipa-image.sh's proxmox-lxc target which exports a FreeIPA-only rootfs.
|
||||||
|
#
|
||||||
|
# Why Docker-in-LXC instead of native install:
|
||||||
|
# FreeIPA + CheckMK + Keycloak are already packaged and wired together as a
|
||||||
|
# compose stack that this repo tests end-to-end. Running that stack inside a
|
||||||
|
# privileged, nesting-enabled LXC reuses all of it verbatim and keeps the
|
||||||
|
# Proxmox container reproducible.
|
||||||
|
#
|
||||||
|
# OUTPUT (written to an output dir, default ~/ansipa-lxc-out):
|
||||||
|
# pct-create-<vmid>.sh runnable pct create command (run on the Proxmox host)
|
||||||
|
# ansipa-<vmid>.conf LXC options to append to /etc/pve/lxc/<vmid>.conf
|
||||||
|
# ansipa-provision.sh first-boot provisioner (installs Docker + brings the
|
||||||
|
# stack up); copied into the CT and run once
|
||||||
|
# .env filled-in ansipa stack environment (secrets!)
|
||||||
|
# DEPLOY-<vmid>.md step-by-step deployment guide
|
||||||
|
#
|
||||||
|
# Requirements on the workstation running THIS script: bash, openssl (for
|
||||||
|
# password generation). The Proxmox host needs a Debian 12 CT template.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
DOTFILES_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
IMAGE_SRC="$DOTFILES_DIR/setup/modules/FreeipaAnsible/image"
|
||||||
|
|
||||||
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'; CYAN='\033[0;36m'; MAGENTA='\033[0;35m'; NC='\033[0m'
|
||||||
|
log() { echo -e "${GREEN}[+]${NC} $*"; }
|
||||||
|
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||||
|
error() { echo -e "${RED}[✗]${NC} $*" >&2; }
|
||||||
|
info() { echo -e "${CYAN}[i]${NC} $*"; }
|
||||||
|
section() { echo -e "\n${BLUE}━━━ $* ━━━${NC}"; }
|
||||||
|
ask() { printf "${MAGENTA}[?]${NC} %s " "$*"; }
|
||||||
|
|
||||||
|
[[ $EUID -eq 0 ]] && { error "Run as your normal user (not root)."; exit 1; }
|
||||||
|
|
||||||
|
gen_pw() { openssl rand -base64 18 2>/dev/null | tr -d '/+=' | cut -c1-20; }
|
||||||
|
|
||||||
|
# ─── Gather configuration ─────────────────────────────────────────────────────
|
||||||
|
section "ansipa Proxmox LXC generator"
|
||||||
|
info "Generates a pre-configured full-stack ansipa container for Proxmox."
|
||||||
|
echo
|
||||||
|
|
||||||
|
ask "IPA domain (e.g. corp.example.com):"; read -r IPA_DOMAIN
|
||||||
|
[[ -z "$IPA_DOMAIN" ]] && { error "IPA domain is required."; exit 1; }
|
||||||
|
ask "IPA server FQDN [ipa.$IPA_DOMAIN]:"; read -r I; IPA_HOSTNAME="${I:-ipa.$IPA_DOMAIN}"
|
||||||
|
ask "Kerberos realm [${IPA_DOMAIN^^}]:"; read -r I; IPA_REALM="${I:-${IPA_DOMAIN^^}}"
|
||||||
|
|
||||||
|
ask "Proxmox VMID [910]:"; read -r I; VMID="${I:-910}"
|
||||||
|
ask "CT hostname [ansipa]:"; read -r I; CT_HOSTNAME="${I:-ansipa}"
|
||||||
|
ask "Proxmox storage [local-lvm]:"; read -r I; PVE_STORAGE="${I:-local-lvm}"
|
||||||
|
ask "Template storage [local]:"; read -r I; TPL_STORAGE="${I:-local}"
|
||||||
|
ask "Debian CT template [debian-12-standard_12.7-1_amd64.tar.zst]:"; read -r I
|
||||||
|
CT_TEMPLATE="${I:-debian-12-standard_12.7-1_amd64.tar.zst}"
|
||||||
|
# FreeIPA alone wants ~2 GB; the full stack (CheckMK/Keycloak/Postgres) needs headroom.
|
||||||
|
ask "RAM MB [6144]:"; read -r I; CT_RAM="${I:-6144}"
|
||||||
|
ask "Cores [4]:"; read -r I; CT_CORES="${I:-4}"
|
||||||
|
ask "Disk GB [20]:"; read -r I; CT_DISK="${I:-20}"
|
||||||
|
ask "Bridge [vmbr0]:"; read -r I; CT_BRIDGE="${I:-vmbr0}"
|
||||||
|
ask "Static IP CIDR or 'dhcp' [dhcp]:"; read -r I; CT_IP="${I:-dhcp}"
|
||||||
|
ask "Advertised CheckMK URL for clients (e.g. http://ansipa.$IPA_DOMAIN:8090) [blank=set later]:"
|
||||||
|
read -r CMK_ADVERTISED_URL
|
||||||
|
|
||||||
|
OUT_DIR="${1:-$HOME/ansipa-lxc-out}"
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
# ─── Generate secrets ─────────────────────────────────────────────────────────
|
||||||
|
section "Generating secrets"
|
||||||
|
IPA_ADMIN_PASSWORD=$(gen_pw); IPA_DM_PASSWORD=$(gen_pw)
|
||||||
|
CMK_ADMIN_PASSWORD=$(gen_pw); KC_ADMIN_PASSWORD=$(gen_pw); KC_DB_PASSWORD=$(gen_pw)
|
||||||
|
SMB_SCAN_PASSWORD=$(gen_pw); LUKS_KEY_UPLOAD_PASSWORD=$(gen_pw)
|
||||||
|
log "Generated admin/service passwords (saved in $OUT_DIR/.env — keep it safe)."
|
||||||
|
|
||||||
|
# ─── .env for the ansipa stack ────────────────────────────────────────────────
|
||||||
|
cat > "$OUT_DIR/.env" <<EOF
|
||||||
|
# ansipa stack environment — generated by ansipa-proxmox-lxc.sh
|
||||||
|
IPA_HOSTNAME=$IPA_HOSTNAME
|
||||||
|
IPA_DOMAIN=$IPA_DOMAIN
|
||||||
|
IPA_REALM=$IPA_REALM
|
||||||
|
IPA_ADMIN_PASSWORD=$IPA_ADMIN_PASSWORD
|
||||||
|
IPA_DM_PASSWORD=$IPA_DM_PASSWORD
|
||||||
|
IPA_SETUP_DNS=false
|
||||||
|
IPA_SETUP_KRA=false
|
||||||
|
|
||||||
|
SMB_SCAN_PASSWORD=$SMB_SCAN_PASSWORD
|
||||||
|
LUKS_KEY_UPLOAD_PASSWORD=$LUKS_KEY_UPLOAD_PASSWORD
|
||||||
|
|
||||||
|
CMK_ADMIN_PASSWORD=$CMK_ADMIN_PASSWORD
|
||||||
|
CMK_SITE_ID=cmk
|
||||||
|
CMK_ADVERTISED_URL=$CMK_ADVERTISED_URL
|
||||||
|
|
||||||
|
KC_HOSTNAME=${IPA_HOSTNAME/ipa./sso.}
|
||||||
|
KC_ADMIN=admin
|
||||||
|
KC_ADMIN_PASSWORD=$KC_ADMIN_PASSWORD
|
||||||
|
KC_DB_PASSWORD=$KC_DB_PASSWORD
|
||||||
|
|
||||||
|
ANSIPA_HTTP_PORT=8088
|
||||||
|
EOF
|
||||||
|
chmod 600 "$OUT_DIR/.env"
|
||||||
|
|
||||||
|
# ─── pct create script ────────────────────────────────────────────────────────
|
||||||
|
# Privileged + nesting + keyctl + fuse: FreeIPA runs systemd and Docker needs
|
||||||
|
# nesting/overlay; keyctl is required by Kerberos/SSSD keyrings inside the CT.
|
||||||
|
NET_LINE="name=eth0,bridge=$CT_BRIDGE,ip=dhcp"
|
||||||
|
[[ "$CT_IP" != "dhcp" ]] && NET_LINE="name=eth0,bridge=$CT_BRIDGE,ip=$CT_IP"
|
||||||
|
|
||||||
|
cat > "$OUT_DIR/pct-create-$VMID.sh" <<EOF
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Run on the Proxmox host. Creates the ansipa LXC container.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
pct create $VMID $TPL_STORAGE:vztmpl/$CT_TEMPLATE \\
|
||||||
|
--hostname $CT_HOSTNAME \\
|
||||||
|
--cores $CT_CORES \\
|
||||||
|
--memory $CT_RAM \\
|
||||||
|
--swap 2048 \\
|
||||||
|
--rootfs $PVE_STORAGE:$CT_DISK \\
|
||||||
|
--net0 $NET_LINE \\
|
||||||
|
--features nesting=1,keyctl=1,fuse=1 \\
|
||||||
|
--unprivileged 0 \\
|
||||||
|
--onboot 1 \\
|
||||||
|
--start 0
|
||||||
|
|
||||||
|
echo "Created CT $VMID. Now append the extra options and start it:"
|
||||||
|
echo " cat ansipa-$VMID.conf >> /etc/pve/lxc/$VMID.conf"
|
||||||
|
echo " pct start $VMID"
|
||||||
|
echo " pct push $VMID ansipa-provision.sh /root/ansipa-provision.sh"
|
||||||
|
echo " pct push $VMID .env /root/.env"
|
||||||
|
echo " pct exec $VMID -- bash /root/ansipa-provision.sh"
|
||||||
|
EOF
|
||||||
|
chmod +x "$OUT_DIR/pct-create-$VMID.sh"
|
||||||
|
|
||||||
|
# ─── LXC config extras ────────────────────────────────────────────────────────
|
||||||
|
# Docker overlay2 + FreeIPA need these cgroup/device allowances in a CT.
|
||||||
|
cat > "$OUT_DIR/ansipa-$VMID.conf" <<EOF
|
||||||
|
# Append to /etc/pve/lxc/$VMID.conf — enables Docker + FreeIPA inside the CT.
|
||||||
|
lxc.apparmor.profile: unconfined
|
||||||
|
lxc.cgroup2.devices.allow: a
|
||||||
|
lxc.cap.drop:
|
||||||
|
lxc.mount.auto: proc:rw sys:rw
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ─── First-boot provisioner (runs INSIDE the container) ───────────────────────
|
||||||
|
cat > "$OUT_DIR/ansipa-provision.sh" <<'PROVEOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# ansipa-provision.sh — runs once inside the LXC to bring up the ansipa stack.
|
||||||
|
set -euo pipefail
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
echo "[ansipa] Installing Docker + git..."
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq ca-certificates curl git >/dev/null
|
||||||
|
install -m 0755 -d /etc/apt/keyrings
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
|
||||||
|
chmod a+r /etc/apt/keyrings/docker.asc
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release; echo $VERSION_CODENAME) stable" \
|
||||||
|
> /etc/apt/sources.list.d/docker.list
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null
|
||||||
|
systemctl enable --now docker
|
||||||
|
|
||||||
|
echo "[ansipa] Fetching the ansipa stack..."
|
||||||
|
git clone --depth 1 https://git.abdelbaki.eu/The_miro/Dotfiles.git /opt/ansipa-src 2>/dev/null \
|
||||||
|
|| { cd /opt/ansipa-src && git pull; }
|
||||||
|
STACK=/opt/ansipa
|
||||||
|
mkdir -p "$STACK"
|
||||||
|
cp -r /opt/ansipa-src/setup/modules/FreeipaAnsible/image/. "$STACK/"
|
||||||
|
cp /root/.env "$STACK/.env"
|
||||||
|
|
||||||
|
echo "[ansipa] Starting the full stack (this builds the FreeIPA image + first-boot ~10 min)..."
|
||||||
|
cd "$STACK"
|
||||||
|
# cgroup v2 hosts need run.sh (compose can't express --cgroupns host for FreeIPA).
|
||||||
|
if [ "$(stat -fc %T /sys/fs/cgroup 2>/dev/null)" = "cgroup2fs" ]; then
|
||||||
|
bash ./run.sh all
|
||||||
|
else
|
||||||
|
docker compose up -d
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[ansipa] Stack starting. Watch first-boot with:"
|
||||||
|
echo " docker logs -f freeipa"
|
||||||
|
echo "[ansipa] Once healthy, wire Keycloak↔FreeIPA LDAP: cd $STACK && ./keycloak-configure.sh"
|
||||||
|
PROVEOF
|
||||||
|
chmod +x "$OUT_DIR/ansipa-provision.sh"
|
||||||
|
|
||||||
|
# ─── Deployment guide ─────────────────────────────────────────────────────────
|
||||||
|
cat > "$OUT_DIR/DEPLOY-$VMID.md" <<EOF
|
||||||
|
# ansipa Proxmox LXC — deployment ($CT_HOSTNAME, VMID $VMID)
|
||||||
|
|
||||||
|
Generated by \`ansipa-proxmox-lxc.sh\`. Runs the full ansipa stack
|
||||||
|
(FreeIPA + CheckMK + Keycloak + PostgreSQL + nginx) as Docker containers
|
||||||
|
inside a privileged, nesting-enabled Proxmox LXC.
|
||||||
|
|
||||||
|
## 1. Copy these files to the Proxmox host
|
||||||
|
\`\`\`
|
||||||
|
scp pct-create-$VMID.sh ansipa-$VMID.conf ansipa-provision.sh .env root@PROXMOX:/root/ansipa/
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## 2. Create and provision the container (on the Proxmox host)
|
||||||
|
\`\`\`
|
||||||
|
cd /root/ansipa
|
||||||
|
# Ensure the Debian template exists: pveam update && pveam download $TPL_STORAGE $CT_TEMPLATE
|
||||||
|
bash pct-create-$VMID.sh
|
||||||
|
cat ansipa-$VMID.conf >> /etc/pve/lxc/$VMID.conf
|
||||||
|
pct start $VMID
|
||||||
|
pct push $VMID .env /root/.env
|
||||||
|
pct push $VMID ansipa-provision.sh /root/ansipa-provision.sh
|
||||||
|
pct exec $VMID -- bash /root/ansipa-provision.sh
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## 3. Access
|
||||||
|
- Portal / all UIs: \`http://<CT-IP>:8088/\` (put your reverse proxy in front — see docs/md/ansipa-setup.md)
|
||||||
|
- FreeIPA: \`/ipa/ui/\` · CheckMK: \`/cmk/\` · Keycloak: \`/auth/\`
|
||||||
|
- Admin passwords are in \`.env\` (IPA_ADMIN_PASSWORD, CMK_ADMIN_PASSWORD, KC_ADMIN_PASSWORD).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- The CT is **privileged** with nesting/keyctl/fuse — required for FreeIPA's
|
||||||
|
systemd + Kerberos keyrings and Docker's overlay2. Do not run untrusted
|
||||||
|
workloads in it.
|
||||||
|
- RAM: ${CT_RAM} MB. FreeIPA + CheckMK + Keycloak together need ~4–6 GB.
|
||||||
|
- Firewall: open the ansipa ports (see docs/md/ansipa-setup.md → Ports).
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ─── Summary ──────────────────────────────────────────────────────────────────
|
||||||
|
section "Done"
|
||||||
|
log "Artifacts written to: $OUT_DIR"
|
||||||
|
info " pct-create-$VMID.sh — create the CT (run on Proxmox host)"
|
||||||
|
info " ansipa-$VMID.conf — append to /etc/pve/lxc/$VMID.conf"
|
||||||
|
info " ansipa-provision.sh — first-boot provisioner (run inside CT)"
|
||||||
|
info " .env — stack secrets (mode 600 — keep safe)"
|
||||||
|
info " DEPLOY-$VMID.md — full deployment guide"
|
||||||
|
echo
|
||||||
|
warn "The .env contains generated admin passwords in plain text. Store it securely."
|
||||||
Loading…
Reference in New Issue