While it's probably not the best thing to admit, I've been neglecting my homelab for some time now. Gotify had been giving me errors for a at least a month and eventually seemed to stop working entirely. So it wasn't a complete surprise when I logged into PVE and saw the container hosting my miscellaneous utilities (Gotify, Grafana, Homepage, etc.) wasn't running.
What started as a routine pct start 100
, however, turned into a deep dive through Proxmox, ZFS, UID mapping, and AppArmor. Here's how I debugged and resurrected a broken LXC container running Docker in my homelab β and the key lessons along the way. Much like this very blog post, I owe most of the credit to Chat GPT.
β οΈ The Initial Problem
When trying to start an LXC container on my Proxmox VE host, I hit this cryptic error:
run_buffer: 571 Script exited with status 1
lxc_init: 845 Failed to run lxc.hook.pre-start for container "100"
__lxc_start: 2034 Failed to initialize container "100"
TASK ERROR: startup for container '100' failed
At first glance, itβs not obvious whatβs failing β especially when the container config looks valid and the root filesystem is still intact.
π Step 1: Confirm the Filesystem
I verified the containerβs ZFS subvolume existed:
zfs list | grep subvol-100
Then I mounted it:
pct mount 100
ls /var/lib/lxc/100/rootfs
β Full filesystem structure was present, which was a relief, β butβ¦
π¨ All files were owned by 100000:100000
, which is expected for unprivileged containers. I had recently switched this one to privileged, and LXC expects root:root
.
π οΈ Step 2: Fix Ownership
To convert the filesystem from unprivileged to privileged:
chown -R root:root /VM/subvol-100-disk-0
But I hit another roadblock:
chown: disk quota exceeded
Turns out ZFS refquota
was silently blocking metadata writes.
π§― Step 3: Remove ZFS Refquota
zfs set refquota=none VM/subvol-100-disk-0
zfs set quota=16G VM/subvol-100-disk-0
With that resolved, chown -R root:root ...
succeeded.
β The container started!
π³ Step 4: Docker Compose β Round Two
Now that the container was up, I tried launching my stack:
docker compose -f docker-compose-master.yml up -d
...only to hit this:
AppArmor enabled on system but the docker-default profile could not be loaded
...
You need policy admin privileges to manage profiles.
This is a classic conflict when running Docker inside LXC: Docker tries to load AppArmor profiles, but LXC blocks that at the kernel level.
π Step 5: Disable AppArmor for LXC
I edited /etc/pve/lxc/100.conf
and added:
lxc.apparmor.profile: unconfined
lxc.cgroup2.devices.allow: a
lxc.cap.drop:
features: nesting=1,keyctl=1
Then restarted the container:
pct restart 100
π Success! All services launched, and Docker stopped complaining.
β Takeaways
-
Switching an LXC from unprivileged to privileged requires a full
chown
toroot:root
-
ZFS
refquota
can silently blockchown
and metadata updates -
Docker inside LXC requires
lxc.apparmor.profile=unconfined
and disabling capability drops -
Always snapshot your LXC containers before big changes:
pct snapshot 100 pre-docker-fix
If you're running Docker-heavy services in LXC, itβs worth weighing whether a lightweight VM might offer fewer headaches β but if you're committed to containers inside containers, it's all solvable with a bit of elbow grease.
β
Want help with composing your own container stack or Proxmox network? Hit me up β or stay tuned for more homelab dispatches.