A self-hostable solution written in Go for creating a community mirror for the Zig programming language. This application is designed for communities, companies, or individuals looking to provide faster local access to Zig toolchains, reducing latency and bandwidth usage on the official servers.
It is lightweight and distributed as a single binary.
- Efficient caching: Downloads files from an upstream server once and serves them from a local cache for all subsequent requests.
- Automatic TLS: Full support for ACME (Let's Encrypt) to automatically obtain and renew TLS certificates.
- Secure by default: Supports HTTPS and automatic redirection from HTTP to HTTPS.
- Standalone binary: Compiles to a single, dependency-free binary for easy deployment.
- Configurable: All settings are manageable via command-line flags, including ports, cache directories, and upstream URL.
- Path correctness: Caches files using the official Zig directory layout (
/download/<version>/and/builds/).
This is the recommended method for most users.
- Navigate to the latest release page.
- Download the archive for your operating system and architecture (e.g.,
go-mirror-zig-v1.0.0-linux-amd64.tar.gz). - Extract the archive.
tar -xvzf go-mirror-zig-v1.0.0-linux-amd64.tar.gz
- Run the application. You can verify it's working by checking the version or help output.
./go-mirror-zig --version
Ensure you have a recent version of Go installed.
- Clone the repository:
git clone https://github.com/savalione/go-mirror-zig.git
- Navigate to the project directory:
cd go-mirror-zig - Build the project:
go build -o go-mirror-zig ./cmd/main.go
For example, you have the following setup:
- A headless (CLI access only) Ubuntu server.
- Nginx as a caching (and ACME challenge) proxy.
In this setup the ports 80 (HTTP) and 443 (HTTPS) are already occupied by the caching proxy.
First, you need to decide where the cache will be stored.
For this example, we'll assume you want to store it in the /zig-mirror directory, which you have already created.
You can run the application with the following flags:
go-mirror-zig -http-port 8080 -cache-dir="/zig-mirror"Then you need to create a Nginx configuration for your mirror:
# zig.example.com
server {
listen 80;
server_name zig.example.com;
location ~/.well-known {
allow all;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
}
}
In the end you may issue a TLS certificate using certbot or manually set up certificates.
For example you have a server without caching proxy. In that case you can set up the caching mirror with automatic ACME support.
First of all you need to open ports 80 (HTTP) and 443 (HTTPS).
After that you need to decide:
- Where to store mirror cache (for example:
/zig-mirror) - The location for storing the obtained TLS certificates, which must be a secure directory (e.g.,
/secure-location).
Then you can run the application with the following flags:
go-mirror-zig -acme -acme-accept-tos -acme-cache /secure-location -acme-email [email protected] -acme-host example.com -cache-dir /zig-mirror -redirect-to-httpsThe application is configured using command-line flags.
Run ./go-mirror-zig -help to see all available options.
| Flag | Description | Default value |
|---|---|---|
-acme |
Obtain TLS certificates using the ACME challenge. | |
-acme-accept-tos |
Accept the ACME provider's Terms of Service. | |
-acme-cache string |
Directory for storing obtained certificates. | |
-acme-directory string |
ACME directory URL. | https://acme-v02.api.letsencrypt.org/directory |
-acme-email string |
Email address for ACME registration and recovery notices. | |
-acme-host string |
The hostname (domain name) for which to obtain the ACME certificate. | |
-cache-dir string |
Path to the directory where downloaded content will be cached. | ./ |
-enable-tls |
Enable the TLS (HTTPS) server. Requires -tls-cert-file and -tls-key-file. |
|
-http-port int |
The port for the plain HTTP listener. | 80 |
-listen-address string |
The IP address to listen on. If empty, listens on all available interfaces. | |
-redirect-to-https |
Enable automatic redirection of HTTP requests to HTTPS. Requires -enable-tls or -acme. |
|
-tls-cert-file string |
Path to the TLS certificate file. | |
-tls-key-file string |
Path to the TLS private key file. | |
-tls-port int |
The port for the secure TLS (HTTPS) listener. | 443 |
-upstream-url string |
The URL of the upstream server to mirror/proxy. | https://ziglang.org |
-version |
Print version information and exit. |
Here is an example service file for running the application with systemd.
- Create the service file:
sudo nano /etc/systemd/system/go-mirror-zig.service
- Add the following configuration, adjusting paths and flags as needed:
[Unit] Description=Go Mirror Zig Service After=network.target [Service] User=zig-mirror Group=zig-mirror Type=simple WorkingDirectory=/opt/zig-mirror ExecStart=/go-mirror-zig -cache-dir=/zig-mirror -acme -acme-accept-tos -acme-host=zig.example.com -acme-email[email protected] -acme-cache=/var/lib/zig-mirror/acme -redirect-to-https Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target
- Reload, enable, and start the service:
sudo systemctl daemon-reload sudo systemctl enable go-mirror-zig.service sudo systemctl start go-mirror-zig.service
Contributions are welcome! We value a healthy and collaborative community.
Please read our Contributing Guidelines to get started. All participants are expected to follow our Code of Conduct.
This project is licensed under The GNU General Public License v3.0. See the LICENSE file for the full license text.
Copyright (C) 2025 Savelii Pototskii (savalione.com)
This project incorporates code from several third-party libraries and assets. We are grateful to their developers and maintainers.
- new.css - MIT License
- Official Zig Project Logo - CC BY-SA 4.0
- The Inter font family - OFL-1.1 License