echo6-docs/runbooks/ct-runbook.md
Matt Johnson e9231ac24a Migration: consolidate Echo6 docs to cortex with full infrastructure cleanup sync
- Documents recent infrastructure cleanup (8 CTs destroyed, 35 DNS records removed, Headscale cleanup)
- Adds 24 new runbooks covering Authentik, PeerTube, Meshtastic, RECON, Proxmox, Mailcow, Internet Archive, GPU routing
- Adds project documentation for headscale, vaultwarden, peertube, matrix, mmud, advbbs, arr stack
- Updates services.md, environment.md, caddy.md, authentik.md to match live infrastructure
- Removes 4 deprecated runbook duplicates (canonical versions live in projects/)
- Adds .gitignore for binary archives and editor temp files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 06:02:16 +00:00

6.3 KiB

Proxmox CT/LXC Provisioning Runbook

Every container gets the same baseline: local user, Tailscale, SSH, Docker, and common tools. No exceptions.


Prerequisites

If you don't have the template cached yet:

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.

# 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:

pct enter $CTID

Everything from here on runs inside the container.


2. Base System Update

apt update && apt upgrade -y

3. Common Tools

apt install -y \
  curl \
  wget \
  vim \
  htop \
  git \
  unzip \
  jq \
  net-tools \
  dnsutils \
  ca-certificates \
  gnupg \
  lsb-release \
  sudo \
  sshpass

4. Create User

useradd -m -s /bin/bash -G sudo zvx
echo "zvx:7redditGold" | chpasswd

Verify:

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:

# 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):

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

# 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:

pct set $CTID --features nesting=1,keyctl=1
pct reboot $CTID

7. Install Tailscale

curl -fsSL https://tailscale.com/install.sh | sh

Bring it up with your auth key:

# 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:

tailscale up --ssh

Verify:

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:

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:

# 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