Files changed: .gitignore CLAUDE.md credentials engine/.embcache.json engine/changelog.md engine/config.yaml engine/lib/__pycache__/agent.cpython-312.pyc engine/lib/agent.py engine/lib/lint.py engine/lint-report.md engine/sweep-full.log engine/sweep.sh vault/.obsidian/graph.json vault/.obsidian/workspace.json vault/INDEX.md vault/archive/projects/mmud/last-ember-chronicle.html vault/archive/projects/mmud/last-ember-howto.html vault/archive/projects/mmud/last-ember.html vault/archive/projects/mmud/mmud-phase5-prompt.md vault/archive/projects/mmud/mmud-phase6-prompt.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/01-update-planned.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/02-npc-nodes.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/03-darkcragg.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/04-dcrg-node.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/05-phase5.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/06-phase6.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/README.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/mmud-project.md vault/docs/hardware/environment.md vault/docs/hardware/ip-allocation.md vault/docs/matrix/archivist.md vault/docs/matrix/matrix_host.md vault/docs/matrix/mautrix_signal.md vault/docs/matrix/synapse.md vault/docs/matrix/synapse_retention_discovery.md vault/docs/navi/cc-rules.md vault/docs/navi/deployment.md vault/docs/navi/themes.md vault/docs/services/ots-setup.md vault/docs/services/services.md vault/docs/services/usenet.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/geo-tools.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/notes/ia-download-queue.md vault/plans/vaultwarden-plan.md vault/projects/advbbs-project.md vault/projects/argus.md vault/projects/deploy-livesync.md vault/projects/matrix-synapse-deployment.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/ct-runbook.md vault/runbooks/edge2-access-reference.md vault/runbooks/expose-service-contabo.md vault/runbooks/expose-service-edge2.md vault/runbooks/expose-service-home.md vault/runbooks/headscale-onboard-node.md vault/runbooks/ia-cli-reference.md vault/runbooks/ia-download-mirror.md vault/runbooks/idahomesh-bridge-setup.md vault/runbooks/idahomesh-vpn-device-setup.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshmonitor-password-reset.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/nordvpn-lxc.md vault/runbooks/peertube-remote-runner.md vault/runbooks/pg-backup.md vault/runbooks/pi-nas-omv-runbook.md vault/runbooks/pipeline-patterns.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/proxmox-onboard-node.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md vault/session-resume/SESSION-HANDOFF-meshai-test.md
273 lines
6.6 KiB
Markdown
273 lines
6.6 KiB
Markdown
---
|
|
title: Proxmox CT/LXC Provisioning Runbook
|
|
type: runbook
|
|
tags:
|
|
- proxmox
|
|
aliases: []
|
|
related:
|
|
- [[proxmox-onboard-node]]
|
|
- [[headscale-onboard-node]]
|
|
- [[meshtasticd-sim-nodes-runbook]]
|
|
- [[proxmox-create-ubuntu-vm]]
|
|
- [[ots-setup]]
|
|
updated: 2026-06-18
|
|
---
|
|
# Proxmox CT/LXC Provisioning Runbook
|
|
|
|
Every container gets the same baseline: local user, Tailscale, SSH, Docker, and common tools. No exceptions.
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- Proxmox VE host with Ubuntu 24.04 LXC template downloaded
|
|
- Tailscale auth key (reusable, from https://login.tailscale.com/admin/settings/keys)
|
|
- SSH access to Proxmox host
|
|
|
|
If you don't have the template cached yet:
|
|
|
|
```bash
|
|
pveam update
|
|
pveam download local system ubuntu-24.04-standard_24.04-2_amd64.tar.zst
|
|
```
|
|
|
|
---
|
|
|
|
## 1. Create the Container
|
|
|
|
Pick the next available CTID. Adjust `--memory`, `--cores`, and `--rootfs` to fit the workload.
|
|
|
|
```bash
|
|
# Variables — edit these per container
|
|
CTID=110
|
|
HOSTNAME="mycontainer"
|
|
STORAGE="local-lvm" # or zfs-pool, ceph, etc.
|
|
DISK_SIZE=8 # GB
|
|
MEMORY=2048 # MB
|
|
CORES=2
|
|
BRIDGE="vmbr0"
|
|
|
|
pct create $CTID local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst \
|
|
--hostname $HOSTNAME \
|
|
--storage $STORAGE \
|
|
--rootfs ${STORAGE}:${DISK_SIZE} \
|
|
--memory $MEMORY \
|
|
--cores $CORES \
|
|
--net0 name=eth0,bridge=${BRIDGE},ip=dhcp \
|
|
--unprivileged 1 \
|
|
--features nesting=1,keyctl=1 \
|
|
--onboot 1 \
|
|
--start 1
|
|
```
|
|
|
|
`nesting=1` is required for Docker. `keyctl=1` prevents keyring errors in systemd containers.
|
|
|
|
Wait a few seconds for the container to boot, then enter it:
|
|
|
|
```bash
|
|
pct enter $CTID
|
|
```
|
|
|
|
Everything from here on runs **inside the container**.
|
|
|
|
---
|
|
|
|
## 2. Base System Update
|
|
|
|
```bash
|
|
apt update && apt upgrade -y
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Common Tools
|
|
|
|
```bash
|
|
apt install -y \
|
|
curl \
|
|
wget \
|
|
vim \
|
|
htop \
|
|
git \
|
|
unzip \
|
|
jq \
|
|
net-tools \
|
|
dnsutils \
|
|
ca-certificates \
|
|
gnupg \
|
|
lsb-release \
|
|
sudo \
|
|
sshpass
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Create User
|
|
|
|
```bash
|
|
useradd -m -s /bin/bash -G sudo zvx
|
|
echo "zvx:7redditGold" | chpasswd
|
|
```
|
|
|
|
Verify:
|
|
|
|
```bash
|
|
su - zvx -c "whoami && sudo -l"
|
|
```
|
|
|
|
---
|
|
|
|
## 5. SSH Configuration
|
|
|
|
SSH should already be running in the Ubuntu 24.04 template, but make sure password auth is enabled for sshpass workflows:
|
|
|
|
```bash
|
|
# Ensure SSH is installed and running
|
|
apt install -y openssh-server
|
|
systemctl enable --now ssh
|
|
|
|
# Allow password auth (needed for sshpass)
|
|
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
|
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
|
|
|
systemctl restart ssh
|
|
```
|
|
|
|
Test from the Proxmox host (exit the container first):
|
|
|
|
```bash
|
|
CT_IP=$(pct exec $CTID -- hostname -I | awk '{print $1}')
|
|
sshpass -p '7redditGold' ssh -o StrictHostKeyChecking=accept-new zvx@$CT_IP "echo 'SSH OK'"
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Install Docker
|
|
|
|
```bash
|
|
# Add Docker's official GPG key and repo
|
|
install -m 0755 -d /etc/apt/keyrings
|
|
curl -fsSL https://download.docker.com/linux/ubuntu/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/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
|
> /etc/apt/sources.list.d/docker.list
|
|
|
|
apt update
|
|
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
|
|
# Add zvx to docker group (no sudo needed for docker commands)
|
|
usermod -aG docker zvx
|
|
|
|
# Verify
|
|
docker run --rm hello-world
|
|
```
|
|
|
|
If Docker fails to start with an AppArmor or permissions error, confirm `nesting=1` is set on the container (Step 1). You can check/fix from the Proxmox host:
|
|
|
|
```bash
|
|
pct set $CTID --features nesting=1,keyctl=1
|
|
pct reboot $CTID
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Install Tailscale
|
|
|
|
```bash
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
```
|
|
|
|
Bring it up with your auth key:
|
|
|
|
```bash
|
|
# Replace with your actual auth key
|
|
tailscale up --authkey=tskey-auth-XXXXXXXXXXXX --ssh
|
|
```
|
|
|
|
If you don't have an auth key handy, run without `--authkey` and it will print a URL to authenticate in a browser:
|
|
|
|
```bash
|
|
tailscale up --ssh
|
|
```
|
|
|
|
Verify:
|
|
|
|
```bash
|
|
tailscale status
|
|
tailscale ip -4
|
|
```
|
|
|
|
The `--ssh` flag enables Tailscale SSH, which lets you SSH into the container over Tailscale without managing keys. The container will appear in your tailnet by its hostname.
|
|
|
|
---
|
|
|
|
## 8. Verification Checklist
|
|
|
|
Run this from inside the container to confirm everything:
|
|
|
|
```bash
|
|
echo "=== CT Provisioning Check ==="
|
|
echo ""
|
|
echo "Hostname: $(hostname)"
|
|
echo "User zvx: $(id zvx 2>/dev/null && echo 'OK' || echo 'MISSING')"
|
|
echo "sudo: $(sudo -l -U zvx 2>/dev/null | grep -q ALL && echo 'OK' || echo 'MISSING')"
|
|
echo "sshpass: $(which sshpass >/dev/null 2>&1 && echo 'OK' || echo 'MISSING')"
|
|
echo "SSH: $(systemctl is-active ssh)"
|
|
echo "Docker: $(docker --version 2>/dev/null || echo 'MISSING')"
|
|
echo "Tailscale: $(tailscale status --self 2>/dev/null | head -1 || echo 'NOT CONNECTED')"
|
|
echo "Tailscale IP: $(tailscale ip -4 2>/dev/null || echo 'N/A')"
|
|
```
|
|
|
|
Expected output — everything should say OK/active with a Tailscale IP:
|
|
|
|
```
|
|
=== CT Provisioning Check ===
|
|
|
|
Hostname: mycontainer
|
|
User zvx: uid=1000(zvx) gid=1000(zvx) groups=1000(zvx),27(sudo),998(docker) OK
|
|
sudo: OK
|
|
sshpass: OK
|
|
SSH: active
|
|
Docker: Docker version 27.x.x, build xxxxxxx
|
|
Tailscale: 100.x.x.x mycontainer tagged-devices linux -
|
|
Tailscale IP: 100.x.x.x
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Reference (Copy/Paste Block)
|
|
|
|
For the impatient — the whole thing end to end after `pct enter`:
|
|
|
|
```bash
|
|
# Update + tools
|
|
apt update && apt upgrade -y
|
|
apt install -y curl wget vim htop git unzip jq net-tools dnsutils \
|
|
ca-certificates gnupg lsb-release sudo sshpass openssh-server
|
|
|
|
# User
|
|
useradd -m -s /bin/bash -G sudo zvx
|
|
echo "zvx:7redditGold" | chpasswd
|
|
|
|
# SSH
|
|
systemctl enable --now ssh
|
|
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
|
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
|
systemctl restart ssh
|
|
|
|
# Docker
|
|
install -m 0755 -d /etc/apt/keyrings
|
|
curl -fsSL https://download.docker.com/linux/ubuntu/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/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
|
> /etc/apt/sources.list.d/docker.list
|
|
apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
usermod -aG docker zvx
|
|
|
|
# Tailscale
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
tailscale up --ssh
|
|
```
|