Expanding Your Mirror
So far, you’ve created a minimal mirror with a single architecture, suite, and section. In practice, you’ll often need to support multiple architectures, distribution releases, and repository sections. This section shows how to expand your mirror configuration.
Understanding the Dimensions
Repository mirrors can be expanded across three dimensions:
- Architectures: CPU architectures (amd64, arm64, i386, etc.)
- Suites: Distribution releases (noble, jammy, focal for Ubuntu; bookworm, trixie, sid for Debian)
- Sections: Repository components (main, universe, restricted, multiverse for Ubuntu; main, contrib, non-free for Debian)
Each combination you add increases the mirror size and sync time.
Adding Multiple Architectures
Many environments support multiple CPU architectures. Add them to the architectures array:
dir = "/var/www/apt/"
[snapshot]
path = "/var/lib/mirrorctl/snapshots"
default_name_format = "2006-01-02T15-04-05Z"
[snapshot.prune]
keep_last = 5
[mirrors.ubuntu-noble]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble"]
sections = ["main"]
architectures = ["amd64", "arm64"] # Added arm64
publish_to_staging = trueThis mirrors both x86-64 and ARM64 packages, supporting servers, desktops, and ARM-based systems.
Common architecture combinations:
["amd64"]: x86-64 only (most common)["amd64", "arm64"]: Modern servers and ARM systems["amd64", "i386"]: Include legacy 32-bit support["amd64", "arm64", "armhf"]: Full ARM compatibility (32 and 64-bit)
Sync to download the arm64 packages:
sudo mirrorctl sync ubuntu-nobleThe new architecture will be added:
INFO Syncing mirror: ubuntu-noble
INFO Downloading packages for arm64
INFO Downloaded 8,450 new packages for arm64
INFO Sync completed successfullyAdding Multiple Suites
Organizations often need to support multiple OS versions. Add multiple releases to the suites array:
[mirrors.ubuntu-noble]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble", "jammy"] # Ubuntu 24.04 and 22.04
sections = ["main"]
architectures = ["amd64", "arm64"]
publish_to_staging = trueThis mirrors both Ubuntu 24.04 LTS (Noble) and 22.04 LTS (Jammy).
Common suite combinations:
- Ubuntu LTS only:
["noble", "jammy", "focal"](24.04, 22.04, 20.04) - Latest + LTS:
["plucky", "noble"](current + latest LTS) - Debian stable + testing:
["bookworm", "trixie"]
After adding suites, sync to download them:
sudo mirrorctl sync ubuntu-nobleThe sync will download packages for all suite/architecture/section combinations.
Disk space considerations
Each suite roughly doubles the mirror size:
- 1 suite (noble) × 1 section (main) × 1 arch (amd64): ~45 GB
- 2 suites (noble, jammy) × 1 section × 1 arch: ~90 GB
- 3 suites × 1 section × 1 arch: ~135 GB
Check space requirements before syncing:
sudo mirrorctl sync --dry-runAdding Multiple Sections
Sections contain different categories of packages. Ubuntu uses:
- main: Officially supported open source software
- universe: Community-maintained open source software
- restricted: Proprietary drivers and firmware
- multiverse: Software with licensing restrictions
Add sections to mirror more packages:
[mirrors.ubuntu-noble]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble", "jammy"]
sections = ["main", "universe"] # Added universe
architectures = ["amd64", "arm64"]
publish_to_staging = trueThis dramatically expands available packages:
- main only: ~13,000 packages
- main + universe: ~60,000+ packages
universe significantly increases mirror size (often 3-4x). The example above would grow from ~90 GB to ~300+ GB.For Debian, sections are:
- main: Free software that meets Debian Free Software Guidelines
- contrib: Free software that depends on non-free software
- non-free: Software that doesn’t meet DFSG
- non-free-firmware: Non-free firmware (Debian 12+)
[mirrors.debian-bookworm]
url = "https://deb.debian.org/debian/"
suites = ["bookworm"]
sections = ["main", "contrib", "non-free", "non-free-firmware"]
architectures = ["amd64"]Including Source Packages
Source packages allow building software from source and auditing code:
[mirrors.ubuntu-noble]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble"]
sections = ["main", "universe"]
architectures = ["amd64", "arm64"]
mirror_source = true # Include source packages
publish_to_staging = trueSource packages add significant size (often 30-50% more) but are valuable for:
- Building custom packages
- Security audits
- Compliance requirements
- Offline development environments
Creating Multiple Mirror Configurations
You can mirror multiple repositories by defining multiple [mirrors.*] sections:
dir = "/var/www/apt/"
[snapshot]
path = "/var/lib/mirrorctl/snapshots"
default_name_format = "2006-01-02T15-04-05Z"
[snapshot.prune]
keep_last = 5
# Ubuntu mirror
[mirrors.ubuntu]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble", "jammy"]
sections = ["main", "universe"]
architectures = ["amd64", "arm64"]
publish_to_staging = true
# Ubuntu security updates (separate repository)
[mirrors.ubuntu-security]
url = "https://security.ubuntu.com/ubuntu/"
suites = ["noble-security", "jammy-security"]
sections = ["main", "universe"]
architectures = ["amd64", "arm64"]
publish_to_staging = true
# Debian mirror
[mirrors.debian]
url = "https://deb.debian.org/debian/"
suites = ["bookworm", "trixie"]
sections = ["main", "contrib", "non-free"]
architectures = ["amd64"]
publish_to_staging = trueSync all mirrors:
sudo mirrorctl syncOr sync specific mirrors:
sudo mirrorctl sync ubuntu ubuntu-securityPartial Mirroring with Filters
For large repositories, you might not want everything. Use filters to reduce mirror size:
[mirrors.ubuntu-noble]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble"]
sections = ["main", "universe"]
architectures = ["amd64"]
# Filter configuration
[mirrors.ubuntu-noble.filters]
keep_versions = 2 # Only keep the 2 most recent versions of each package
exclude_patterns = [
".*-dbg$", # Exclude debug symbol packages
".*-doc$", # Exclude documentation packages
"linux-image-.*-generic-hwe.*" # Exclude HWE kernels
]Filters help manage disk space when mirroring large repositories.
Understanding keep_versions
Debian repositories keep multiple versions of packages. For example:
nginx_1.18.0-1_amd64.debnginx_1.20.1-1_amd64.debnginx_1.24.0-2_amd64.deb
Setting keep_versions = 2 keeps only the 2 most recent:
nginx_1.24.0-2_amd64.debnginx_1.20.1-1_amd64.deb
This is useful for development mirrors where you don’t need full history.
For production, use keep_versions = 0 (keep all versions) to ensure maximum compatibility.
Example: Production-Ready Configuration
Here’s a realistic production configuration supporting multiple environments:
dir = "/var/www/apt/"
[snapshot]
path = "/var/lib/mirrorctl/snapshots"
default_name_format = "2006-01-02T15-04-05Z"
[snapshot.prune]
keep_last = 7
keep_within = "30d"
# Primary Ubuntu mirror - main and universe
[mirrors.ubuntu]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble", "jammy", "focal"] # Support 3 LTS versions
sections = ["main", "universe"]
architectures = ["amd64", "arm64"]
publish_to_staging = true
# Ubuntu security updates - critical for production
[mirrors.ubuntu-security]
url = "https://security.ubuntu.com/ubuntu/"
suites = ["noble-security", "jammy-security", "focal-security"]
sections = ["main", "universe"]
architectures = ["amd64", "arm64"]
publish_to_staging = true
# Ubuntu updates repository
[mirrors.ubuntu-updates]
url = "https://archive.ubuntu.com/ubuntu/"
suites = ["noble-updates", "jammy-updates", "focal-updates"]
sections = ["main", "universe"]
architectures = ["amd64", "arm64"]
publish_to_staging = trueSync all:
sudo mirrorctl syncMonitoring Disk Usage
As your mirror expands, monitor disk usage:
# Check total mirror size
du -sh /var/www/apt/*
# Check snapshot sizes
du -sh /var/lib/mirrorctl/snapshots/*/*Use --dry-run before adding new suites or sections:
sudo mirrorctl sync --dry-runWhat’s Next?
Now that your mirror is expanded, learn about Security Best Practices to ensure your mirror is verified and trustworthy.