Skip to content
daemonlessPublic

About

Managed FreeBSD pkg caching appliance — proxies pkg.FreeBSD.org to speed up package fetches across image builds and insulate them from upstream rate limits/outages.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Daemonless pkg cache

Build Status Last Commit OCI Pulls

Managed FreeBSD pkg caching appliance — proxies pkg.FreeBSD.org to speed up package fetches across image builds and insulate them from upstream rate limits/outages.

Port 80
Registry ghcr.io/daemonless/pkg-cache
Source https://github.com/daemonless/pkg-cache
Website https://daemonless.io/images/pkg-cache/

Version Tags

Tag Description Best For
latest daemonless Appliance. Managed FreeBSD pkg cache proxy built on nginx-base. Most users — recommended.

Prerequisites

Before deploying, ensure your host environment is ready. See the Quick Start Guide for host setup instructions.

Deployment

Podman Compose

services:
  pkg-cache:
    image: "ghcr.io/daemonless/pkg-cache:latest"
    container_name: pkg-cache
    environment:
      - TZ=UTC  # Timezone for the container
      - PKG_UPSTREAM=pkg.FreeBSD.org  # FreeBSD pkg mirror to proxy, e.g. pkg1.us.freebsd.org or pkg0.eu.freebsd.org. Defaults to the primary pkg.FreeBSD.org.
      - PKG_CACHE_SIZE=50g  # Max on-disk cache size (nginx max_size), e.g. 10g, 100g, 500g. Keep the /cache volume at least this big.
      - SKIP_CHOWN=true  # Skip the startup recursive chown of /config and /cache once ownership is recorded in /config/.chown_done (default true). Set false to force a chown on every start. The marker lives in /config, so /config must be a persistent volume for the skip to take effect across restarts.
      - PKG_LOG_MAX_SIZE=50m  # Size cap for each on-disk log in /config/log (access.log, error.log), e.g. 10m, 50m, 1g. A log past this is rotated away so /config can't fill; the stats totals are kept separately and survive rotation.
      - PKG_CACHE_APT=${PKG_CACHE_APT:-false}  # Cache apt repositories (Debian and Ubuntu) under /debian/, /debian-security/, /ubuntu/, /ubuntu-security/ and /ubuntu-ports/: true or false.
      - PKG_CACHE_DNF=${PKG_CACHE_DNF:-false}  # Cache dnf repositories (Fedora and EPEL) under /fedora/ and /epel/: true or false.
      - PKG_CACHE_APK=${PKG_CACHE_APK:-false}  # Cache Alpine's apk repositories under /alpine/: true or false.
      - PKG_CACHE_PACMAN=${PKG_CACHE_PACMAN:-false}  # Cache Arch Linux's pacman repositories under /archlinux/: true or false.
      - PKG_DEBIAN_UPSTREAM=https://deb.debian.org/debian  # Debian mirror for /debian/, as a URL base.
      - PKG_DEBIAN_SECURITY_UPSTREAM=https://deb.debian.org/debian-security  # Debian security mirror for /debian-security/, as a URL base.
      - PKG_UBUNTU_UPSTREAM=https://archive.ubuntu.com/ubuntu  # Ubuntu mirror for /ubuntu/ (amd64), as a URL base, e.g. https://us.archive.ubuntu.com/ubuntu.
      - PKG_UBUNTU_SECURITY_UPSTREAM=https://security.ubuntu.com/ubuntu  # Ubuntu security mirror for /ubuntu-security/, as a URL base.
      - PKG_UBUNTU_PORTS_UPSTREAM=https://ports.ubuntu.com/ubuntu-ports  # Ubuntu mirror for /ubuntu-ports/ (arm64 and other architectures), as a URL base.
      - PKG_FEDORA_UPSTREAM=https://dl.fedoraproject.org/pub/fedora/linux  # Fedora mirror for /fedora/, as a URL base ending at the directory that holds releases/ and updates/. The default is Fedora's master; a mirror near you is kinder, e.g. https://mirror.example.org/fedora/linux. It must answer itself: a mirror that redirects bypasses the cache.
      - PKG_EPEL_UPSTREAM=https://dl.fedoraproject.org/pub/epel  # EPEL mirror for /epel/, as a URL base.
      - PKG_ALPINE_UPSTREAM=https://dl-cdn.alpinelinux.org/alpine  # Alpine mirror for /alpine/, as a URL base.
      - PKG_ARCH_UPSTREAM=https://geo.mirror.pkgbuild.com  # Arch Linux mirror for /archlinux/, as a URL base (the directory that holds core/ and extra/).
    volumes:
      - "/containers/pkg-cache:/config"
      - "/containers/pkg-cache/cache:/cache"
    ports:
      - "80:80"
    # always (not unless-stopped) so FreeBSD's podman rc.d auto-starts it at boot
    restart: always

