How can I debug a Typst compilation which does not finish? (Automatic downloading of Typst packages stopped working in Gitlab runner / Docker container)

I have been using a Gitlab runner in a Docker container to compile some Typst documents, without problems, until recently. If I now compile a document in the container which does not require new packages, it still works fine, but if I use a package that requires downloading, the process hangs until the Gitlab runner timeout is reached. A typical example output would be:


#16 [11/35] RUN echo hi > tmp.typ
#16 DONE 0.2s
#17 [12/35] RUN typst compile tmp.typ
#17 DONE 0.2s
#18 [13/35] RUN echo '#import "@preview/cetz-plot:0.1.3"' >> tmp.typ
#18 DONE 0.2s
#19 [14/35] RUN typst compile tmp.typ
#19 CANCELED
ERROR: failed to build: failed to solve: Canceled: context canceled
WARNING: step_script could not run to completion because the timeout was exceeded. For more control over job and script timeouts see: https://docs.gitlab.com/ci/runners/configure_runners/#set-script-and-after_script-timeouts
ERROR: Job failed: execution took longer than 1h0m0s seconds

So a file containing just hi compiles fine, but a file containing #import "@preview/cetz-plot:0.1.3" as well, will hang in the compilation process without output for an hour, until the timeout is reached. Also, if I use the same package that was downloaded to a Docker container before the issue appeared (somewhere between 3 months and a week ago), then I can still use that package without problem, so the issue seems to be in the downloading. I tried downloading a different package instead of cetz-plot, and that gave the same result.

I first noticed this problem when upgrading from Typst 0.14.2 to 0.15.0. The behaviour seems to be the same in both versions.

  • Is there a way to have Typst generate more output, so I can find out what the problem is?
  • Or can anyone maybe guess what the problem is so I can solve it?

My only clue is that earlier this/previous year downloading from https://upload.wikimedia.org/ using wget suddenly stopped working, and I had to add extra arguments --retry-on-http-error=429 --waitretry=10 --tries=5 to make it work again. Do the Typst package servers maybe require a similar specification to handle downloads from a Docker container or Gitlab runner? I am clueless since Typst does not show any output during a failed attempt to download a package.

The typst cli should have printed something like this:

downloading @preview/β—‹β—‹:β—‹β—‹
0 B / β—‹β—‹ KiB ( 0 %), β—‹β—‹ KiB/s, ETA: 0 s
β—‹β—‹ KiB / β—‹β—‹ KiB (β—‹β—‹ %), β—‹β—‹ KiB/s, ETA: β—‹β—‹ s

…or this:

error: failed to download package (https://packages.typst.org/preview/β—‹β—‹-β—‹β—‹.tar.gz: Dns Failed: resolve dns name β€˜packages.typst.org:443’: …

Is it possible that stdout/stderr is somehow blocked, making some logs hidden? If your GitLab instance is public, it would be helpful if you provide a link.

Perhaps you can try wget https://packages.typst.org/preview/cetz-plot-0.1.3.tar.gz before typst compile …?
(If you want to set up the files manually, refer to Packages - Typst Extra Docs)


By the way, the tmp trick can be simplified as echo … | typst compile - tmp.pdf.

Thanks! it seems to work now :slight_smile:
I reproduced the issue in a public repo, and as you can see here, the output you mention is not shown: manual_docker_build (#14361341051) Β· Jobs Β· novanext / TUDelft thesis Typst Β· GitLab

Checking with the simple wget call, the download failed, but adding the extra arguments it worked. What is more, after downloading cetz-plot-0.1.3.tar.gz with the additional arguments, the simple wget call worked as well, and also the downloading inside typst started working; see here: manual_docker_build (#15254587425) Β· Jobs Β· novanext / TUDelft thesis Typst Β· GitLab

Now the remaining question would be: is there a nicer way to tell the Typst (or the server?) that I would like to retry after an error 429? It feels a bit hacky to use an otherwise not needed wget download to give this information, instead of using Typst itself.

Thanks for the tip on passing a pipe as input to Typst, I wasn’t aware that is possible!

I now added this to my Dockerfile:

RUN cat <<EOF > ~/.wgetrc
  retry_on_http_error = 429
  waitretry = 10
  tries = 5
EOF

RUN typst compile -f=pdf <<EOF /dev/null
  #import "@preview/booktabs:0.0.4"
  #import "@preview/cetz:0.4.2"
  #import "@preview/cetz-plot:0.1.4"
  #import "@preview/ctz-euclide:0.1.5"
  #import "@preview/fletcher:0.5.8"
  #import "@preview/komet:0.2.0"
  #import "@preview/layout-ltd:0.1.0"
  #import "@preview/lilaq:0.5.0"
  #import "@preview/marge:0.1.0"
  #import "@preview/mitex:0.2.6"
  #import "@preview/polylux:0.4.0"
  #import "@preview/zero:0.6.0"
EOF

This seems to work, but even when I remove the first bit, it works. So the problem that made me start this topic is not completely reproducible, unfortunately…

1 Like