This guide documents the exact steps taken to fix the following Docker errors when running inside an unprivileged Proxmox LXC on Ubuntu 24.04.3 LTS:
open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied: unknownCould not check if docker-default AppArmor profile was loaded: open /sys/kernel/security/apparmor/profiles: permission denied
Environment:
- Hypervisor: Proxmox VE (LXC container) running behind a firewall
- CT OS: Ubuntu 24.04.3 LTS (Noble Numbat)
- LXC: Unprivileged container
- Docker: 28.5.2
- Initial containerd: 1.7.29-1
ubuntu.24.04noble - runc: 1.3.3
Goal: Get Docker working reliably inside the LXC (including
docker run hello-worldanddocker compose up) by downgrading containerd and disabling Docker’s AppArmor integration inside the container.
From inside the LXC container, any attempt to start a container failed with:
docker run hello-worldError:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied: unknown
After some changes, this evolved into:
Could not check if docker-default AppArmor profile was loaded: open /sys/kernel/security/apparmor/profiles: permission denied
This indicated two separate but related issues:
- A containerd / runc bug around
net.ipv4.ip_unprivileged_port_startin nested/containerized environments. - AppArmor access problems inside an LXC when Docker tries to check or use AppArmor profiles.
On the Proxmox host, edit the LXC configuration for the container running Docker.
Example CTID: 117
nano /etc/pve/lxc/117.confAdd (or ensure) the following lines exist:
features: keyctl=1,nesting=1
lxc.apparmor.profile: unconfinednesting=1andkeyctl=1are required for Docker-in-LXC to behave properly.lxc.apparmor.profile: unconfinedrelaxes AppArmor constraints for this particular container (expected decision for a “Docker host” CT).
After saving the file, restart the LXC from the Proxmox host:
pct stop 117
pct start 117Then log back into the container.
Inside the container, we observed the available versions of containerd.io:
apt list -a containerd.ioOutput snippet (Ubuntu 24.04 / noble):
containerd.io/noble,now 1.7.29-1~ubuntu.24.04~noble amd64 [installed]
containerd.io/noble 1.7.28-2~ubuntu.24.04~noble amd64
containerd.io/noble 1.7.28-1~ubuntu.24.04~noble amd64
containerd.io/noble 1.7.28-0~ubuntu.24.04~noble amd64
...
We downgraded to the known-good version 1.7.28-1~ubuntu.24.04~noble:
apt-get update
apt-get install -y containerd.io=1.7.28-1~ubuntu.24.04~noble
apt-mark hold containerd.io
apt-mark holdprevents automatic upgrades back to the problematic version during futureapt upgraderuns.
Restart Docker to pick up the downgraded containerd:
systemctl restart dockerAt this point, the original net.ipv4.ip_unprivileged_port_start error was resolved, but Docker still failed due to AppArmor being partially visible but unusable inside the LXC.
Even with lxc.apparmor.profile: unconfined, Docker still tried to interact with AppArmor and failed to read /sys/kernel/security/apparmor/profiles. To fix that, we told Docker inside the container to treat itself as running inside another container and skip AppArmor integration entirely.
Create a systemd drop-in for the Docker service:
systemctl edit dockerThis opens an override file (e.g. /etc/systemd/system/docker.service.d/override.conf). Put the following content in it:
[Service]
Environment=container="setmeandforgetme"Save and exit.
Then reload systemd and restart Docker:
systemctl daemon-reload
systemctl restart dockerConfirm that Docker no longer lists AppArmor as a security option:
docker info | grep -i apparmor || echo "no apparmor entry"Expected output:
no apparmor entry
Now test Docker again inside the LXC:
docker run hello-worldExpected output (successful run):
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
If using Docker Compose (v2 plugin), you can now run your stack normally, for example:
cd ~/beszel
docker compose up -dCheck running containers:
docker psExample output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9897c2825b2a henrygd/beszel "/beszel serve --htt…" X minutes ago Up X minutes 0.0.0.0:8090->8090/tcp, [::]:8090->8090/tcp beszel
51f064b0af18 ghcr.io/mbecker20/periphery:latest "periphery" 4 months ago Up X minutes 0.0.0.0:8120->8120/tcp, [::]:8120->8120/tcp komodo-periphery-periphery-1
At this point, Docker is fully functional again inside the Proxmox LXC.
If Docker itself was recently upgraded and you want to stabilize the environment further, you can also hold the Docker Engine packages (if installed from Docker’s official repo):
apt-mark hold docker-ce docker-ce-cli docker-ce-rootless-extrasThis ensures that containerd and Docker remain on known-good versions until you explicitly decide to upgrade and re-test.
In this setup:
- The LXC is unprivileged, which already provides a boundary.
lxc.apparmor.profile: unconfinedrelaxes AppArmor at the LXC level so Docker can operate normally in a nested environment.- Docker’s AppArmor integration is disabled inside this LXC via the
Environment=container="setmeandforgetme"override.
This combination is a reasonable trade-off for a dedicated “Docker host” LXC in a homelab environment, but you should:
- Avoid running highly untrusted containers in this CT.
- Keep it segregated from more sensitive services if possible.
- Periodically review Docker and containerd updates and re-evaluate whether upstream has fixed the underlying issues so you can remove workarounds in the future.
On Proxmox host (/etc/pve/lxc/117.conf):
features: keyctl=1,nesting=1
lxc.apparmor.profile: unconfinedThen:
pct restart 117Inside the LXC:
# Downgrade and pin containerd
apt-get update
apt-get install -y containerd.io=1.7.28-1~ubuntu.24.04~noble
apt-mark hold containerd.io
systemctl restart docker
# Disable Docker AppArmor integration via systemd override
systemctl edit docker
# (add this)
# [Service]
# Environment=container="setmeandforgetme"
systemctl daemon-reload
systemctl restart docker
# Verify
docker info | grep -i apparmor || echo "no apparmor entry"
docker run hello-worldIf those commands succeed, Docker is healthy again and docker compose up -d should work for your stacks.
This file is intended for GitHub documentation under a homelab / Proxmox / Docker so future you (or others) can quickly reproduce the fix when Docker breaks in nested LXC environments on Ubuntu 24.04.