Save as compose.yaml, then run podman-compose up -d.

AppJail Director

.env:

# .env

DIRECTOR_PROJECT=pkg-cache
TZ=UTC
PKG_UPSTREAM=pkg.FreeBSD.org
PKG_CACHE_SIZE=50g
SKIP_CHOWN=true
PKG_LOG_MAX_SIZE=50m
PKG_CACHE_APT=${PKG_CACHE_APT:-false}
PKG_CACHE_DNF=${PKG_CACHE_DNF:-false}
PKG_CACHE_APK=${PKG_CACHE_APK:-false}
PKG_CACHE_PACMAN=${PKG_CACHE_PACMAN:-false}
PKG_DEBIAN_UPSTREAM=https://deb.debian.org/debian
PKG_DEBIAN_SECURITY_UPSTREAM=https://deb.debian.org/debian-security
PKG_UBUNTU_UPSTREAM=https://archive.ubuntu.com/ubuntu
PKG_UBUNTU_SECURITY_UPSTREAM=https://security.ubuntu.com/ubuntu
PKG_UBUNTU_PORTS_UPSTREAM=https://ports.ubuntu.com/ubuntu-ports
PKG_FEDORA_UPSTREAM=https://dl.fedoraproject.org/pub/fedora/linux
PKG_EPEL_UPSTREAM=https://dl.fedoraproject.org/pub/epel
PKG_ALPINE_UPSTREAM=https://dl-cdn.alpinelinux.org/alpine
PKG_ARCH_UPSTREAM=https://geo.mirror.pkgbuild.com

appjail-director.yml:

# appjail-director.yml

options:
  - virtualnet: ':<random> default'
  - nat:
services:
  pkg-cache:
    name: pkg_cache
    options:
      - container: 'args:--pull'
      - expose: '80:80 proto:tcp'
    oci:
      user: root
      environment:
        - TZ: !ENV '${TZ}'
        - PKG_UPSTREAM: !ENV '${PKG_UPSTREAM}'
        - PKG_CACHE_SIZE: !ENV '${PKG_CACHE_SIZE}'
        - SKIP_CHOWN: !ENV '${SKIP_CHOWN}'
        - PKG_LOG_MAX_SIZE: !ENV '${PKG_LOG_MAX_SIZE}'
        - PKG_CACHE_APT: !ENV '${PKG_CACHE_APT}'
        - PKG_CACHE_DNF: !ENV '${PKG_CACHE_DNF}'
        - PKG_CACHE_APK: !ENV '${PKG_CACHE_APK}'
        - PKG_CACHE_PACMAN: !ENV '${PKG_CACHE_PACMAN}'
        - PKG_DEBIAN_UPSTREAM: !ENV '${PKG_DEBIAN_UPSTREAM}'
        - PKG_DEBIAN_SECURITY_UPSTREAM: !ENV '${PKG_DEBIAN_SECURITY_UPSTREAM}'
        - PKG_UBUNTU_UPSTREAM: !ENV '${PKG_UBUNTU_UPSTREAM}'
        - PKG_UBUNTU_SECURITY_UPSTREAM: !ENV '${PKG_UBUNTU_SECURITY_UPSTREAM}'
        - PKG_UBUNTU_PORTS_UPSTREAM: !ENV '${PKG_UBUNTU_PORTS_UPSTREAM}'
        - PKG_FEDORA_UPSTREAM: !ENV '${PKG_FEDORA_UPSTREAM}'
        - PKG_EPEL_UPSTREAM: !ENV '${PKG_EPEL_UPSTREAM}'
        - PKG_ALPINE_UPSTREAM: !ENV '${PKG_ALPINE_UPSTREAM}'
        - PKG_ARCH_UPSTREAM: !ENV '${PKG_ARCH_UPSTREAM}'
    volumes:
      - pkg-cache: /config
      - pkg-cache_cache: /cache
volumes:
  pkg-cache:
    device: '/containers/pkg-cache'
  pkg-cache_cache:
    device: '/containers/pkg-cache/cache'

Makejail:

# Makejail

ARG tag=latest

