Skip to content

FreeBSD pkg cache FreeBSD pkg cache

Description / nameInput element
Container Registry
Container Configuration Root Path
Timezone
FreeBSD pkg cache Host Port
FreeBSD pkg cache /config Path
FreeBSD pkg cache /cache Path

Build Status Last Commit

nginx caching proxy for pkg.FreeBSD.org — speeds up FreeBSD package fetches across image builds and insulates them from upstream rate limits/outages.

Port 80
Registry ghcr.io/daemonless/pkg-cache
Daemonless daemonless/pkg-cache
Source daemonless/pkg-cache
Website daemonless.io/guides/freebsd-pkg-cache

Version Tags

Tag Description Best For
latest Upstream Binary. Built from official release. Most users. Matches Linux Docker behavior.

Root Privileges Required

Podman on FreeBSD currently requires root. All commands must be run as root (or via doas/sudo).

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

Deployment

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=10g  # Max on-disk cache size (nginx max_size), e.g. 50g, 100g, 500g. Keep the /cache volume at least this big.
      - ENABLE_STATS=false  # Set to true to enable the GoAccess real-time stats dashboard on port 7890.
    volumes:
      - "/path/to/containers/pkg-cache:/config"
      - "/path/to/containers/pkg-cache/cache:/cache"
      - "/etc/resolv.conf:/etc/resolv.conf"
    ports:
      - "80:80"
      - "7890:7890"
    restart: unless-stopped
1
2
3
4
5
6
7
# .env

DIRECTOR_PROJECT=pkg-cache
TZ=UTC
PKG_UPSTREAM=pkg.FreeBSD.org
PKG_CACHE_SIZE=10g
ENABLE_STATS=false
# appjail-director.yml

options:
  - virtualnet: ':<random> default'
  - nat:
services:
  pkg-cache:
    name: pkg_cache
    options:
      - container: 'boot args:--pull'
      - expose: '80:80 proto:tcp' \
      - expose: '7890:7890 proto:tcp' \
    oci:
      user: root
      environment:
        - TZ: !ENV '${TZ}'
        - PKG_UPSTREAM: !ENV '${PKG_UPSTREAM}'
        - PKG_CACHE_SIZE: !ENV '${PKG_CACHE_SIZE}'
        - ENABLE_STATS: !ENV '${ENABLE_STATS}'
    volumes:
      - PKG_CACHE_CONFIG_PATH: /config
      - PKG_CACHE_CACHE_PATH: /cache
      - /etc/resolv.conf: /etc/resolv.conf
volumes:
  PKG_CACHE_CONFIG_PATH:
    device: '/path/to/containers/pkg-cache'
  PKG_CACHE_CACHE_PATH:
    device: '/path/to/containers/pkg-cache/cache'
  /etc/resolv.conf:
    device: '/etc/resolv.conf'
1
2
3
4
5
6
# Makejail

ARG tag=latest

OPTION overwrite=force
OPTION from=ghcr.io/daemonless/pkg-cache:${tag}
podman run -d --name pkg-cache \
  -p 80:80 \
  -p 7890:7890 \
  -e TZ=UTC \
  -e PKG_UPSTREAM=pkg.FreeBSD.org \
  -e PKG_CACHE_SIZE=10g \
  -e ENABLE_STATS=false \
  -v /path/to/containers/pkg-cache:/config \
  -v /path/to/containers/pkg-cache/cache:/cache \
  -v /etc/resolv.conf:/etc/resolv.conf \
  ghcr.io/daemonless/pkg-cache:latest
appjail oci run -Pd \
  -o overwrite=force \
  -o container="args:--pull" \
  -o virtualnet=":<random> default" \
  -o nat \
  -o expose="80:80 proto:tcp" \
  -o expose="7890:7890 proto:tcp" \
  -e TZ=UTC \
  -e PKG_UPSTREAM=pkg.FreeBSD.org \
  -e PKG_CACHE_SIZE=10g \
  -e ENABLE_STATS=false \
  -o fstab="/path/to/containers/pkg-cache /config <pseudofs>" \
  -o fstab="/path/to/containers/pkg-cache/cache /cache <pseudofs>" \
  -o fstab="/etc/resolv.conf /etc/resolv.conf <pseudofs>" \
  ghcr.io/daemonless/pkg-cache:latest pkg-cache
- name: Deploy pkg-cache
  containers.podman.podman_container:
    name: pkg-cache
    image: "ghcr.io/daemonless/pkg-cache:latest"
    state: started
    restart_policy: always
    env:
      TZ: "UTC"
      PKG_UPSTREAM: "pkg.FreeBSD.org"
      PKG_CACHE_SIZE: "10g"
      ENABLE_STATS: "false"
    ports:
      - "80:80"
      - "7890:7890"
    volumes:
      - "/path/to/containers/pkg-cache:/config"
      - "/path/to/containers/pkg-cache/cache:/cache"
      - "/etc/resolv.conf:/etc/resolv.conf"

Access at: http://localhost:80

Interactive Configuration

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 10g Max on-disk cache size (nginx max_size), e.g. 50g, 100g, 500g. Keep the /cache volume at least this big.
ENABLE_STATS false Set to true to enable the GoAccess real-time stats dashboard on port 7890.

Volumes

Path Description
/config Config and logs storage (nginx.conf, log/, stats/).
/cache Package cache storage (proxy_cache). Size to match max_size in nginx.conf (default 10G).
/etc/resolv.conf

Ports

Port Protocol Description
80 TCP HTTP — pkg clients point their FreeBSD.conf url here
7890 TCP GoAccess stats dashboard (HTML) — enabled via ENABLE_STATS=true

Pointing clients at the cache

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

1
2
3
4
5
6
7
FreeBSD: {
  url: "pkg+http://<cache-host>/${ABI}/quarterly",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

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. Size the /cache volume to at least PKG_CACHE_SIZE (default 10G).

Implementation Details

  • Architectures: amd64
  • User: bsd (UID/GID set via PUID/PGID). Defaults to 1000:1000.
  • Base: Built on ghcr.io/daemonless/base (FreeBSD 15.1).

Need help? Join our Discord community.