{"id":50529101,"url":"https://github.com/bcrist/zigmirror","last_synced_at":"2026-06-03T11:01:45.198Z","repository":{"id":351922953,"uuid":"1213073436","full_name":"bcrist/zigmirror","owner":"bcrist","description":"mirror of codeberg.org/bcrist/zigmirror","archived":false,"fork":false,"pushed_at":"2026-05-06T03:51:37.000Z","size":78,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T05:32:26.942Z","etag":null,"topics":["zig","zig-program","ziglang"],"latest_commit_sha":null,"homepage":"https://codeberg.org/bcrist/zigmirror","language":"Zig","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bcrist.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-17T02:40:38.000Z","updated_at":"2026-05-02T13:29:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bcrist/zigmirror","commit_stats":null,"previous_names":["bcrist/zigmirror"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bcrist/zigmirror","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrist%2Fzigmirror","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrist%2Fzigmirror/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrist%2Fzigmirror/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrist%2Fzigmirror/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bcrist","download_url":"https://codeload.github.com/bcrist/zigmirror/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrist%2Fzigmirror/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33860971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["zig","zig-program","ziglang"],"created_at":"2026-06-03T11:01:44.234Z","updated_at":"2026-06-03T11:01:45.192Z","avatar_url":"https://github.com/bcrist.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zig Community Mirror Server\n\n`zigmirror` is a simple [Zig Community Mirror](https://codeberg.org/ziglang/www.ziglang.org/src/branch/main/MIRRORS.md) cache server.  It utilizes two caches:\n* A small memory cache for \"strange\" requests\n* A larger filesystem cache for \"typical\" requests\n\nBoth caches are configured to hold a maximum number of files and maximum total memory/disk usage.\nThis makes it a good option to run on systems with constrained memory or disk space, while also allowing it to be scaled up on beefy machines.\n\n## Usage\n`zigmirror` expects a single command line argument: the path to the `zigmirror.sx` configuration file.  If not specified as an absolute path, it will recursively search for the file, starting in the executable directory and moving through the parent chain until it is found, or the root directory is reached.  Running without any arguments (i.e. just `zigmirror`) behaves the same as running `zigmirror etc/zigmirror.sx`, invoking the recursive parent directory search.\n\n`zig build` will output a default configuration file to `zig-out/etc/default.zigmirror.sx`.  Delete the `default.` prefix and modify it as necessary.\n\nAn HTML `/stats` endpoint is served which provides information about what is currently available in the cache, how frequently it is accessed, etc.\n\nIn addition to the zig compiler source, zig-bootstrap, and build artifacts that all community servers are required to cache, the zig compiler devkits found at `https://ziglang.org/download/deps/zig+llvm+lld+clang-\u003ctarget\u003e-\u003cversion\u003e.\u003cext\u003e` are also allowed to be cached, but support for this can be disabled in the configuration file.  These are the build tools used by the zig compiler CI runners, and can be useful for building an LLVM-enabled zig compiler locally, especially on Windows.\n\n## HTTPS Termination\nZig community mirrors are expected to serve over HTTPS, but good TLS support complicates server projects significantly, and often it's better/easier to just handle HTTPS termination through a load balancer or reverse proxy.  Therefore this project assumes that you'll use an external solution such as [TLSproxy](https://github.com/c2FmZQ/tlsproxy).\n\n## Request Rate Limiting\nBasic IP-based request rate limiting is included.  When used, the HTTPS terminating proxy must set/update the `X-Forwarded-For` HTTP header.  Limiting will be applied to all IPs listed in the header, but once a request has been blocked, any remaining IPs in the list will not take a hit for that request.  Rate limiting can be disabled entirely by removing the `(request_rate_limit ...)` expression from the config file.\n\n## Memory/Disk Usage Tuning\nThe `(cache (mem))` and `(cache (fs))` expressions in the config file include two inline parameters:\n* `max_entries`, the maximum number of artifacts that can exist in the cache at any particular time\n* `max_bytes`, the maximum total memory/disk that can be consumed by the cache at any particular time\n\nAverage artifact size is somewhere around 25MB (most build artifacts are around 50MB and `.minisig` artifacts are tiny), so it's best to set `max_entries` to at least `max_bytes / (25 * 1024 * 1024)`.\n\nWhen an artifact is evicted from the memory cache, it is moved to the filesystem cache, unless the filesystem cache is full and everything it contains is more important than the item from the memory cache.\nAdditionally, popular artifacts may be moved from the memory cache to the FS cache before the memory cache is full.  The conditions for this are controlled with the `(cache ... (mem ... (periodic_eviction ...)))` config expression.\nOptionally, moving to the filesystem cache can be skipped if the artifact wasn't referenced enough while in memory, using the `(cache ... (fs ... (min_requests n)))` expression in the config file.  If you set this higher than 1, you may want to set the memory cache size a little higher (I'd recommend at least 2GB / 100 entries).\n\nWhen serving artifacts from the filesystem, `sendfile` is utilized, so the OS's internal filesystem cache is leveraged as much as possible.  Therefore, you shouldn't allocate a majority of your system memory towards the memory cache.  I recommend at least 1 GB, but not more than 25% of your physical memory.\n\n`(upstream (max_connections n))` controls how many threads may try to download new artifacts from `ziglang.org` at the same time.  Each thread doing this temporarily stores the full artifact in memory before adding it to the memory cache, so setting this to a large number will increase process memory usage.  Note: If a client requests an artifact that's already being downloaded for another client, the subsequent client(s) will be blocked until the original download completes and the artifact enters the cache.\n\n## Typical Installation\n```sh\n# Build zigmirror:\ncd ~\ngit clone https://codeberg.org/bcrist/zigmirror\ncd zigmirror\nzig build -Doptimize=ReleaseSafe\n\n# Install zigmirror:\nsudo useradd --system --shell /usr/sbin/nologin zigmirror\n\nsudo install -m 0750 -o zigmirror -g zigmirror -D zig-out/bin/zigmirror /usr/local/bin/zigmirror\nsudo install -m 0644 -o zigmirror -g zigmirror -D zig-out/etc/default.zigmirror.sx /usr/local/etc/zigmirror.sx\nsudo vi /usr/local/etc/zigmirror.sx # modify as desired\n\nsudo install -m 0644 src/zigmirror.service /etc/systemd/system/zigmirror.service\nsudo vi /etc/systemd/system/zigmirror.service # modify as desired\nsudo systemctl daemon-reload\nsudo systemctl enable zigmirror\nsudo systemctl start zigmirror\n\n# Build TLSproxy:\ncd ~\ngit clone https://github.com/c2FmZQ/tlsproxy\ncd tlsproxy\ngo generate ./...\ngo build -o tlsproxy\n\n# Install TLSproxy:\nsudo useradd --system --shell /usr/sbin/nologin tlsproxy\n\nsudo install -m 0750 -o tlsproxy -g tlsproxy -D tlsproxy /usr/local/bin/tlsproxy\nsudo install -m 0644 -o tlsproxy -g tlsproxy -D ../zigmirror/tlsproxy/config.yaml /usr/local/etc/tlsproxy/config.yaml\nsudo vi /usr/local/etc/tlsproxy/config.yaml # modify as desired\n\nsudo mkdir -p /usr/local/var/cache/tlsproxy\n\nsudo install -m 0644 ../zigmirror/tlsproxy/tlsproxy.service /etc/systemd/system/tlsproxy.service\nsudo vi /etc/systemd/system/tlsproxy.service # modify as desired\nsudo systemctl daemon-reload\nsudo systemctl enable tlsproxy\nsudo systemctl start tlsproxy\n```\n\nUpdating after initial installation:\n```sh\ncd ~/zigmirror\ngit pull\nsudo zig build upgrade -Doptimize=ReleaseSafe -Dupgrade-bin-user=zigmirror\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcrist%2Fzigmirror","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbcrist%2Fzigmirror","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcrist%2Fzigmirror/lists"}