Proxmox containers
Running Containers on Proxmox VE
A Procedural Tutorial for Administrators
1. Purpose
This tutorial explains the key concepts and procedures involved in running Linux containers on Proxmox Virtual Environment.
After completing the tutorial, you should be able to:
1. Explain the difference between a container and a virtual machine.
2. Download a container operating-system template.
3. Create and configure an LXC container.
4. Allocate CPU, memory, storage, and networking resources.
5. Start, stop, update, and troubleshoot a container.
6. Configure backups, snapshots, and firewall protection.
7. Decide whether an application should run in an LXC container, a virtual machine, or Docker.
2. Understand Proxmox Container Architecture
Proxmox VE supports two primary forms of virtualization:
• KVM virtual machines
• LXC containers
A KVM virtual machine emulates a complete computer and runs its own kernel. An LXC container shares the Proxmox host’s Linux kernel but maintains a separate user space, filesystem, processes, network configuration, and resource limits.
Proxmox containers are designed primarily as system containers. A system container behaves like a small Linux server. It can run services such as:
• Web servers
• Database servers
• DNS servers
• File-sharing services
• Monitoring systems
• Internal business applications
• Reverse proxies
• Development environments
The Proxmox Container Toolkit, accessed through the pct command, manages LXC containers and integrates them with Proxmox storage, networking, clustering, firewall, backup, and high-availability features.
Container versus virtual machine
| Consideration | LXC container | KVM virtual machine |
| Kernel | Shares the Proxmox host kernel | Uses its own kernel |
| Operating systems | Linux only | Linux, Windows, BSD, and others |
| Startup time | Usually a few seconds | Usually longer |
| Resource overhead | Low | Higher |
| Isolation | Good, but less complete than a VM | Stronger isolation |
| Kernel modules | Controlled by the host | Managed inside the VM |
| Hardware passthrough | More complicated | Generally more flexible |
| Best use | Lightweight Linux services | Strong isolation or non-Linux workloads |
Use a container when the workload is Linux-based, does not require its own kernel, and benefits from low overhead.
Use a virtual machine when the workload:
• Runs Windows or another non-Linux operating system.
• Requires a custom kernel.
• Requires stronger security isolation.
• Requires complicated hardware passthrough.
• Runs software that is not compatible with LXC restrictions.
• Will host untrusted users or untrusted code.
3. Understand System Containers and Application Containers
An LXC container in Proxmox normally represents an entire Linux operating-system environment. For example, one container might run Debian with Nginx, PHP, SSH, systemd, and scheduled tasks.
This differs from the common Docker model, in which each container usually runs a single application or service.
A useful way to distinguish them is:
• Proxmox LXC: a lightweight Linux server.
• Docker container: a packaged application process.
Current Proxmox documentation also describes support for creating LXC-based containers from Open Container Initiative images. However, application-container support is identified as a technology preview. For ordinary production administration, conventional Linux LXC templates remain the more established approach.
4. Prepare the Proxmox Host
Before creating a container, confirm that the Proxmox node has:
• Available memory
• Available CPU capacity
• Suitable storage
• A working Linux bridge
• Current system updates
• A configured backup destination
Step 1: Check the Proxmox version
Open the Proxmox shell and run:
bash
pveversion -v
Step 2: Install available updates
Use the Proxmox web interface:
1. Select the Proxmox node.
2. Select Updates.
3. Click Refresh.
4. Review the available packages.
5. Click Upgrade.
Alternatively, use the host shell:
bash
apt update
apt full-upgrade
Reboot the host when a kernel or other major system component has been updated:
bash
reboot
Do not install ordinary application workloads directly on the Proxmox host. Keep the host dedicated to virtualization, storage, networking, backup, and cluster management.
Step 3: Review available storage
In the web interface:
1. Select Datacenter.
2. Select Storage.
3. Review each storage target.
4. Confirm that at least one storage target permits Container content.
5. Confirm that storage is available for Container templates and Backup files.
Typical storage roles might be:
| Storage name | Typical contents |
| local | Templates, ISO images, backup files |
| local-lvm | Container and VM disks |
| local-zfs | Container and VM datasets |
| pbs | Proxmox Backup Server backups |
| nfs-backup | Backup files on network storage |
Step 4: Review the network bridge
In the web interface:
1. Select the Proxmox node.
2. Select System.
3. Select Network.
4. Identify the primary bridge, commonly named vmbr0.
5. Confirm that the bridge is connected to the correct physical network interface.
A container’s virtual network adapter normally connects to a Linux bridge. The bridge acts like a virtual Ethernet switch that connects the container to the physical network.
5. Download a Container Template
A container template is a compressed Linux filesystem used to create new containers.
Using the web interface
1. Select the storage that accepts container templates, commonly local.
2. Select CT Templates.
3. Click Templates.
4. Select a Linux distribution.
5. Click Download.
6. Wait for the download task to finish.
Common choices include Debian, Ubuntu, AlmaLinux, Rocky Linux, Fedora, and Alpine Linux.
Using the command line
bash
pveam available
pveam available | grep debian
pveam update
pveam download local debian-13-standard_13.1-1_amd64.tar.zst
pveam list local
The exact filename changes as templates are updated. Use the filename shown by pveam available.
6. Plan the Container
Before clicking Create CT, record the planned configuration.
| Setting | Example |
| Container ID | 110 |
| Hostname | web01 |
| Operating system | Debian |
| Privilege mode | Unprivileged |
| CPU cores | 2 |
| Memory | 2 GB |
| Swap | 512 MB |
| Root disk | 16 GB |
| Bridge | vmbr0 |
| IPv4 address | 192.168.10.110/24 |
| Gateway | 192.168.10.1 |
| DNS domain | example.local |
| DNS server | 192.168.10.5 |
| Start at boot | Yes |
| Firewall | Yes |
| Backup | Nightly |
Choose a descriptive hostname. Avoid generic names such as server1 when a functional name such as proxy01, wiki01, or monitor01 would be clearer.
7. Choose Between Privileged and Unprivileged Containers
Unprivileged container
In an unprivileged container, root inside the container is mapped to a non-root user ID on the Proxmox host.
Advantages include better protection against container escape and reduced impact of many container-level security problems.
Disadvantages include more complicated permissions for bind mounts, device access, and some nested workloads.
Privileged container
In a privileged container, root inside the container corresponds more directly to root privileges on the host.
This can simplify device access, certain network appliances, filesystem mounts, and legacy applications, but it offers weaker isolation.
Recommended rule
Use an unprivileged container by default. Create a privileged container only when the workload has a documented technical requirement that cannot reasonably be met with an unprivileged container.
8. Create a Container Through the Web Interface
Step 1: Open the creation wizard
1. Log in to the Proxmox web interface.
2. Select the desired node.
3. Click Create CT.
Step 2: Complete the General page
Enter the node, CT ID, hostname, optional resource pool, root password, and SSH public key. Enable Unprivileged container unless there is a documented reason not to.
Step 3: Select the template
Choose the template storage and downloaded operating-system template.
Step 4: Configure the root disk
Choose the storage target and disk size.
| Workload | Starting root disk |
| DNS or small utility | 4–8 GB |
| Reverse proxy | 8–16 GB |
| General Linux server | 16–32 GB |
| Database server | 32 GB or more |
| File or media service | Separate data mount recommended |
Step 5: Allocate CPU resources
Set cores, CPU limit if needed, and CPU units. Start small and increase resources based on measured demand.
Step 6: Allocate memory
Set memory and swap.
| Workload | Memory |
| Small DNS or proxy server | 512 MB–1 GB |
| General web application | 1–4 GB |
| Database server | Based on workload |
| Monitoring platform | 2–8 GB or more |
Leave sufficient memory for the Proxmox host, ZFS ARC if applicable, other guests, and backup operations.
Step 7: Configure networking
Enter the interface name, bridge, VLAN tag if needed, IP configuration, gateway, firewall setting, and optional rate limit.
For DHCP:
text
IPv4: DHCP
For a static address:
text
IPv4/CIDR: 192.168.10.110/24
Gateway: 192.168.10.1
Step 8: Configure DNS
Specify the DNS search domain and DNS server addresses.
Step 9: Confirm the configuration
Review the settings, optionally enable Start after created, and click Finish.
9. Create a Container from the Command Line
bash
pct create 110 \
local:vztmpl/debian-13-standard_13.1-1_amd64.tar.zst \
--hostname web01 \
--unprivileged 1 \
--cores 2 \
--memory 2048 \
--swap 512 \
--rootfs local-lvm:16 \
--net0 name=eth0,bridge=vmbr0,ip=192.168.10.110/24,gw=192.168.10.1,firewall=1 \
--nameserver 192.168.10.5 \
--searchdomain example.local \
--ssh-public-keys /root/.ssh/id_ed25519.pub \
--onboot 1
Display the container configuration:
bash
pct config 110
10. Start and Access the Container
bash
pct start 110
pct status 110
pct console 110
pct enter 110
pct list
Use exit to leave the container shell.
11. Perform the Initial Operating-System Configuration
For Debian or Ubuntu:
bash
apt update
apt full-upgrade -y
Set the timezone:
bash
timedatectl set-timezone America/Chicago
Create an administrative user:
bash
adduser administrator
usermod -aG sudo administrator
Install and enable SSH if required:
bash
apt install openssh-server
systemctl enable --now ssh
Recommended SSH settings after key-based access has been tested:
text
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart SSH:
bash
systemctl restart ssh
Install basic tools as needed:
bash
apt install curl wget vim-nox nano htop ca-certificates gnupg unzip
12. Manage Container Resources
bash
pct set 110 --memory 4096
pct set 110 --swap 1024
pct set 110 --cores 4
pct set 110 --onboot 1
pct set 110 --startup order=20,up=30,down=60
Startup ordering is useful when one service depends on another.
13. Add Storage to a Container
Proxmox-managed mount point
bash
pct set 110 --mp0 local-lvm:50,mp=/srv/data,backup=1
Bind mount
bash
mkdir -p /srv/shared
pct set 110 --mp0 /srv/shared,mp=/mnt/shared
Bind mounts require careful planning for user-ID mappings, backups, and migration.
14. Understand User-ID Mapping
A common default mapping is conceptually similar to:
| Container ID | Host ID |
| 0 | 100000 |
| 1 | 100001 |
| 1000 | 101000 |
For example:
bash
chown 101000:101000 /srv/shared
cat /etc/subuid
cat /etc/subgid
Verify mappings before changing ownership.
15. Configure Networking After Creation
bash
pct config 110
pct set 110 --net0 name=eth0,bridge=vmbr0,ip=dhcp,firewall=1
pct set 110 --net0 name=eth0,bridge=vmbr0,ip=192.168.10.110/24,gw=192.168.10.1,firewall=1
pct set 110 --net0 name=eth0,bridge=vmbr0,tag=20,ip=192.168.20.110/24,gw=192.168.20.1,firewall=1
16. Configure the Proxmox Firewall
Enable and review the firewall at the Datacenter, node, container, and interface levels as appropriate.
Example policy:
| Direction | Action | Protocol/port | Source |
| In | Accept | TCP 22 | Administration subnet |
| In | Accept | TCP 443 | Internal networks |
| In | Drop | All others | Any |
| Out | Accept | Required traffic | Any |
Always create and test management-access rules before applying a default-deny policy.
17. Back Up Containers
Create a manual backup:
bash
vzdump 110 --storage nfs-backup --mode snapshot --compress zstd
Backup modes include snapshot, suspend, and stop.
A basic retention plan might include seven daily backups, four weekly backups, and several monthly backups.
Periodically test restores by restoring under a temporary ID, attaching the container to an isolated network, starting it, and verifying the operating system, application, and data.
18. Use Snapshots Carefully
bash
pct snapshot 110 before-upgrade
pct listsnapshot 110
pct rollback 110 before-upgrade
pct delsnapshot 110 before-upgrade
Snapshots are short-term rollback tools, not backups.
19. Clone and Template Containers
Before cloning, remove or regenerate machine-specific information such as hostnames, IP addresses, SSH host keys, application node identifiers, monitoring IDs, and database replication identities.
Use full clones when the new container should be independent.
20. Monitor Container Performance
Useful commands include:
bash
top
htop
free -h
df -h
ip address
ss -tulpn
journalctl -p warning
Investigate CPU, memory, storage, networking, application, and host contention issues before simply adding resources.
21. Stop, Reboot, and Shut Down Containers Correctly
bash
pct shutdown 110
pct reboot 110
pct stop 110
pct status 110
Use pct stop only when graceful shutdown fails or immediate termination is necessary.
22. Troubleshoot a Container That Will Not Start
bash
pct start 110 --debug
pct config 110
pvesm status
journalctl -xe
journalctl -xe | grep 110
df -h
zpool status
zfs list
pvs
vgs
lvs
The container configuration is normally stored under:
text
/etc/pve/lxc/110.conf
23. Troubleshoot Network Connectivity
From the host:
bash
ping 192.168.10.110
pct config 110
Inside the container:
bash
ip address
ip route
cat /etc/resolv.conf
ping 192.168.10.1
ping 1.1.1.1
getent hosts example.com
curl -I https://example.com
Check the interface, IP address, gateway, external routing, DNS, VLAN, bridge, and firewall rules in that order.
24. Use Nesting Only When Required
bash
pct set 110 --features nesting=1
Nesting may be required for Docker, Podman, some build systems, and certain sandboxing tools. It expands access to kernel-related interfaces and can reduce isolation.
25. Decide How to Run Docker
Option 1: Docker in a virtual machine
text
Proxmox host
└── Linux virtual machine
└── Docker Engine
├── Application container
├── Database container
└── Proxy container
This is usually the safest general recommendation for production Docker deployments.
Option 2: Docker in an LXC container
text
Proxmox host
└── LXC system container
└── Docker Engine
└── Application containers
This uses fewer resources but adds complexity around nesting, storage drivers, networking, AppArmor, cgroups, and device access.
Option 3: Docker directly on the Proxmox host
This is generally discouraged because Docker can alter firewall behavior, bridges, packet-filtering rules, storage configuration, and upgrade behavior.
26. Apply Container Security Practices
1. Prefer unprivileged containers.
2. Keep Proxmox VE updated.
3. Keep container operating systems updated.
4. Use SSH keys instead of passwords.
5. Disable unnecessary services.
6. Restrict management access by network.
7. Enable appropriate firewall rules.
8. Avoid exposing the Proxmox interface directly to the Internet.
9. Use multifactor authentication for administrators.
10. Back up container data.
11. Test restores.
12. Do not mount sensitive host directories into containers.
13. Avoid unnecessary nesting.
14. Avoid privileged containers unless technically required.
15. Use separate containers for unrelated services.
16. Monitor logs and resource usage.
17. Use a VM for untrusted code or workloads requiring stronger isolation.
27. Maintain Containers
Weekly tasks
• Review failed Proxmox tasks.
• Review backup results.
• Check storage utilization.
• Review high CPU or memory usage.
• Check container service health.
Monthly tasks
• Install operating-system updates.
• Review firewall rules.
• Review user accounts and SSH keys.
• Review available disk space.
• Verify monitoring and alerts.
• Test at least one representative backup restore.
Quarterly tasks
• Review resource allocations.
• Remove obsolete snapshots.
• Review privileged containers.
• Review containers with nesting enabled.
• Review unsupported or end-of-life operating systems.
• Confirm documentation and recovery procedures.
28. Example Deployment: Create a Small Web Server
Use these example settings:
| Setting | Value |
| CT ID | 120 |
| Hostname | web01 |
| Template | Current Debian template |
| Unprivileged | Yes |
| Cores | 2 |
| Memory | 1 GB |
| Swap | 512 MB |
| Root disk | 8 GB |
| IP address | 192.168.10.120/24 |
| Gateway | 192.168.10.1 |
| Bridge | vmbr0 |
| Start at boot | Yes |
| Firewall | Yes |
Then run:
bash
pct start 120
pct enter 120
apt update
apt full-upgrade -y
apt install nginx -y
systemctl enable --now nginx
systemctl status nginx
ss -tulpn | grep :80
curl http://127.0.0.1
Test from another computer by opening:
text
http://192.168.10.120
Configure firewall access, add the container to the backup schedule, and document its purpose, owner, IP address, and recovery procedure.
29. Essential pct Command Reference
| Task | Command |
| List containers | pct list |
| Show status | pct status 110 |
| Show configuration | pct config 110 |
| Start | pct start 110 |
| Graceful shutdown | pct shutdown 110 |
| Stop immediately | pct stop 110 |
| Reboot | pct reboot 110 |
| Open console | pct console 110 |
| Enter shell | pct enter 110 |
| Set memory | pct set 110 --memory 4096 |
| Set CPU cores | pct set 110 --cores 4 |
| Enable startup | pct set 110 --onboot 1 |
| Create snapshot | pct snapshot 110 snapshot-name |
| List snapshots | pct listsnapshot 110 |
| Roll back snapshot | pct rollback 110 snapshot-name |
| Delete snapshot | pct delsnapshot 110 snapshot-name |
| Create backup | vzdump 110 --storage backup-storage |
| Display help | pct help |
| Display command help | pct help create |
30. Final Deployment Checklist
• [ ] The workload is appropriate for LXC.
• [ ] An unprivileged container was used unless privilege is required.
• [ ] CPU and memory limits are reasonable.
• [ ] The root disk has adequate free space.
• [ ] Application data is stored appropriately.
• [ ] The IP address and hostname are documented.
• [ ] DNS resolution works.
• [ ] The operating system is updated.
• [ ] SSH keys are configured.
• [ ] Unnecessary services are disabled.
• [ ] Firewall rules are enabled and tested.
• [ ] Automatic startup is configured.
• [ ] Startup order is configured when dependencies exist.
• [ ] Monitoring is active.
• [ ] Scheduled backups are active.
• [ ] A restore has been tested.
• [ ] Temporary snapshots have been removed.
• [ ] The application owner and recovery procedure are documented.
Conclusion
Proxmox LXC containers provide an efficient way to run Linux server workloads with less overhead than complete virtual machines. Their efficiency comes from sharing the Proxmox host’s Linux kernel.
A well-managed deployment begins by selecting the correct virtualization model. Use an unprivileged LXC container for ordinary trusted Linux services, a KVM virtual machine for stronger isolation or specialized operating-system requirements, and a dedicated Linux VM for most production Docker environments.
Reliable container operations depend on more than creating the container. Administrators must also plan storage, networking, security, updates, monitoring, backups, and tested recovery procedures.
Reference
Proxmox VE documentation: https://pve.proxmox.com/pve-docs/
