{"id":16022790,"url":"https://github.com/alexpovel/latex-extras-docker","last_synced_at":"2025-09-13T15:50:08.603Z","repository":{"id":109322546,"uuid":"177413963","full_name":"alexpovel/latex-extras-docker","owner":"alexpovel","description":"Moved, see website link","archived":false,"fork":false,"pushed_at":"2021-08-20T15:45:26.000Z","size":261,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T22:03:45.629Z","etag":null,"topics":["debian","docker","glossaries","glossaries-extra","gnuplot","image","java","latex","lualatex","pandoc","tex","texlive","texlive-distribution","texlive-full"],"latest_commit_sha":null,"homepage":"https://github.com/alexpovel/latex-cookbook/tree/master/.devcontainer/image","language":"Shell","has_issues":true,"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/alexpovel.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}},"created_at":"2019-03-24T12:48:47.000Z","updated_at":"2025-02-17T01:44:44.000Z","dependencies_parsed_at":"2023-05-09T21:18:15.971Z","dependency_job_id":null,"html_url":"https://github.com/alexpovel/latex-extras-docker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexpovel%2Flatex-extras-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexpovel%2Flatex-extras-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexpovel%2Flatex-extras-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexpovel%2Flatex-extras-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexpovel","download_url":"https://codeload.github.com/alexpovel/latex-extras-docker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248153554,"owners_count":21056457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["debian","docker","glossaries","glossaries-extra","gnuplot","image","java","latex","lualatex","pandoc","tex","texlive","texlive-distribution","texlive-full"],"created_at":"2024-10-08T18:41:52.052Z","updated_at":"2025-04-10T03:36:39.704Z","avatar_url":"https://github.com/alexpovel.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docker image with custom, almost-full TeXLive distribution \u0026 various tools\n\n[![Docker Pulls](https://img.shields.io/docker/pulls/alexpovel/latex)](https://hub.docker.com/r/alexpovel/latex)\n\nServes a lot of needs surrounding LaTeX file generation and handling.\nFor the rationale behind the installed Debian packages, see [below](#custom-tools).\nTo see how to build the image, also see [below](#building).\n\n## Quick Intro\n\nTo use the image, you can use the [example](tests/minimal.tex) provided in this repository:\n\n- Bash:\n\n  ```bash\n  docker run \\\n    --rm \\\n    --volume $(pwd)/tests:/tex \\\n    alexpovel/latex\n  ```\n\n- PowerShell:\n\n  ```powershell\n  docker run `\n    --rm `\n    --volume ${PWD}/tests:/tex `\n    alexpovel/latex\n  ```\n\nThe parts making up the command are:\n\n- The last line is the location on [DockerHub](https://hub.docker.com/repository/docker/alexpovel/latex).\n  Without specifying a [*tag*](https://hub.docker.com/repository/docker/alexpovel/latex/tags?page=1),\n  the default `latest` is implied.\n  See [below](#historic-builds) for more options.\n- The `--rm` option removes the container after a successful run.\n  This is generally desired since containers are not supposed to be stateful:\n  once their process terminates, the container terminates, and it can be considered junk.\n- Providing a `--volume`, in this case [`tests/`](./tests/) in the current working directory,\n  is required for the container to find files to work on.\n  It has to be *mounted* to a location *inside* the container.\n  This has to be whatever the last `WORKDIR` instruction in the [Dockerfile](Dockerfile) is,\n  e.g. `/tex`.\n\n  Otherwise, you can always override the `WORKDIR` using the `--workdir` option.\n  This is the directory in which the Docker container's process works in and expects to\n  find files.\n- Note that there is no command given, e.g. there is nothing *after* `alexpovel/latex`.\n  In this form, the container runs as an executable (just as if you ran `lualatex` or\n  similar commands), where the program to be executed is determined by the `ENTRYPOINT`\n  instruction in the [Dockerfile](Dockerfile).\n\n  For example, if the `ENTRYPOINT` is set to `latexmk`, running the above command will\n  execute `latexmk` in the container's context, without you having to specify it.\n\n  (`latexmk` is a recipe-like tool that automates LaTeX document compilation by running\n  `lualatex`, `biber` and whatever else required for compilation as many times as\n  needed for proper PDF output (so references like `??` in the PDF are resolved).\n  It does this by detecting that auxiliary files no longer change (steady-state).\n  The tool is best configured using its config file, `.latexmkrc`.)\n\n  Any options to the `ENTRYPOINT` executable are given at the end of the command, e.g.:\n\n  ```bash\n  docker run \\\n    --rm \\\n    --volume $(pwd)/tests:/tex \\\n    alexpovel/latex \\\n    -c\n  ```\n\n  to run, if `latexmk` is the `ENTRYPOINT`, the equivalent of `latexmk -c`\n  ([cleaning auxiliary files](https://mg.readthedocs.io/latexmk.html#cleaning-up)).\n\n  To **overwrite** the `ENTRYPOINT`, e.g. because you want to run only `lualatex`,\n  use the `--entrypoint` option, e.g. `--entrypoint=\"lualatex\"`.\n  Similarly, you can work inside of the container directly, e.g. for debugging, using\n  `--entrypoint=\"bash\"`.\n\n## Approach\n\nThis Dockerfile is based on a custom TeXLive installer using their\n[`install-tl` tool](https://www.tug.org/texlive/doc/install-tl.html),\ninstead of\n[Debian's `texlive-full`](https://packages.debian.org/search?searchon=names\u0026keywords=texlive-full).\nOther, smaller `texlive-` collections would be\n[available](https://packages.debian.org/search?suite=default\u0026section=all\u0026arch=any\u0026searchon=names\u0026keywords=texlive),\nbut TeXLive cannot install missing packages on-the-fly,\n[unlike MiKTeX](https://miktex.org/howto/miktex-console/).\nTherefore, images should come with all desirable packages in place; installing them after\nthe fact in running containers using [`tlmgr`](https://www.tug.org/texlive/tlmgr.html)\nis the wrong approach (containers are only meant to be run; if they are incomplete,\nmodify the *image*, ordinarily by modifying the `Dockerfile`).\n\nThis approach has the following advantages:\n\n- Using [\"vanilla\" TeXLive](https://www.tug.org/texlive/debian.html)\n  affords us the latest packages directly from the source, while the official\n  Debian package might lag behind a bit.\n  This is often not relevant, but has bitten me several times while working with the\n  latest packages.\n- The installation can be adjusted better.\n  For example, *multiple GBs* of storage/image size are saved by omitting unneeded PDF\n  documentation files.\n- We can install arbitrary TeXLive versions, as long as they are the\n  [current](https://tug.org/texlive/acquire-netinstall.html)\n  or an\n  archived (\u003cftp://tug.org/historic/systems/texlive/\u003e)\n  version.\n  Otherwise, to obtain [older or even obsolete TeXLive installations](#historic-builds),\n  one would have to also obtain a corresponding Debian version.\n  This way, we can choose a somewhat recent Debian version and simply install an old\n  TeXLive into it.\n\n  Eligible archive versions are those year directories (`2019`, `2020`, ...) present\n  at the above FTP link that have a `tlnet-final` subdirectory.\n  This is (speculating here) a frozen, aka final, version, put online the day the *next*\n  major release goes live.\n  For example, version `2021` released on 2021-04-01 and `2020` received its `tlnet-final`\n  subdirectory that same day.\n\nThe `install-tl` tool is configured via a [*Profile* file](config/texlive.profile), see also\nthe [documentation](https://www.tug.org/texlive/doc/install-tl.html#PROFILES).\nThis enables unattended, pre-configured installs, as required for a Docker installation.\n\n---\n\nThe (official?) [`texlive/texlive` image](https://hub.docker.com/r/texlive/texlive) follows\n[the same approach](https://hub.docker.com/layers/texlive/texlive/latest/images/sha256-70fdbc1d9596c8eeb4a80c71a8eb3a5aeb63bed784112cbdb87f740e28de7a80?context=explore).\nHowever, there are a bunch of things this Dockerfile does differently that warrant not\nbuilding `FROM` that image:\n\n- a user-editable, thus more easily configurable [profile](config/texlive.profile).\n  This is mainly concerning the picked package *collections*. Unchecking (putting a `0`)\n  unused ones saves around 500MB at the time of writing.\n- more elaborate support for [historic versions](#historic-builds)\n- an installation procedure incorporating a proper `USER`\n\nThings they do that do not happen here:\n\n- verify download integrity using `gpg`\n\n### Historic Builds\n\nLaTeX is a slow world, and many documents/templates in circulation still rely on\noutdated practices or packages.\nThis can be a huge hassle.\nMaintaining an old LaTeX distribution next to a current one on the same host is\nnot fun.\nThis is complicated by the fact that (La)TeX seems to do things differently than pretty much\neverything else.\nFor this, Docker is the perfect tool.\n\nThis image can be built (`docker build`) with different build `ARG`s, and the build\nprocess will figure out the proper way to handle installation.\nThere is a [script](texlive.sh) to handle getting and installing TeXLive from the\nproper location ([current](https://www.tug.org/texlive/acquire-netinstall.html) or\n[archive](ftp://tug.org/historic/systems/texlive/)).\nRefer to the [Dockerfile](Dockerfile) for the available `ARG`s (all `ARG` have a default).\nThese are handed to the build process via the\n[`--build-arg` option](https://docs.docker.com/engine/reference/commandline/build/#options).\n\nNote that for a *specific* TeXLive version to be picked, it needs to be present in their\n[archives](ftp://tug.org/historic/systems/texlive/).\nThe *current* TeXLive is not present there (it's not historic), but is available under\nthe `latest` Docker tag.\nAs such, if for example `2020` is the *current* TeXLive, and the image is to be based on\nDebian 10, there is *no* `debian-10-texlive-2020` tag.\nYou would obtain this using the `latest` tag.\nAs soon as TeXLive 2020 is superseded and consequently moved to the archives,\nthe former tag can become available.\n\nTo build an array of different versions automatically, DockerHub provides\n[advanced options](https://docs.docker.com/docker-hub/builds/advanced/) in the form of\nhooks, e.g. a [build hook](hooks/build).\nThese are bash scripts that override the default DockerHub build process.\nAt build time, DockerHub provides\n[environment variables](https://docs.docker.com/docker-hub/builds/advanced/#environment-variables-for-building-and-testing)\nwhich can be used in the build hook to forward these into the Dockerfile build process.\nAs such, by just specifying the image *tags* on DockerHub, we can build corresponding\nimages automatically (see also\n[here](https://web.archive.org/web/20201005132636/https://dev.to/samuelea/automate-your-builds-on-docker-hub-by-writing-a-build-hook-script-13fp)).\nFor more info on this, see [below](#on-dockerhub).\n\nThe approximate [matching of Debian to TeXLive versions](https://www.tug.org/texlive/debian.html)\nis (see also [here](https://www.debian.org/releases/) and [here](https://www.debian.org/distrib/archive).):\n\n| Debian Codename | Debian Version | TeXLive Version |\n| --------------- | :------------: | :-------------: |\n| bullseye        |       11       |      2020       |\n| buster          |       10       |      2018       |\n| stretch         |       9        |      2016       |\n| jessie          |       8        |      2014       |\n| wheezy          |       7        |      2012       |\n| squeeze         |      6.0       |      2009       |\n| lenny           |      5.0       |     unknown     |\n| etch            |      4.0       |     unknown     |\n| sarge           |      3.1       |     unknown     |\n| woody           |      3.0       |     unknown     |\n| potato          |      2.2       |     unknown     |\n| slink           |      2.1       |     unknown     |\n| hamm            |      2.0       |     unknown     |\n\nThis is only how the official Debian package is shipped.\nThese versions can be, to a narrow extend, freely mixed.\nUsing `install-tl`, older versions of TeXLive can be installed on modern Debian versions.\n\n#### Issues\n\nUsing [*obsolete* Debian releases](https://www.debian.org/releases/) comes with a long\nlist of headaches.\nAs such, Debian versions do not reach too far back.\nIt does not seem worth the effort.\nInstead, it seems much easier to install older TeXLive versions onto reasonably recent\nDebians.\n\nIssues I ran into are:\n\n- `apt-get update` will fail if the original Debian repository is dead (Debian 6/TeXLive 2014):\n\n  ```plaintext\n  W: Failed to fetch http://httpredir.debian.org/debian/dists/squeeze/main/binary-amd64/Packages.gz  404  Not Found\n  W: Failed to fetch http://httpredir.debian.org/debian/dists/squeeze-updates/main/binary-amd64/Packages.gz  404  Not Found\n  W: Failed to fetch http://httpredir.debian.org/debian/dists/squeeze-lts/main/binary-amd64/Packages.gz  404  Not Found\n  E: Some index files failed to download, they have been ignored, or old ones used instead.\n  ```\n\n  As such, there needs to be a [dynamic way to update `/etc/apt/sources.list`](https://github.com/alexpovel/latex-extras-docker/blob/fa9452c236079a65563daff22767b2b637dd80c6/adjust_sources_list.sh)\n  if the Debian version to be used in an archived one, see also\n  [here](https://web.archive.org/web/20201007095943/https://www.prado.lt/using-old-debian-versions-in-your-sources-list).\n- `RUN wget` (or `curl` etc.) via `HTTPS` will fail for older releases, e.g. GitHub\n  rejected the connection due to the outdated TLS version of the old release (Debian 6/TeXLive 2015):\n\n  ```text\n  Connecting to github.com|140.82.121.4|:443... connected.\n  OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version\n  ```\n\n- Downloading older releases requires using the [Debian archives](http://archive.debian.org/debian/).\n  This works fine, however a warning is issued (Debian 6/TeXLive 2014):\n\n  ```plaintext\n  W: GPG error: http://archive.debian.org squeeze Release: The following signatures were invalid: KEYEXPIRED 1520281423 KEYEXPIRED 1501892461\n  ```\n\n  Probably related to this, the installation then fails:\n\n  ```plaintext\n  WARNING: The following packages cannot be authenticated!\n    libgdbm3 libssl0.9.8 wget libdb4.7 perl-modules perl openssl ca-certificates\n  E: There are problems and -y was used without --force-yes\n  ```\n\n  According to `man apt-get`, `--force-yes` is both deprecated and absolutely not\n  recommended.\n  The correct course here is to `--allow-unauthenticated`, however this would also\n  affect the build process for modern versions, where authentication *did not* fail.\n  The official Debian archives are probably trustworthy, but this is still an issue.\n- A more obscure issue is (Debian 7/TeXLive 2011):\n\n  ```plaintext\n  The following packages have unmet dependencies:\n    perl : Depends: perl-base (= 5.14.2-21+deb7u3) but 5.14.2-21+deb7u6 is to be installed\n  E: Unable to correct problems, you have held broken packages.\n  ```\n\n  While the error message itself is crystal-clear, debugging this is probably a nightmare.\n- Tools like `pandoc`, which was released in [2006](https://pandoc.org/releases.html),\n  limit the earliest possible Debian version as long as the tool's installation is part\n  of the Dockerfile.\n  In this example, 2006 should in any case be early enough (if not, update your LaTeX\n  file to work with more recent versions, that is probably decidedly less work).\n\n## Custom Tools\n\nThe auxiliary tools are (for the actual, up-to-date list, see the [Dockerfile](Dockerfile)):\n\n- A *Java Runtime Environment* for [`bib2gls`](https://ctan.org/pkg/bib2gls) from the\n  [`glossaries-extra` package](https://www.ctan.org/pkg/glossaries-extra).\n\n  `bib2gls` takes in `*.bib` files with glossary, symbol, index and other definitions\n  and applies sorting, filtering etc.\n  For this, it requires Java.\n- [`inkscape`](https://inkscape.org/) because the [`svg`](https://ctan.org/pkg/svg)\n  package needs it.\n  We only require the CLI, however there is no \"no-GUI\" version available.\n  Headless Inkscape is [currently in the making](https://web.archive.org/web/20201007100140/https://wiki.inkscape.org/wiki/index.php/Future_Architecture).\n\n  Using that package, required PDFs and PDF_TEXs are only generated at build-time\n  (on the server or locally) and treated as a cache.\n  As such, they can be discarded freely and are regenerated in the next compilation run,\n  using `svg`, which calls `inkscape`.\n  Therefore, the `svg` package gets rid of all the PDF/PDF_TEX intermediate junk and lets us\n  deal with the true source -- `*.svg` files -- directly.\n  These files are really [XML](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics),\n  ergo text-based, ergo suitable for VCS like `git` (as opposed to binary PDFs).\n\n  Being an external tool, `svg`/`inkscape` also requires the `--shell-escape` option to\n  `lualatex` etc. for writing outside files.\n- [`gnuplot`](http://www.gnuplot.info/) for `contour gnuplot` commands for `addplot3` in `pgfplots`.\n  So essentially, an external add-on for the magnificent `pgfplots` package.\n  For `gnuplot` to write computed results to a file for `pgfplots` to read,\n  `--shell-escape` is also required.\n- [`pandoc`](https://pandoc.org/) as a very flexible, convenient markup conversion tool.\n  For example, it can convert Markdown (like this very [README](README.md)) to PDF\n  via LaTeX:\n\n  ```bash\n  pandoc README.md --output=README.pdf  # pandoc infers what to do from suffixes\n  ```\n\n  The default output is usable, but not very pretty.\n  This is where *templates* come into play.\n  A very tidy and well-made such template is\n  [*Eisvogel*](https://github.com/Wandmalfarbe/pandoc-latex-template).\n  Its installation is not via a (Debian) package, so it has to be downloaded specifically.\n  For this, additional requirements are:\n\n  - `wget` to download the archive,\n  - `librsvg2-bin` for the `rsvg-convert` tool.\n    This is used by `pandoc` to convert SVGs when embedding them into the new PDF.\n\n  Note that `pandoc` and its *Eisvogel* template can draw\n  [metadata from a YAML header](https://pandoc.org/MANUAL.html#metadata-variables),\n  for example:\n\n  ```yaml\n  ---\n  title: \"Title\"\n  author: [Author]\n  date: \"YYYY-MM-DD\"\n  subject: \"Subject\"\n  keywords: [Keyword1, Keyword2]\n  lang: \"en\"\n  ...\n  ```\n\n  among other metadata variables.\n  *Eisvogel* uses it to fill the document with info, *e.g.* the PDF header and\n  footer.\n\n  `pandoc` is not required for LaTeX work, but is convenient to have at the ready for\n  various conversion jobs.\n\n## Building\n\nThe proper way to access these images is via DockerHub.\n\n### On DockerHub\n\nThis repository and its [Dockerfile](Dockerfile) are built into the corresponding image\ncontinuously and made available on [DockerHub](https://hub.docker.com/repository/docker/alexpovel/latex).\n\nThere, the automated build process looks somewhat like:\n\n![DockerHub Build Rules](images/dockerhub_build_rules.png)\n\nThe DockerHub build process combines these build rules with the [build hook](hooks/build)\nto automatically build and tag images as specified by those rules.\n\nFor the currently available tags, see [here](https://hub.docker.com/repository/docker/alexpovel/latex/tags?page=1).\n\n### Locally\n\nThe Dockerfile can of course also be built locally.\nIf you desire to use non-default `ARG`s, the build might look like:\n\n```bash\nexport TL_VERSION=\"\u003cversion\u003e\"\nexport BASE_OS=\"\u003cLinux distro name\u003e\"\nexport OS_VERSION=\"\u003cversion corresponding to that name, e.g. '8' or 'buster' (Debian)\u003e\"\n\ndocker build . \\\n  --build-arg TL_VERSION=${TL_VERSION} \\\n  --build-arg BASE_OS=${BASE_OS} \\\n  --build-arg OS_VERSION=${OS_VERSION} \\\n  --tag \u003csome\u003e/\u003cname\u003e:${BASE_OS}-${OS_VERSION}-texlive-${TL_VERSION}\n```\n\nEssentially, you would want to emulate what the [build hook](hooks/build) does.\n\nThis process can take a very long time, especially when downloading from the TeXLive/TUG\narchives.\nFor developing/debugging, it is advisable to download the archive files once.\nE.g. for TexLive 2014, you would want this directory: \u003cftp://tug.org/historic/systems/texlive/2014/tlnet-final/\u003e.\nDownload in one go using:\n\n```bash\nwget --recursive --no-clobber ftp://tug.org/historic/systems/texlive/2014/tlnet-final\n```\n\nThe `--no-clobber` option allows you to restart the download at will.\nThen, work with the `--repository=/some/local/path` option of `install-tl`,\nafter [copying the archive directory into the image at build time](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#understand-build-context)\n(see also [here](https://tex.stackexchange.com/a/374651/120853)).\nHaving a local copy circumvents [unstable connections](https://tex.stackexchange.com/q/370686/120853)\nand minimizes unnecessary load onto TUG servers.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexpovel%2Flatex-extras-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexpovel%2Flatex-extras-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexpovel%2Flatex-extras-docker/lists"}