If you want to run Docker Containers in Proxmox, you have two choices: an LXC container or a virtual machine. The primary contrast between both methods lies in the resources that the Proxmox host consumes. The resources must be decided upon in advance when creating a virtual machine (VM). That said, if you specify that your VM should use 4GB of memory, it will require an entire 4GB when activated. LXC containers are distinct as the allocated memory is more like a cap instead. For this reason, LXC containers drastically reduce system resources compared to VMs. Although numerous other distinctions exist between LXC containers and VMs, the reduction in system resource utilization is perhaps the most evident regularly.
For this guide, I’ll run through a setup I have in my homelab, which does not deal with much compute or traffic throughput workloads at all
Setup
Some example lightweight services I use in my home lab infrastructure are
lightweight System Requirements:
- Deployed on Proxmox
- Debian 11 LXC Container
- 512MiB or 1024MiB Memory
- 1 Core CPU
- 8GB Disk Space
Setup Docker host
Enable nesting
Older versions of Proxmox
- In older versions of Proxmox, you need to enable nesting features in the Proxmox VE Container Configuration so Docker can run. Newer vesions of proxmox has exposed this option as a tick box in the Web GUI
For older versions of Proxmox, the /etc/pve/lxc/<CTID>.conf
files stores
container configuration, where CTID is the numeric ID of the given container.
# On the proxmox server
# e.g., where my LXC ID is 101
nano /etc/pve/lxc/101.conf
insert at the bottom of the file:
features: keyctl=1,nesting=1
- Reboot the container
Newer versions of Proxmox
For Newer versions of Proxmox, You can enable this option in the GUIYou can enable this option in the GUI
Install Docker and other tools
- Optionally, Install any prerequisite or useful tools on the Docker host
# Run as root
apt apt update && apt upgrade -y
apt install -y dnsutils net-tools sudo jq git
- See Install Docker Engine for official Install guide. For example, I can run the following for my Debian based system
# Run as root
apt-get update
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose
- Create the docker group and add your user to the docker group.
sudo groupadd docker
sudo usermod -aG docker $USER
- Confirm you can run a docker container:
docker run hello-world
- To allow us to start containers on reboot, ensure
docker.service
enabled on system startup
# Start Docker containers on host start/reboot
$ sudo systemctl enable docker
Clone repo and start services!
If you keep your Docker container Infrastructure-as-Code then you can pull it from your repo and run
- Create designated directory for the repo and
git clone
the repo locally
export GITHUB_USER=armsultan
export GITHUB_TOKEN=[secret]
export GITHUB_REPOSITORY=armsultan/t3st-core-services
git clone https://${GITHUB_USER}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY} ~/services
- Start the Docker Containers for the first time:
cd ~/services
docker-compose up -d
- Run
docker ps
and check there are no errors:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e4a6043a23c maildev/maildev:2.0.5 "bin/maildev" 55 seconds ago Up 54 seconds (healthy) 0.0.0.0:25->1025/tcp, :::25->1025/tcp, 0.0.0.0:80->1080/tcp, :::80->1080/tcp maildev
e5564323dd3d services_syslog-ng "tini -- /bin/sh -c …" 55 seconds ago Up 54 seconds 0.0.0.0:601->601/tcp, :::601->601/tcp, 0.0.0.0:514->514/udp, :::514->514/udp, 0.0.0.0:6514->6514/tcp, :::6514->6514/tcp syslog-ng
48bc51ee1d3d services_coredns "/coredns -conf /etc…" 55 seconds ago Up 54 seconds 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, :::53->53/tcp, :::53->53/udp
Other Tips
-
*Optional: Disable Postfix on the Docker Host Since we will use port 25
# Kill process on port 25 kill -9 $(lsof -t -i:25 -sTCP:LISTEN) # Disable postfix sudo update-rc.d postfix disable
-
For your containers to start on boot, make sure your services in your
docker-compose.yml
has one the following options# It will always restart the container, no matter whatever be the exit code is. restart: always # Will keep an instance running unless the container is stopped restart: unless-stopped # will issue a restart if the exit code indicated a failure restart: on-failure
This will run when you reboot your system if you run below command only once
docker-compose up -d
-
Limit logs to prevent logs filling your system
logging:
driver: "json-file"
options:
max-file: "5"
max-size: "10m"