OPTION container=boot
OPTION overwrite=force
OPTION from=ghcr.io/daemonless/pkg-cache:${tag}

Save the files above, then run appjail-director up.

Warning

Exposing ports in AppJail means that your service can be reached from remote hosts. If that is not your intention, do not expose the ports and communicate with the service using the jail's IPv4 address or hostname assigned by the virtual network.

To avoid exposing ports, just remove the expose option in your appjail-director.yml or from your command-line arguments.

Bastille

Warning

Bastille's OCI support is experimental. It requires buildah and shares the host network stack (inherit). Mount volumes with --volume HOST JAIL; without it, image-declared volumes are stored under ${bastille_volumesdir}/${jail}.

services:
  pkg-cache:
    name: pkg-cache
    image: "ghcr.io/daemonless/pkg-cache:latest"
    network:
      - mode: host
    environment:
      - TZ=UTC
      - PKG_UPSTREAM=pkg.FreeBSD.org
      - PKG_CACHE_SIZE=50g
      - SKIP_CHOWN=true
      - PKG_LOG_MAX_SIZE=50m
      - PKG_CACHE_APT=${PKG_CACHE_APT:-false}
      - PKG_CACHE_DNF=${PKG_CACHE_DNF:-false}
      - PKG_CACHE_APK=${PKG_CACHE_APK:-false}
      - PKG_CACHE_PACMAN=${PKG_CACHE_PACMAN:-false}
      - PKG_DEBIAN_UPSTREAM=https://deb.debian.org/debian
      - PKG_DEBIAN_SECURITY_UPSTREAM=https://deb.debian.org/debian-security
      - PKG_UBUNTU_UPSTREAM=https://archive.ubuntu.com/ubuntu
      - PKG_UBUNTU_SECURITY_UPSTREAM=https://security.ubuntu.com/ubuntu
      - PKG_UBUNTU_PORTS_UPSTREAM=https://ports.ubuntu.com/ubuntu-ports
      - PKG_FEDORA_UPSTREAM=https://dl.fedoraproject.org/pub/fedora/linux
      - PKG_EPEL_UPSTREAM=https://dl.fedoraproject.org/pub/epel
      - PKG_ALPINE_UPSTREAM=https://dl-cdn.alpinelinux.org/alpine
      - PKG_ARCH_UPSTREAM=https://geo.mirror.pkgbuild.com
    volumes:
      - "/containers/pkg-cache:/config"
      - "/containers/pkg-cache/cache:/cache"

Save as bastille-compose.yml, then run bastille up. Open http://<server>:80 from another machine (the server's own browser can't use a published port).

Parameters

Environment Variables

Variable Default Description
TZ UTC Timezone for the container
PKG_UPSTREAM pkg.FreeBSD.org FreeBSD pkg mirror to proxy, e.g. pkg1.us.freebsd.org or pkg0.eu.freebsd.org. Defaults to the primary pkg.FreeBSD.org.
PKG_CACHE_SIZE 50g Max on-disk cache size (nginx max_size), e.g. 10g, 100g, 500g. Keep the /cache volume at least this big.
SKIP_CHOWN true Skip the startup recursive chown of /config and /cache once ownership is recorded in /config/.chown_done (default true). Set false to force a chown on every start. The marker lives in /config, so /config must be a persistent volume for the skip to take effect across restarts.
PKG_LOG_MAX_SIZE 50m Size cap for each on-disk log in /config/log (access.log, error.log), e.g. 10m, 50m, 1g. A log past this is rotated away so /config can't fill; the stats totals are kept separately and survive rotation.
PKG_CACHE_APT ${PKG_CACHE_APT:-false} Cache apt repositories (Debian and Ubuntu) under /debian/, /debian-security/, /ubuntu/, /ubuntu-security/ and /ubuntu-ports/: true or false.
PKG_CACHE_DNF ${PKG_CACHE_DNF:-false} Cache dnf repositories (Fedora and EPEL) under /fedora/ and /epel/: true or false.
PKG_CACHE_APK ${PKG_CACHE_APK:-false} Cache Alpine's apk repositories under /alpine/: true or false.
PKG_CACHE_PACMAN ${PKG_CACHE_PACMAN:-false} Cache Arch Linux's pacman repositories under /archlinux/: true or false.
PKG_DEBIAN_UPSTREAM https://deb.debian.org/debian Debian mirror for /debian/, as a URL base.
PKG_DEBIAN_SECURITY_UPSTREAM https://deb.debian.org/debian-security Debian security mirror for /debian-security/, as a URL base.
PKG_UBUNTU_UPSTREAM https://archive.ubuntu.com/ubuntu Ubuntu mirror for /ubuntu/ (amd64), as a URL base, e.g. https://us.archive.ubuntu.com/ubuntu.
PKG_UBUNTU_SECURITY_UPSTREAM https://security.ubuntu.com/ubuntu Ubuntu security mirror for /ubuntu-security/, as a URL base.
PKG_UBUNTU_PORTS_UPSTREAM https://ports.ubuntu.com/ubuntu-ports Ubuntu mirror for /ubuntu-ports/ (arm64 and other architectures), as a URL base.
PKG_FEDORA_UPSTREAM https://dl.fedoraproject.org/pub/fedora/linux Fedora mirror for /fedora/, as a URL base ending at the directory that holds releases/ and updates/. The default is Fedora's master; a mirror near you is kinder, e.g. https://mirror.example.org/fedora/linux. It must answer itself: a mirror that redirects bypasses the cache.
PKG_EPEL_UPSTREAM https://dl.fedoraproject.org/pub/epel EPEL mirror for /epel/, as a URL base.
PKG_ALPINE_UPSTREAM https://dl-cdn.alpinelinux.org/alpine Alpine mirror for /alpine/, as a URL base.
PKG_ARCH_UPSTREAM https://geo.mirror.pkgbuild.com Arch Linux mirror for /archlinux/, as a URL base (the directory that holds core/ and extra/).

