Skip to main content

Proxmox Package Mirror

🧭 Lab Architecture (what you’re building)

You will create two internet-connected machines:

Name Role OS
mirror-online Package mirror builder Debian 13 (Trixie)
pve-prox-online Proxmox VE node (client) Proxmox VE 9

Both are online for now. Later we simulate air-gap by disconnecting network.


🖥️ Step 0 — Create VirtualBox VMs

VM 1 — apt-mirror (Debian 13)

  • Name: apt-mirror
  • OS: Debian (64-bit)
  • CPU: 2 cores
  • RAM: 4 GB
  • Disk: 200–500 GB (important for mirror!)
  • Network: NAT (internet access)

Install Debian 13 (Trixie) minimal.


VM 2 — prox-online (Proxmox VE 9)

  • Name: prox-online
  • OS: Debian (64-bit)
  • CPU: 4 cores
  • RAM: 8 GB (minimum 4 works)
  • Disk: 64–128 GB
  • Network: NAT

Install Proxmox VE 9 ISO.


🌐 Step 1 — Basic networking

After install:

On apt-mirror

ip a

Example:

192.168.1.240

On prox-online

Test connectivity:

ping 8.8.8.8

🧱 Step 2 — Install mirror on apt-mirror

apt update
apt install apt-mirror nginx

⚙️ Step 3 — Configure mirror

nano /etc/apt/mirror.list

Use:

set base_path /var/spool/apt-mirror
set nthreads 20
set _tilde 0

############ Debian 13 ############
deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware

############ Proxmox VE 9 ############
deb http://download.proxmox.com/debian/pve trixie pve-no-subscription

clean http://deb.debian.org/debian
clean http://security.debian.org/debian-security
clean http://download.proxmox.com/debian/pve

⬇️ Step 4 — Run initial mirror

apt-mirror

⏳ This will take a long time (first sync).


🌐 Step 5 — Serve mirror via nginx

nano /etc/nginx/sites-available/mirror
server {
    listen 80;
    server_name mirror01;

    root /var/spool/apt-mirror/mirror;
    autoindex on;
}

Enable:

ln -s /etc/nginx/sites-available/mirror /etc/nginx/sites-enabled/
systemctl reload nginx

🧪 Step 6 — Test mirror

From prox-online:

curl http://mirror01/deb.debian.org/debian/

If DNS fails, use IP:

curl http://192.168.56.10/deb.debian.org/debian/

⚙️ Step 7 — Configure Proxmox (prox-online)

Edit:

nano /etc/apt/sources.list

Replace with:

deb http://mirror01/deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://mirror01/deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb http://mirror01/security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware

deb http://mirror01/download.proxmox.com/debian/pve trixie pve-no-subscription

Disable enterprise repo:

sed -i 's/^deb/#deb/' /etc/apt/sources.list.d/pve-enterprise.list

🔄 Step 8 — Test updates via mirror

apt update
apt upgrade

👉 If this works, your mirror is correct.


🔒 Step 9 — Simulate air-gapped environment

Now simulate real-world:

Option A (simple)

  • Disable internet in VirtualBox (set network to “Host-only”)

Option B (better)

  • Keep internal network between VMs
  • Remove outbound internet

Then test again:

apt update

✅ If it still works → mirror is fully self-contained


💾 Step 10 — (Real-world) Transfer model

In production you will:

On internet system (mirror01):

apt-mirror
rsync -av --delete /var/spool/apt-mirror/mirror/ /media/usb/

Move to airgap:

rsync -av /media/usb/ /srv/mirror/

Serve via nginx → same as above


⚠️ Important lessons from this lab

1. DNS vs IP

In airgap, DNS usually doesn’t exist → use IP or internal DNS.


2. Mirror path structure matters

APT expects:

/deb.debian.org/debian
/security.debian.org/debian-security
/download.proxmox.com/debian/pve

Do NOT flatten directories.


3. Storage grows fast

Even in lab:

  • Start small if needed:
deb http://deb.debian.org/debian trixie main

👍 Final result

You now have:

mirror01 (Debian) → builds mirror → serves HTTP
pve01 (Proxmox) → installs updates from mirror

And you verified:

  • works online
  • works offline

🚀 If you want next

I can help you:

  • shrink mirror to “Proxmox-only minimal set” (~20–40GB)
  • add USB incremental sync strategy (fast updates)
  • or build a fully automated offline update pipeline with versioning

Just tell me 👍