LXC Containers
Updated: 2026-07-01
Overview
Proxmox VE currently runs the restored service platform as separate unprivileged LXCs:
- CT
101 podman-lxcfor rootless Podman applications and data services. - CT
102 technitium-dnsfor DNS. - CT
103 caddy-ingressfor HTTP/HTTPS ingress. - CT
104 khysitefor a separate site workload that still needs a full service page. - CT
105 ts-routerfor Headscale/Tailscale subnet routing.
Older references to CT 100 proxy and CT 107 dns describe the Docker,
Traefik, Pi-hole, and Cloudflared era. Treat them as historical unless a fresh
pct list shows them running and a current page explicitly says they are in
use.
Verified Running Containers
Read-only Proxmox checks on 2026-06-26, with CT 105 added and verified on
2026-07-01:
| CT | State | CPU | Memory | Root disk | Network | Startup | Purpose |
|---|---|---|---|---|---|---|---|
101 podman-lxc |
Running | 4 cores | 8192 MiB | 64 GiB local-lvm |
192.168.2.20/24, VLAN 2, gateway 192.168.2.1 |
order=3, onboot=1 |
Rootless Podman application host |
102 technitium-dns |
Running | 2 cores | 1024 MiB | 8 GiB local-lvm |
192.168.2.2/24, VLAN 2, gateway 192.168.2.1 |
order=2, onboot=1 |
Technitium DNS |
103 caddy-ingress |
Running | 2 cores | 1024 MiB | 8 GiB local-lvm |
192.168.2.3/24, VLAN 2, gateway 192.168.2.1 |
order=2, onboot=1 |
Caddy ingress |
104 khysite |
Running | 2 cores | 512 MiB | 8 GiB local-lvm |
192.168.2.5/24, VLAN 2, gateway 192.168.2.1 |
onboot=1 |
Site workload; document before changing |
105 ts-router |
Running | 1 core | 512 MiB | 8 GiB local-lvm |
192.168.2.120/24, VLAN 2, gateway 192.168.2.1 |
order=2, onboot=1 |
Dedicated Headscale/Tailscale subnet router |
All five running CTs are unprivileged.
CT 101 podman-lxc
CT 101 is the active application container host. It runs rootless Podman as
podsvc. Live DHCP on July 1, 2026 placed it at 192.168.2.20/24.
It uses Technitium DNS through a local dhclient override until OPNsense DMZ
DHCP option 6 is corrected:
nameserver: 192.168.2.2
DNS override: /etc/dhcp/dhclient.conf supersedes DNS to 192.168.2.2
features: nesting=1,keyctl=1
unprivileged: 1
It also has the narrow /dev/net/tun passthrough required by rootless Podman 5
networking:
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
Current rootless services are documented in Podman Ecosystem Standards.
CT 102 technitium-dns
CT 102 is the DNS replacement for the historical Pi-hole/Cloudflared role at
the same resolver address, 192.168.2.2.
Verified listeners on 2026-06-26:
| Listener | Purpose |
|---|---|
192.168.2.2:53/tcp and 192.168.2.2:53/udp |
Client and infrastructure DNS |
127.0.0.1:53/tcp and 127.0.0.1:53/udp |
Local DNS |
192.168.2.2:5380/tcp and 127.0.0.1:5380/tcp |
Technitium web console |
Because the web console is listening on the DMZ address, OPNsense rules must limit access to approved admin networks or it must be moved behind Caddy with OIDC. Do not expose the Technitium console publicly.
CT 103 caddy-ingress
CT 103 is the Caddy ingress host. It is separate from CT 101 because ingress
holds certificate and authentication material and needs low ports.
Verified on 2026-06-26:
| Item | Value |
|---|---|
| Caddy version | v2.11.4 |
| Listeners | *:80, *:443 |
| Required modules | dns.providers.cloudflare v0.2.4, security v1.1.62 |
Low-port binding is handled by a narrow file capability on the Caddy binary. Do not lower rootless Podman privileged-port limits to solve ingress.
See Caddy and Technitium Migration and Agent Handoff: Caddy, Technitium, and HTTPS.
CT 104 khysite
CT 104 khysite is running at 192.168.2.5. It needs a current service page
before any major change, restore, or retirement decision.
Minimum pre-change checks:
ssh pvessh 'pct config 104'
ssh pvessh 'pct exec 104 -- hostname'
ssh pvessh 'pct exec 104 -- systemctl --no-pager --state=running,failed'
Do not assume it is part of the rootless Podman stack.
On July 1, 2026, CTs 101 through 104 were locally mitigated for the DMZ
DHCP DNS issue:
/etc/dhcp/dhclient.conf: supersede domain-name-servers 192.168.2.2;
/etc/resolv.conf: nameserver 192.168.2.2
This should become unnecessary after OPNsense Dnsmasq sends option 6
192.168.2.2 on the DMZ interface.
CT 105 ts-router
CT 105 ts-router is the dedicated Headscale/Tailscale subnet router for the
DMZ route 192.168.2.0/24. It replaced pve as serving router on
2026-07-01.
Current configuration:
hostname: ts-router
ostype: debian
unprivileged: 1
features: nesting=1,keyctl=1
net0: bridge=vmbr0, tag=2, ip=dhcp, firewall=1
MAC: BC:24:11:F2:77:FD
DMZ lease: 192.168.2.120/24
nameserver: 192.168.2.2
Tailscale requires /dev/net/tun passthrough:
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
Inside the CT:
Tailscale version: 1.98.8
Headscale owner: infra
Tailnet IP: 100.64.0.3
Advertised route: 192.168.2.0/24
SNAT: enabled
Forwarding file: /etc/sysctl.d/99-tailscale-subnet-router.conf
DNS override: /etc/dhcp/dhclient.conf supersedes DNS to 192.168.2.2
Historical Containers
The June 2026 baseline docs referenced:
| CT | Historical role | Current handling |
|---|---|---|
100 proxy |
Docker, Traefik, and app stacks | Historical source material; replaced by CT 101 plus Caddy where migrated |
107 dns |
Pi-hole and Cloudflared | Historical source material; replaced by CT 102 technitium-dns |
101 gam |
Stopped old identity before rebuild | Replaced by CT 101 podman-lxc |
105 down |
Stopped large filesystem | Preserve evidence before repair or deletion |
106 rdhost |
RustDesk signal/relay server | Preserve identity files if clients are migrated |
Operational Procedures
ssh pve 'pct list'
ssh pve 'pct status <CTID>'
ssh pve 'pct config <CTID>'
ssh pve 'pct start <CTID>'
ssh pve 'pct shutdown <CTID>'
ssh pve 'pct enter <CTID>'
For rootless Podman services on CT 101, use Podman Ecosystem Standards.
Troubleshooting
- DNS failure: check CT
102, then OPNsense DNS enforcement. - HTTPS failure with working DNS: check CT
103, then the CT101high-port backend. - Rootless app failure: check CT
101user units and Podman containers aspodsvc. - DMZ reachability failure: check VLAN tag
2,vmbr0, gateway192.168.2.1, and OPNsense rules. - Tailnet route failure: check CT
105, Headscale route state, and whether the client has accepted subnet routes.