Volumes

Path Description
/config Logs (log/), stats totals (stats/) and the startup ownership marker (.chown_done). Mount as a persistent volume so the chown is skipped on later starts.
/cache Package cache storage (proxy_cache). Size to match max_size in nginx.conf (default 50G).

Ports

Port Protocol Description
80 TCP HTTP — pkg clients point their FreeBSD.conf url here; browsers get the stats page

How it works

Package files (*.pkg) are cached for 365 days — their filenames are versioned and immutable, so a HIT is always safe. Catalog metadata (meta.conf, packagesite.*, data.*) is cached for 1 minute instead, so pkg keeps resolving the latest updates without serving stale catalogs.

Linux package managers

apt (Debian, Ubuntu), dnf (Fedora, EPEL), apk (Alpine) and pacman (Arch Linux) can come through the cache too. Each is off until its switch is on: PKG_CACHE_APT, PKG_CACHE_DNF, PKG_CACHE_APK, PKG_CACHE_PACMAN. They live under their own paths (/debian/, /ubuntu/, /fedora/, /epel/, /alpine/, /archlinux/), with the same rules: packages are kept, indexes are refreshed every minute, and signatures still verify on the client. The landing page has the command for each distribution, with this cache's address filled in. Every family shares PKG_CACHE_SIZE: with Debian, Ubuntu or Fedora on, give it more than FreeBSD alone needs.

Pointing clients at the cache

On a build host (or any FreeBSD box), drop in /usr/local/etc/pkg/repos/FreeBSD.conf:

FreeBSD: {
  url: "http://<cache-host>/${ABI}/quarterly",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

Use plain http://, not pkg+http:// — pkg on FreeBSD 15 rejects the pkg+ scheme unless mirror_type is srv.

Then pkg update fetches through the cache — first pull is a MISS, everything after is a HIT, and package signatures still verify end-to-end.

pkg audit can use the cache too — the appliance proxies the FreeBSD vulnerability database at /vuxml/:

echo 'VULNXML_SITE = "http://<cache-host>/vuxml/vuln.xml.xz";' >> /usr/local/etc/pkg.conf

No nginx config is required; the appliance renders its managed config at startup from environment variables. Size the /cache volume to at least PKG_CACHE_SIZE (default 50G — a full set of packages for one FreeBSD release and arch is around 10G).

Stats

Open http://<cache-host>/ in a browser. The landing page shows the hit rate, bytes served from cache versus fetched upstream, cache disk usage, top clients and the most recent requests, refreshed every few seconds. Nothing to enable; the same numbers are at /stats.json.

Architectures: amd64, aarch64 User: bsd (UID/GID via PUID/PGID, defaults to 1000:1000) Base: FreeBSD 15.1


Need help? Join our Discord community.

About

Managed FreeBSD pkg caching appliance — proxies pkg.FreeBSD.org to speed up package fetches across image builds and insulate them from upstream rate limits/outages.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages