Skip to main content

Proxmox VE

This guide covers deploying Nekzus on Proxmox Virtual Environment (PVE). Proxmox is a powerful open-source virtualization platform that supports both VMs and LXC containers, making it ideal for homelab and production deployments.


Overview​

Proxmox offers three deployment options for Nekzus:

MethodUse CaseResource UsageComplexity
LXC ContainerRecommended for most usersLow (256 MB RAM)Easy
VM with DockerFull isolation, complex networkingMedium (512 MB+ RAM)Medium
Docker on HostQuick testing, single-node setupsMinimalEasy

Prerequisites​

Before proceeding, ensure you have:

  • Proxmox VE 7.0 or newer installed
  • Root or administrative access to the Proxmox host
  • At least 512 MB free RAM and 2 GB disk space
  • Network access to Docker Hub (or local registry)
  • Basic familiarity with Proxmox web interface

LXC containers provide near-native performance with minimal overhead. This is the recommended deployment method for most users.

Step 1: Download Container Template​

  1. Open the Proxmox web interface

  2. Navigate to your storage (e.g., local)

  3. Click CT Templates

  4. Click Templates and download one of these:

    • Debian 12 (recommended)
    • Ubuntu 22.04 LTS
    • Alpine Linux (smallest footprint)
  1. Select your storage under Datacenter
  2. Click CT Templates in the content panel
  3. Click Templates button
  4. Search for "debian-12" or "ubuntu-22.04"
  5. Click Download

Step 2: Create the LXC Container​

  1. Click Create CT in the top-right corner
  2. Configure the container:

General Tab:

  • CT ID: Choose a unique ID (e.g., 110)
  • Hostname: nekzus
  • Password: Set a root password
  • SSH public key: (Optional) Add your SSH key

Template Tab:

  • Storage: Select where you downloaded the template
  • Template: Choose your downloaded template

Disks Tab:

  • Storage: Select your preferred storage
  • Disk size: 4 GB minimum (8 GB recommended)

CPU Tab:

  • Cores: 1 (2 recommended for production)

Memory Tab:

  • Memory: 512 MB (256 MB minimum)
  • Swap: 256 MB

Network Tab:

  • Bridge: vmbr0 (or your network bridge)
  • IPv4: DHCP or static IP
  • IPv6: Optional
  1. Click Finish to create the container

Step 3: Configure Container Features​

For Docker to run inside the LXC container, enable nesting:

# On Proxmox host
pct set 110 --features nesting=1
Privileged vs Unprivileged Containers

Unprivileged (Recommended):

  • More secure, runs with reduced privileges
  • Requires nesting=1 feature for Docker
  • Some Docker images may have limitations

Privileged:

  • Full access to host resources
  • Easier Docker compatibility
  • Less secure, use only if necessary

To create a privileged container, add --unprivileged 0 to the creation command.

Step 4: Install Docker in LXC​

Start the container and install Docker:

# Enter the container
pct enter 110

# Update packages
apt update && apt upgrade -y

# Install prerequisites
apt install -y ca-certificates curl gnupg

# Add Docker GPG key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

# Add Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Verify installation
docker run hello-world

Step 5: Deploy Nekzus​

Create the deployment directory and configuration:

# Create project directory
mkdir -p /opt/nekzus
cd /opt/nekzus

# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
nekzus:
image: nstalgic/nekzus:latest
container_name: nekzus
environment:
NEKZUS_JWT_SECRET: "${NEKZUS_JWT_SECRET}"
NEKZUS_BOOTSTRAP_TOKEN: "${NEKZUS_BOOTSTRAP_TOKEN}"
NEKZUS_BASE_URL: "${NEKZUS_BASE_URL:-http://nekzus:8080}"
NEKZUS_ADDR: ":8080"
ports:
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- nekzus-data:/app/data
restart: unless-stopped
healthcheck:
test: ["/app/nekzus", "--health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s

volumes:
nekzus-data:
EOF

# Generate secure secrets
cat > .env << EOF
NEKZUS_JWT_SECRET=$(openssl rand -base64 32)
NEKZUS_BOOTSTRAP_TOKEN=$(openssl rand -base64 24)
NEKZUS_BASE_URL=http://$(hostname -I | awk '{print $1}'):8080
EOF

# Start Nekzus
docker compose up -d

# Verify it's running
docker compose logs -f

Step 6: Configure Auto-Start​

Enable the container to start on boot:

# On Proxmox host
pct set 110 --onboot 1

Docker will automatically start the Nekzus container when the LXC boots.


Option 2: Virtual Machine with Docker​

VMs provide full isolation and are ideal for complex networking scenarios or when running untrusted workloads.

Step 1: Download ISO​

Download a Linux ISO for your VM:

  1. Navigate to your storage (e.g., local)
  2. Click ISO Images
  3. Click Download from URL
  4. Use one of these URLs:
    • Debian 12: https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.4.0-amd64-netinst.iso
    • Ubuntu 22.04: https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso

Step 2: Create the VM​

  1. Click Create VM in the top-right corner
  2. Configure the VM:

General Tab:

  • VM ID: Choose a unique ID (e.g., 200)
  • Name: nekzus-vm

OS Tab:

  • ISO image: Select your downloaded ISO
  • Type: Linux
  • Version: 6.x - 2.6 Kernel (or latest)

System Tab:

  • BIOS: Default (SeaBIOS)
  • Machine: q35
  • Qemu Agent: Enable (install qemu-guest-agent later)

Disks Tab:

  • Bus/Device: VirtIO Block
  • Storage: Select your storage
  • Disk size: 16 GB minimum (32 GB recommended)
  • Discard: Enable (for SSD/thin provisioning)

CPU Tab:

  • Sockets: 1
  • Cores: 2 (4 recommended for production)
  • Type: host (best performance)

Memory Tab:

  • Memory: 1024 MB (2048 MB recommended)

Network Tab:

  • Bridge: vmbr0
  • Model: VirtIO (paravirtualized)
  1. Click Finish and start the VM

Step 3: Install Operating System​

  1. Open the VM console via Proxmox web interface
  2. Complete the OS installation
  3. Install required packages after first boot:
# Update system
apt update && apt upgrade -y

# Install QEMU guest agent for better Proxmox integration
apt install -y qemu-guest-agent
systemctl enable qemu-guest-agent
systemctl start qemu-guest-agent

# Install Docker (same as LXC step)
apt install -y ca-certificates curl gnupg

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Step 4: Deploy Nekzus​

Follow the same deployment steps as the LXC container (Step 5 above).


Option 3: Docker on Proxmox Host​

For quick testing or single-node setups, you can run Docker directly on the Proxmox host.

Production Considerations

Running Docker on the Proxmox host is not recommended for production because:

  • Container issues can affect the hypervisor
  • Resource contention with VMs/LXCs
  • Security risk if containers are compromised
  • Makes Proxmox upgrades more complex

Step 1: Install Docker on Proxmox Host​

# SSH into Proxmox host
ssh root@proxmox-host

# Install Docker
apt update
apt install -y docker.io docker-compose-plugin

# Enable Docker service
systemctl enable docker
systemctl start docker

Step 2: Deploy Nekzus​

# Create project directory
mkdir -p /opt/nekzus
cd /opt/nekzus

# Create docker-compose.yml and .env (same as LXC Step 5)
# Then start:
docker compose up -d

Network Configuration​

Bridge Networking​

Proxmox uses Linux bridges for networking. The default bridge vmbr0 connects VMs/LXCs to your physical network.

View current bridges:

# On Proxmox host
cat /etc/network/interfaces

Example bridge configuration:

auto vmbr0
iface vmbr0 inet static
address 192.168.1.100/24
gateway 192.168.1.1
bridge-ports enp0s3
bridge-stp off
bridge-fd 0

VLAN Configuration​

To isolate Nekzus on a separate VLAN:

1. Create a VLAN-aware bridge:

Add to /etc/network/interfaces:

auto vmbr0
iface vmbr0 inet manual
bridge-ports enp0s3
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094

2. Assign VLAN to container/VM:

# Assign VLAN 100 to container
pct set 110 --net0 name=eth0,bridge=vmbr0,tag=100,ip=dhcp

Static IP Configuration​

For production deployments, use static IPs:

pct set 110 --net0 name=eth0,bridge=vmbr0,ip=192.168.1.110/24,gw=192.168.1.1

Port Forwarding (NAT)​

If your Proxmox host is behind NAT, forward ports to the container/VM:

# On Proxmox host - Add to /etc/network/interfaces under vmbr0
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to 192.168.1.110:8080
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to 192.168.1.110:8080

Storage Configuration​

Bind Mounts (LXC)​

Mount host directories into LXC containers for persistent storage:

# Create host directory
mkdir -p /mnt/nekzus-data

# Add bind mount to container
pct set 110 --mp0 /mnt/nekzus-data,mp=/app/data

# Restart container
pct restart 110

Update your docker-compose.yml to use the mounted path:

volumes:
- /app/data:/app/data

Volume Configuration​

LXC with additional disk:

# Add 10GB disk to container
pct set 110 --mp1 local-lvm:10,mp=/data

VM with additional disk:

# Add 50GB disk to VM
qm set 200 --scsi1 local-lvm:50

Storage Recommendations​

Storage TypeUse CasePerformance
local-lvmVMs, high-performance LXCsBest
local-zfsSnapshots, data integrityGood
NFS/CIFSShared storage, backupsModerate
localISO images, templatesN/A

Docker Socket Access for Discovery​

Nekzus uses the Docker socket for automatic service discovery. Configure access based on your deployment method.

LXC Container​

The Docker socket inside the LXC is at /var/run/docker.sock. The docker-compose.yml already mounts it:

volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro

VM​

Same as LXC - mount the local Docker socket inside the VM.

Host Docker with Proxmox LXC/VM Discovery​

To discover containers running on the Proxmox host from within an LXC:

Method 1: Pass-through Docker socket (Privileged LXC only)

# On Proxmox host
# Add to /etc/pve/lxc/110.conf
lxc.mount.entry: /var/run/docker.sock var/run/docker.sock none bind,create=file 0 0

# Requires privileged container
pct set 110 --unprivileged 0

Method 2: Docker TCP socket (Recommended for unprivileged)

On Proxmox host, enable Docker TCP:

# Create Docker daemon override
mkdir -p /etc/systemd/system/docker.service.d/
cat > /etc/systemd/system/docker.service.d/override.conf << 'EOF'
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375
EOF

# Reload and restart Docker
systemctl daemon-reload
systemctl restart docker

In your LXC container, configure Nekzus to use TCP:

# config.yaml
discovery:
docker:
enabled: true
socket_path: "tcp://192.168.1.100:2375" # Proxmox host IP
poll_interval: "30s"
Security Warning

Exposing Docker TCP without TLS is a security risk. For production:

  • Use Docker TLS certificates
  • Restrict access with firewall rules
  • Consider using a Unix socket proxy

TLS Configuration​

Deploy with Caddy for automatic TLS:

docker-compose.yml
services:
nekzus:
image: nstalgic/nekzus:latest
container_name: nekzus
networks:
- nekzus
environment:
NEKZUS_JWT_SECRET: "${NEKZUS_JWT_SECRET}"
NEKZUS_BOOTSTRAP_TOKEN: "${NEKZUS_BOOTSTRAP_TOKEN}"
NEKZUS_BASE_URL: "${NEKZUS_BASE_URL}"
NEKZUS_ADDR: ":8080"
command: ["--config", "/app/configs/config.yaml", "--insecure-http"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- nekzus-data:/app/data
restart: unless-stopped

caddy:
image: caddy:2.8-alpine
container_name: nekzus-caddy
depends_on:
- nekzus
networks:
- nekzus
ports:
- "8443:8443"
- "80:80"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
restart: unless-stopped

networks:
nekzus:
driver: bridge

volumes:
nekzus-data:
caddy-data:
caddy-config:
Caddyfile
:8443 {
reverse_proxy nekzus:8080
tls internal
}

:80 {
redir https://{host}:8443{uri} permanent
}

Using Proxmox Reverse Proxy​

If you already have a reverse proxy on Proxmox, configure it to forward to Nekzus:

Nginx example:

server {
listen 443 ssl;
server_name nekzus.yourdomain.com;

ssl_certificate /etc/ssl/certs/nekzus.crt;
ssl_certificate_key /etc/ssl/private/nekzus.key;

location / {
proxy_pass http://192.168.1.110:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Backup and Restore​

Proxmox Backup​

Backup LXC container:

# Manual backup
vzdump 110 --storage local --compress zstd --mode snapshot

# Restore
pct restore 111 /var/lib/vz/dump/vzdump-lxc-110-*.tar.zst

Backup VM:

# Manual backup
vzdump 200 --storage local --compress zstd --mode snapshot

# Restore
qmrestore /var/lib/vz/dump/vzdump-qemu-200-*.vma.zst 201

Automated Backups​

Configure automated backups in Proxmox:

  1. Navigate to Datacenter > Backup
  2. Click Add
  3. Configure schedule, storage, and compression
  4. Select your Nekzus container/VM

Nekzus Data Backup​

In addition to Proxmox backups, Nekzus has built-in backup functionality:

config.yaml
backup:
enabled: true
directory: "/app/data/backups"
schedule: "24h"
retention: 7

Troubleshooting​

LXC Container Issues​

Docker fails to start in LXC

Symptom: Cannot connect to the Docker daemon

Solutions:

  1. Enable nesting feature:

    pct set 110 --features nesting=1
    pct restart 110
  2. Check container is not running in unprivileged mode with incompatible settings:

    pct config 110 | grep -E "unprivileged|features"
  3. For persistent issues, try privileged mode:

    pct set 110 --unprivileged 0
    pct restart 110
Permission denied errors

Symptom: permission denied while trying to connect to Docker daemon socket

Solutions:

  1. Check socket permissions:

    ls -la /var/run/docker.sock
  2. Add user to docker group:

    usermod -aG docker $USER
  3. Restart Docker service:

    systemctl restart docker
Network connectivity issues in LXC

Symptom: Container cannot reach internet or other hosts

Solutions:

  1. Check network configuration:

    pct config 110 | grep net
    ip addr show eth0
  2. Verify DNS resolution:

    cat /etc/resolv.conf
    ping -c 3 8.8.8.8
  3. Check bridge configuration on Proxmox host:

    brctl show

VM Issues​

VM network not working

Symptom: No network connectivity after OS installation

Solutions:

  1. Ensure VirtIO drivers are installed:

    lsmod | grep virtio
  2. Check network interface:

    ip link show
    dhclient -v eth0
  3. Verify bridge configuration in Proxmox

Slow VM performance

Symptom: High latency, slow disk I/O

Solutions:

  1. Use VirtIO drivers for disk and network
  2. Enable CPU type host:
    qm set 200 --cpu host
  3. Enable discard for SSD:
    qm set 200 --scsi0 local-lvm:32,discard=on
  4. Install QEMU guest agent

Docker Discovery Issues​

Services not being discovered

Symptom: Docker containers not appearing in Nekzus

Solutions:

  1. Verify Docker socket is mounted:

    docker compose exec nekzus ls -la /var/run/docker.sock
  2. Check discovery is enabled in config:

    discovery:
    docker:
    enabled: true
    socket_path: "unix:///var/run/docker.sock"
  3. Ensure containers have Nekzus labels:

    labels:
    nekzus.enable: "true"
    nekzus.app.name: "My Service"
  4. Check Nekzus logs:

    docker compose logs nekzus | grep -i discovery
Docker socket access denied in unprivileged LXC

Symptom: Cannot access Docker socket from host

Solutions:

  1. Use Docker TCP socket instead (see Docker Socket Access section)
  2. Convert to privileged container if security permits
  3. Use a socket proxy like docker-socket-proxy

Resource Issues​

Container/VM running out of memory

Symptom: OOM killer terminating processes

Solutions:

  1. Increase memory allocation:

    # LXC
    pct set 110 --memory 1024

    # VM
    qm set 200 --memory 2048
  2. Add swap:

    pct set 110 --swap 512
  3. Check Docker resource limits in compose file

High CPU usage

Symptom: Container/VM using excessive CPU

Solutions:

  1. Check running processes:

    docker stats
    top -c
  2. Limit CPU in Proxmox:

    # LXC
    pct set 110 --cpulimit 2

    # VM
    qm set 200 --cpulimit 2
  3. Check Nekzus health checks aren't too frequent


Performance Optimization​

LXC Optimization​

# Increase file descriptor limit
pct set 110 --mp0 /mnt/nekzus-data,mp=/app/data
pct set 110 --features nesting=1

# Add to /etc/pve/lxc/110.conf for better I/O
lxc.cgroup2.memory.max: 1G
lxc.cgroup2.cpu.max: 200000 100000

VM Optimization​

# Use VirtIO for best performance
qm set 200 --cpu host
qm set 200 --scsihw virtio-scsi-single
qm set 200 --net0 virtio,bridge=vmbr0

# Enable ballooning for memory efficiency
qm set 200 --balloon 512

Docker Optimization​

docker-compose.yml
services:
nekzus:
# ... other config ...
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

Security Best Practices​

  1. Use unprivileged LXC containers when possible
  2. Enable Proxmox firewall and restrict access to necessary ports
  3. Use strong secrets for JWT and bootstrap tokens
  4. Keep systems updated: Proxmox, container OS, and Docker
  5. Enable TLS for all external communication
  6. Limit Docker socket access - use read-only mounts
  7. Configure resource limits to prevent DoS
  8. Use VLANs to isolate Nekzus from sensitive networks
  9. Enable Proxmox two-factor authentication
  10. Regular backups with tested restore procedures

Next Steps​