Since June 2024 I’ve been operating a mirror for Zig releases at http://mirrors.nektro.net/zig/.

https://github.com/mlugg/setup-zig was testflighting what would eventually become the https://ziglang.org/download/community-mirrors/ system and I wanted a browsable directory of all past versions. At time of writing it has 0.11, 0.12, 0.13, all of 0.14-dev, 0.14, 0.14.1, all of 0.15-dev so far.

This isn’t a tutorial per se since this setup isn’t actually eligible for the Community Mirrors listing (as it queries for new versions on a cron job instead of on request), but it works for me and sharing is caring so here it is in the hopes it may be helpful to someone else or any potential future version of myself.

An example of using this mirror with setup-zig can be seen here: https://github.com/nektro/zigmod/blob/master/.github/workflows/push.yml#L19.

The first bit is an nginx rewrite rule that allows flat namespace requests that setup-zig makes to be compatible with the versioned folders that actually exist on disk. So a request for say http://mirrors.nektro.net/s3cgi/zig-aarch64-linux-0.15.0-dev.769+4d7980645.tar.xz is actually gonna reroute to http://mirrors.nektro.net/zig/0.15.0-dev.769+4d7980645/zig-aarch64-linux-0.15.0-dev.769+4d7980645.tar.xz. I’ll have to update this soon since ZSF updated the pattern for tarballs starting with >=0.15.0-dev.631+9a3540d61 for master builds and >= 0.14.1 for tagged releases to be zig-arch-os-version.ext.

[pontus ~] cat .nginx/conf.d/000-default-server.conf
    location ~ /s3cgi {
        rewrite ^\/s3cgi\/zig\-(windows|macos|linux|freebsd|netbsd)\-(x86_64|aarch64|riscv64)-(\d\.\d+\.\d(?:\-dev\.\d+\+[0-9a-f]+)?)(\.tar\.xz|\.zip)((?:\.minisig)?)$ /zig/$3/zig-$1-$2-$3$4$5 last;
    }

Below are the scripts I run on the aforementioned cron job to query index.json and download the latest tarballs and minisign files.

[pontus ~] cat download_zig_release.sh
#!/bin/bash

has_exec() {
  which "$1" >/dev/null 2>&1 || return 1
}
fail() {
  has_failure=1
  printf "${C_RED}setup error${C_RESET}: %s\n" "$@"
}
test_exec() {
  has_exec "$1" || fail "'$1' is missing"
}
parallelwget() {
  printf '%s\n' $@ | xargs -L1 wget -q --show-progress --no-clobber
}

test_exec 'curl'
test_exec 'xargs'
test_exec 'wget'

if [ -n "$has_failure" ]; then
  exit 1
fi

echo 'have all prorams. good.'

original_dir=$PWD
self_file=$0
self_dir=$(dirname $self_file)

cd $self_dir
jq=$(realpath ./jq-linux-amd64)
cd www/mirrors.nektro.net/public_html/zig

zig_version=$(curl -s https://ziglang.org/download/index.json | $jq -r '.master.version')
zig_version=${1:-$zig_version}
echo "saving Zig version: ${zig_version}"

mkdir -p $zig_version
cd $zig_version

parallelwget https://ziglang.org/download/${zig_version}/zig-{x86_64,aarch64}-windows-${zig_version}.zip{,.minisig}
parallelwget https://ziglang.org/download/${zig_version}/zig-{x86_64,aarch64}-macos-${zig_version}.tar.xz{,.minisig}
parallelwget https://ziglang.org/download/${zig_version}/zig-{x86_64,aarch64,riscv64}-linux-${zig_version}.tar.xz{,.minisig}
parallelwget https://ziglang.org/download/${zig_version}/zig-{x86_64,aarch64,riscv64}-freebsd-${zig_version}.tar.xz{,.minisig}
parallelwget https://ziglang.org/download/${zig_version}/zig-{x86_64,aarch64}-netbsd-${zig_version}.tar.xz{,.minisig}
[pontus ~] cat download_zig_master.sh
#!/bin/bash

has_exec() {
  which "$1" >/dev/null 2>&1 || return 1
}
fail() {
  has_failure=1
  printf "${C_RED}setup error${C_RESET}: %s\n" "$@"
}
test_exec() {
  has_exec "$1" || fail "'$1' is missing"
}
parallelwget() {
  printf '%s\n' $@ | xargs -L1 wget -q --show-progress --no-clobber
}

test_exec 'curl'
test_exec 'xargs'
test_exec 'wget'

if [ -n "$has_failure" ]; then
  exit 1
fi

echo 'have all prorams. good.'

original_dir=$PWD
self_file=$0
self_dir=$(dirname $self_file)

cd $self_dir
jq=$(realpath ./jq-linux-amd64)
cd www/mirrors.nektro.net/public_html/zig

zig_version=$(curl -s https://ziglang.org/download/index.json | $jq -r '.master.version')
zig_version=${1:-$zig_version}
echo "saving Zig version: ${zig_version}"

mkdir -p $zig_version
cd $zig_version

parallelwget https://ziglang.org/builds/zig-{x86_64,aarch64}-windows-${zig_version}.zip{,.minisig}
parallelwget https://ziglang.org/builds/zig-{x86_64,aarch64}-macos-${zig_version}.tar.xz{,.minisig}
parallelwget https://ziglang.org/builds/zig-{x86_64,aarch64,riscv64}-linux-${zig_version}.tar.xz{,.minisig}
parallelwget https://ziglang.org/builds/zig-{x86_64,aarch64,riscv64}-freebsd-${zig_version}.tar.xz{,.minisig}
parallelwget https://ziglang.org/builds/zig-{x86_64,aarch64}-netbsd-${zig_version}.tar.xz{,.minisig}

As for why I haven’t setup HTTPS yet, it is because the hosting provider I use for this particular box doesn’t make it super simple to setup on custom domains and verifying the minisign signatures when I download provides the same security guarantees that HTTPS would.

At time of writing the disk usage is 232 / 1000 GB (last calculated 2025-07-28 07:06 UTC).