A daily mirror of CTAN/systems/texlive/tlnet on Cloudflare R2. This is the directory
tlmgr installs and updates from, and it is the only part of CTAN here, complete with every
platform, docs and sources. About 17,000 files and 6.8 GB.
TeX Live and TinyTeX both use tlmgr:
tlmgr option repository https://tlnet.ijosh.com/systems/texlive/tlnet/
tlmgr update --self --allFor a fresh install, give the installer the same URL:
install-tl -repository https://tlnet.ijosh.com/systems/texlive/tlnet/To go back to CTAN's mirror rotation: tlmgr option repository ctan.
The path mirrors CTAN's own layout, so the host works anywhere a CTAN mirror URL does. It tracks the current TeX Live release and moves to the next one when upstream does.
Once a day GitHub Actions runs the following pipeline inside the toolbox image. Every step
is a verb of the rsync engine in katoptra/lib, in the
order Taskfile.yml gives
them; the landing page is this mirror's own verb:
clockliststaterebuild— stamp the day, list the subtree on CTAN's master (dante), and fetch the listing the previous run left in the bucket, rebuilding it from the bucket if it went missing.diffsplit— take what upstream has and the state lacks, refuse a tree past R2's free 10 GB, and split the delta into batches.preparebatches— check the signedtexlive.tlpdb.sha512against the pinned TeX Live key, then per batch rsync the files, check every signed file and every package container against the tlpdb's checksums, upload, and write the new state. The tlpdb lands last, after every container it names.deletereconcile— drop the keys that left upstream, and once a day sweep the bucket against the state for anything neither owns.index— upload the landing page athttps://tlnet.ijosh.com/, dated.smokereportping— readtexlive.tlpdb.sha512and a sample of the run's keys back over the public domain, summarise what landed, and ping healthchecks.io. Silence is the alert.
Is it fresh?
Check last-modified on the index:
curl -sI https://tlnet.ijosh.com/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512tlmgr's default repository is CTAN's mirror rotation: every request lands on a different
volunteer mirror, and any one of them can be unreachable, on a slow connection, behind on
TLS, or a few days stale.
This setup ensures a consistent, reliable source for TeX Live updates built on Cloudflare's network.
- Fork this repo.
- Create an R2 bucket named
tlnet, an API token with Object Read & Write scoped to it, and a custom domain pointing at the bucket. SetHOSTto that domain inTaskfile.yml. For a landing page at/, add a Cloudflare Transform Rule rewriting the path/to/index.html, and put your own links and text insite/index.html. - Add the repository secrets below. They are the whole requirement.
- Actions -> sync -> Run workflow. The first run finds an empty bucket and fills it; every run after that pushes the daily delta.
- Start it every day. Nothing in this repository schedules a run: add a
schedule:trigger tosync.ymlwith a time of your own, or dispatch it from outside, as this mirror is.
| Secret | What it is |
|---|---|
R2_ACCOUNT_ID |
The Cloudflare account the bucket lives in |
R2_ACCESS_KEY_ID |
R2 API token with Object Read & Write on the bucket |
R2_SECRET_ACCESS_KEY |
That token's secret |
HEALTHCHECK_URL |
Optional: a healthchecks.io ping URL |
To test or run locally, with task and Docker (or Apple's container) installed:
task check # render every command of the pipeline inside the toolbox image; diff it against render.txt
task sync # one run, with the three R2_* variables and HEALTHCHECK_URL exportedThe image, the engine's verbs and the two workflows this repository calls are
katoptra/lib's: the include and the image at v1, the
workflows at a release commit.
Pull requests are welcome.
MIT licensed. Built by Josh Vaughen.