From b6ce19897af9eed85e878ab8bebb7d0b6d711bd2 Mon Sep 17 00:00:00 2001 From: joergklein Date: Thu, 2 Apr 2026 11:24:12 +0000 Subject: [PATCH 01/19] feat(templates): add docker-texlive template with code-server --- modules/docker-texlive/Dockerfile | 23 + modules/docker-texlive/README.md | 89 + modules/docker-texlive/icon/texlive.svg | 2356 +++++++++++++++++++++++ modules/docker-texlive/main.tf | 132 ++ 4 files changed, 2600 insertions(+) create mode 100644 modules/docker-texlive/Dockerfile create mode 100644 modules/docker-texlive/README.md create mode 100644 modules/docker-texlive/icon/texlive.svg create mode 100644 modules/docker-texlive/main.tf diff --git a/modules/docker-texlive/Dockerfile b/modules/docker-texlive/Dockerfile new file mode 100644 index 000000000..f3e776cc7 --- /dev/null +++ b/modules/docker-texlive/Dockerfile @@ -0,0 +1,23 @@ +ARG TEXLIVE_VERSION=latest +FROM registry.gitlab.com/islandoftex/images/texlive:${TEXLIVE_VERSION} + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + curl \ + unzip \ + wget \ + && rm -rf /var/lib/apt/lists/* + +# Set locale to UTF-8 +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 + +# Optional: Update TeX Live packages +# Only enable if you need the latest packages +# RUN tlmgr update --self --all + +# Working directory inside the container +WORKDIR /home/texlive + +# Icon +COPY icon/ /icon/ diff --git a/modules/docker-texlive/README.md b/modules/docker-texlive/README.md new file mode 100644 index 000000000..2cf38cc46 --- /dev/null +++ b/modules/docker-texlive/README.md @@ -0,0 +1,89 @@ +--- +display_name: Docker TeX Live +description: Provision Docker containers with TeX Live, code-server +icon: ../../../../.icons/texlive.svg +verified: true +tags: [code-server, docker, texlive] +--- + +# TeX Live Development on Docker Containers + +Provision Docker containers pre-configured for TeX development as [Coder workspaces](https://coder.com/docs/workspaces) with this template. + +Each workspace comes with: + +- **TeX Live** — TeX Live is a comprehensive, cross-platform distribution for TeX and LaTeX systems that provides all necessary programs, macro packages, and fonts for professional typesetting. +- **code-server** — VS Code in the browser for general editing. + +The workspace is based on the [TeX Live](https://www.tug.org/texlive) image. It provides nearly all packages from the [Comprehensive TeX Archive Network (CTAN)](https://www.ctan.org), although some non-free packages may be restricted. + +## Prerequisites + +### Infrastructure + +#### Running Coder inside Docker + +If you installed Coder as a container within Docker, you will have to do the following things: + +- Make the Docker socket available to the container + - **(recommended) Mount `/var/run/docker.sock` via `--mount`/`volume`** + - _(advanced) Restrict the Docker socket via https://github.com/Tecnativa/docker-socket-proxy_ +- Set `--group-add`/`group_add` to the GID of the Docker group on the **host** machine + - You can get the GID by running `getent group docker` on the **host** machine + +#### Running Coder outside of Docker + +If you installed Coder as a system package, the VM you run Coder on must have a running Docker socket and the `coder` user must be added to the Docker group: + +```bash +# Add coder user to Docker group +sudo adduser coder docker + +# Restart Coder server +sudo systemctl restart coder + +# Test Docker +sudo -u coder docker ps +``` + +## Architecture + +This template provisions the following resources: + +- Docker image (built from `build/Dockerfile`, extending `registry.gitlab.com/islandoftex/images/texlive` with system dependencies) +- Docker container (ephemeral — destroyed on workspace stop) +- Docker volume (persistent on `/home/texlive`) + +When the workspace restarts, tools and files outside `/home/texlive` are not persisted. + +> [!NOTE] +> This template is designed to be a starting point! Edit the Terraform to extend it for your use case. + +## Customization + +The continuous integration is scheduled to rebuild all Docker images weekly. Hence, pulling the latest image will provide you with an at most one week old snapshot of TeX Live including all packages. You can manually update within the container by running `tlmgr update --self --all`. + +Each of the weekly builds is tagged with `TL{RELEASE}-{YEAR}-{MONTH}-{DAY}-{HOUR}-{MINUTE}` apart from being latest for one week. If you want to have reproducible builds or happen to find a regression in a later image you can still revert to a date that worked, e.g. `TL2019-2019-08-01-08-14 or latest`. + +- [Container Registry TeX Live](https://gitlab.com/islandoftex/images/texlive/container_registry) +- [Dockerhub TeX Live](https://hub.docker.com/r/texlive/texlive) + +### Installing additional TeX packages + +If you want to update packages from CTAN after installation, see these [examples of using tlmgr](https://tug.org/texlive/doc/tlmgr.html#EXAMPLES). This is not required, or even necessarily recommended; it's up to you to decide if it makes sense to get continuing updates in your particular situation. + +Typically the main binaries are not updated in TeX Live between major releases. If you want to get updates for LuaTeX and other packages and programs that aren't officially released yet, they may be available in the [TLContrib repository](http://contrib.texlive.info), or you may need to [compile the sources](https://tug.org/texlive/svn) yourself. + +### Adding system dependencies + +The `build/Dockerfile` extends the `registry.gitlab.com/islandoftex/images/texlive` base image with system packages required by modules (e.g. `curl` for code-server). If you add modules that need additional system-level tools, add them to the `Dockerfile`: + +```dockerfile +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + curl \ + unzip \ + wget \ + your-package-here \ + && rm -rf /var/lib/apt/lists/* +``` diff --git a/modules/docker-texlive/icon/texlive.svg b/modules/docker-texlive/icon/texlive.svg new file mode 100644 index 000000000..7189c92fb --- /dev/null +++ b/modules/docker-texlive/icon/texlive.svg @@ -0,0 +1,2356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/docker-texlive/main.tf b/modules/docker-texlive/main.tf new file mode 100644 index 000000000..1910aa049 --- /dev/null +++ b/modules/docker-texlive/main.tf @@ -0,0 +1,132 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + docker = { + source = "kreuzwerker/docker" + } + } +} + +locals { + username = data.coder_workspace_owner.me.name +} + +variable "docker_socket" { + default = "" + description = "(Optional) Docker socket URI" + type = string +} + +variable "texlive_version" { + default = "2026" + description = "The TeX Live image tag to use (e.g., TL2026-2026-01-01-08-14 or latest)" + type = string +} + +provider "docker" { + host = var.docker_socket != "" ? var.docker_socket : null +} + +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +# Docker image for TeX Live 2026 +resource "docker_image" "texlive" { + name = "texlive:${var.texlive_version}" + build { + context = "./build" + dockerfile = "Dockerfile" + build_args = { + TEXLIVE_VERSION = var.texlive_version + } + } +} + +resource "docker_volume" "home_volume" { + name = "coder-${data.coder_workspace.me.id}-home" + lifecycle { ignore_changes = all } + labels = { + "coder.owner" = data.coder_workspace_owner.me.name + "coder.owner_id" = data.coder_workspace_owner.me.id + "coder.workspace_id" = data.coder_workspace.me.id + "coder.workspace_name_at_creation" = data.coder_workspace.me.name + } +} + +resource "docker_container" "texlive_workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.texlive.image_id + name = "texlive-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" + hostname = data.coder_workspace.me.name + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + + volumes { + container_path = "/home/texlive" + volume_name = docker_volume.home_volume.name + read_only = false + } + + host { + host = "host.docker.internal" + ip = "host-gateway" + } + + labels = { + "coder.owner" = data.coder_workspace_owner.me.name + "coder.owner_id" = data.coder_workspace_owner.me.id + "coder.workspace_id" = data.coder_workspace.me.id + "coder.workspace_name" = data.coder_workspace.me.name + } +} + +# Optional: Coder agent for workspace metrics +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + startup_script = <<-EOT + set -e + if [ ! -f ~/.init_done ]; then + cp -rT /etc/skel ~ 2>/dev/null || true + touch ~/.init_done + fi + EOT + + env = { + GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email + GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_COMMITTER_EMAIL = data.coder_workspace_owner.me.email + } +} + +# Code Server — served through the Coder agent +module "code-server" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/code-server/coder" + version = "~> 1.0" + + agent_id = coder_agent.main.id + order = 1 + folder = "/home/texlive" +} + +# Coder App für TeX Live 2026 + Code Server +resource "coder_app" "texlive" { + agent_id = coder_agent.main.id + slug = "texlive" + display_name = "TeX Live 2026" + url = "http://localhost:8080" # Code Server Port + icon = "/icon/texlive.svg" # Icon im Container + subdomain = true + share = "owner" + order = 1 + + labels = { + "module" = "docker-texlive" + "workspace" = data.coder_workspace.me.name + "owner" = data.coder_workspace_owner.me.name + } +} From 3ff24f1d654d9480fb8e83d1a590aa9985c7acfc Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:17:34 +0000 Subject: [PATCH 02/19] refactor: move template to registry/joergklein/templates/docker-texlive - Move files from modules/docker-texlive/ to correct namespace path - Create namespace README for joergklein - Move Dockerfile into build/ subdirectory - Fix README frontmatter: remove verified flag, fix icon path - Fix main.tf: add entrypoint for coder agent, fix label syntax, add metadata blocks, remove invalid coder_app resource --- modules/docker-texlive/main.tf | 132 --------------- registry/joergklein/README.md | 11 ++ .../templates}/docker-texlive/README.md | 3 +- .../docker-texlive/build}/Dockerfile | 0 .../docker-texlive/build}/icon/texlive.svg | 0 .../templates/docker-texlive/main.tf | 159 ++++++++++++++++++ 6 files changed, 171 insertions(+), 134 deletions(-) delete mode 100644 modules/docker-texlive/main.tf create mode 100644 registry/joergklein/README.md rename {modules => registry/joergklein/templates}/docker-texlive/README.md (98%) rename {modules/docker-texlive => registry/joergklein/templates/docker-texlive/build}/Dockerfile (100%) rename {modules/docker-texlive => registry/joergklein/templates/docker-texlive/build}/icon/texlive.svg (100%) create mode 100644 registry/joergklein/templates/docker-texlive/main.tf diff --git a/modules/docker-texlive/main.tf b/modules/docker-texlive/main.tf deleted file mode 100644 index 1910aa049..000000000 --- a/modules/docker-texlive/main.tf +++ /dev/null @@ -1,132 +0,0 @@ -terraform { - required_providers { - coder = { - source = "coder/coder" - } - docker = { - source = "kreuzwerker/docker" - } - } -} - -locals { - username = data.coder_workspace_owner.me.name -} - -variable "docker_socket" { - default = "" - description = "(Optional) Docker socket URI" - type = string -} - -variable "texlive_version" { - default = "2026" - description = "The TeX Live image tag to use (e.g., TL2026-2026-01-01-08-14 or latest)" - type = string -} - -provider "docker" { - host = var.docker_socket != "" ? var.docker_socket : null -} - -data "coder_provisioner" "me" {} -data "coder_workspace" "me" {} -data "coder_workspace_owner" "me" {} - -# Docker image for TeX Live 2026 -resource "docker_image" "texlive" { - name = "texlive:${var.texlive_version}" - build { - context = "./build" - dockerfile = "Dockerfile" - build_args = { - TEXLIVE_VERSION = var.texlive_version - } - } -} - -resource "docker_volume" "home_volume" { - name = "coder-${data.coder_workspace.me.id}-home" - lifecycle { ignore_changes = all } - labels = { - "coder.owner" = data.coder_workspace_owner.me.name - "coder.owner_id" = data.coder_workspace_owner.me.id - "coder.workspace_id" = data.coder_workspace.me.id - "coder.workspace_name_at_creation" = data.coder_workspace.me.name - } -} - -resource "docker_container" "texlive_workspace" { - count = data.coder_workspace.me.start_count - image = docker_image.texlive.image_id - name = "texlive-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" - hostname = data.coder_workspace.me.name - env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] - - volumes { - container_path = "/home/texlive" - volume_name = docker_volume.home_volume.name - read_only = false - } - - host { - host = "host.docker.internal" - ip = "host-gateway" - } - - labels = { - "coder.owner" = data.coder_workspace_owner.me.name - "coder.owner_id" = data.coder_workspace_owner.me.id - "coder.workspace_id" = data.coder_workspace.me.id - "coder.workspace_name" = data.coder_workspace.me.name - } -} - -# Optional: Coder agent for workspace metrics -resource "coder_agent" "main" { - arch = data.coder_provisioner.me.arch - os = "linux" - startup_script = <<-EOT - set -e - if [ ! -f ~/.init_done ]; then - cp -rT /etc/skel ~ 2>/dev/null || true - touch ~/.init_done - fi - EOT - - env = { - GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) - GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email - GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) - GIT_COMMITTER_EMAIL = data.coder_workspace_owner.me.email - } -} - -# Code Server — served through the Coder agent -module "code-server" { - count = data.coder_workspace.me.start_count - source = "registry.coder.com/coder/code-server/coder" - version = "~> 1.0" - - agent_id = coder_agent.main.id - order = 1 - folder = "/home/texlive" -} - -# Coder App für TeX Live 2026 + Code Server -resource "coder_app" "texlive" { - agent_id = coder_agent.main.id - slug = "texlive" - display_name = "TeX Live 2026" - url = "http://localhost:8080" # Code Server Port - icon = "/icon/texlive.svg" # Icon im Container - subdomain = true - share = "owner" - order = 1 - - labels = { - "module" = "docker-texlive" - "workspace" = data.coder_workspace.me.name - "owner" = data.coder_workspace_owner.me.name - } -} diff --git a/registry/joergklein/README.md b/registry/joergklein/README.md new file mode 100644 index 000000000..5e52b8bae --- /dev/null +++ b/registry/joergklein/README.md @@ -0,0 +1,11 @@ +--- +display_name: "Jörg Klein" +bio: "TeX Live enthusiast" +github: "joergklein" +avatar: "https://avatars.githubusercontent.com/u/38553171?v=4" +status: "community" +--- + +# Jörg Klein + +TeX Live enthusiast diff --git a/modules/docker-texlive/README.md b/registry/joergklein/templates/docker-texlive/README.md similarity index 98% rename from modules/docker-texlive/README.md rename to registry/joergklein/templates/docker-texlive/README.md index 2cf38cc46..2df6c5848 100644 --- a/modules/docker-texlive/README.md +++ b/registry/joergklein/templates/docker-texlive/README.md @@ -1,8 +1,7 @@ --- display_name: Docker TeX Live description: Provision Docker containers with TeX Live, code-server -icon: ../../../../.icons/texlive.svg -verified: true +icon: ../../../../.icons/docker.svg tags: [code-server, docker, texlive] --- diff --git a/modules/docker-texlive/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile similarity index 100% rename from modules/docker-texlive/Dockerfile rename to registry/joergklein/templates/docker-texlive/build/Dockerfile diff --git a/modules/docker-texlive/icon/texlive.svg b/registry/joergklein/templates/docker-texlive/build/icon/texlive.svg similarity index 100% rename from modules/docker-texlive/icon/texlive.svg rename to registry/joergklein/templates/docker-texlive/build/icon/texlive.svg diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf new file mode 100644 index 000000000..a2ac3c86d --- /dev/null +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -0,0 +1,159 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + docker = { + source = "kreuzwerker/docker" + } + } +} + +locals { + username = data.coder_workspace_owner.me.name +} + +variable "docker_socket" { + default = "" + description = "(Optional) Docker socket URI" + type = string +} + +variable "texlive_version" { + default = "latest" + description = "The TeX Live image tag to use (e.g., TL2025-2025-01-01-08-14 or latest)" + type = string +} + +provider "docker" { + host = var.docker_socket != "" ? var.docker_socket : null +} + +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + startup_script = <<-EOT + set -e + if [ ! -f ~/.init_done ]; then + cp -rT /etc/skel ~ 2>/dev/null || true + touch ~/.init_done + fi + EOT + + env = { + GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" + } + + metadata { + display_name = "CPU Usage" + key = "0_cpu_usage" + script = "coder stat cpu" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "RAM Usage" + key = "1_ram_usage" + script = "coder stat mem" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "Home Disk" + key = "3_home_disk" + script = "coder stat disk --path $${HOME}" + interval = 60 + timeout = 1 + } +} + +module "code-server" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/code-server/coder" + + version = "~> 1.0" + agent_id = coder_agent.main.id + agent_name = "main" + order = 1 + folder = "/home/texlive" +} + +resource "docker_image" "texlive" { + name = "texlive:${var.texlive_version}" + build { + context = "./build" + dockerfile = "Dockerfile" + build_args = { + TEXLIVE_VERSION = var.texlive_version + } + } +} + +resource "docker_volume" "home_volume" { + name = "coder-${data.coder_workspace.me.id}-home" + lifecycle { + ignore_changes = all + } + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name_at_creation" + value = data.coder_workspace.me.name + } +} + +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.texlive.image_id + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" + hostname = data.coder_workspace.me.name + entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + + host { + host = "host.docker.internal" + ip = "host-gateway" + } + + volumes { + container_path = "/home/texlive" + volume_name = docker_volume.home_volume.name + read_only = false + } + + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name" + value = data.coder_workspace.me.name + } +} From d398760c828f3c42078a3bd1e25928dd874863cd Mon Sep 17 00:00:00 2001 From: joergklein <38553171+joergklein@users.noreply.github.com> Date: Fri, 3 Apr 2026 10:01:14 +0200 Subject: [PATCH 03/19] Update README.md --- registry/joergklein/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/registry/joergklein/README.md b/registry/joergklein/README.md index 5e52b8bae..ab905f1dc 100644 --- a/registry/joergklein/README.md +++ b/registry/joergklein/README.md @@ -1,6 +1,6 @@ --- display_name: "Jörg Klein" -bio: "TeX Live enthusiast" +bio: "Data Scientists" github: "joergklein" avatar: "https://avatars.githubusercontent.com/u/38553171?v=4" status: "community" @@ -8,4 +8,4 @@ status: "community" # Jörg Klein -TeX Live enthusiast +Data Scientists From d44aec52dc97f8dbc7e9a87d576bc3de70402268 Mon Sep 17 00:00:00 2001 From: joergklein Date: Fri, 3 Apr 2026 11:18:50 +0000 Subject: [PATCH 04/19] Add an avatar --- registry/joergklein/.images/avatar.jpg | Bin 0 -> 1222 bytes registry/joergklein/README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 registry/joergklein/.images/avatar.jpg diff --git a/registry/joergklein/.images/avatar.jpg b/registry/joergklein/.images/avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d71831071746c626bab51ad55dbdc08bb5ebf153 GIT binary patch literal 1222 zcmex=KU|?coW@chxW@Tkz0jjJ8$}zAA zvI;30I#U-U>$dGXcJ4ZK_{h;?$4{I*b?NeztJkjIxOwa0qsLF4K70P+<*SdM zK7aZ8?fZ|PzZe;qA>IL!5Dy{wM-b>ACKeWE7Iu(-7@5j}m|2j8Rnd@5$T5&Tu~1ma zsF6d&Y2w0-2RW6EgFc8R6KQ!#m{`Vr(Mu#brIP!m}`f_n(=pZ~WQc$gW15ymXY zV9)UU-?@}z<)=4y>Qt&+%UfvdYIWgckiEUD7gu~RGZlYgY`e3>LYbxBFsVK>7)KI+?!f4Jn* zD|)0zQR~%#)%q+lUq!cFJ9u4rp`>W&+KpNt@9p*z-uc`7-3NAy_YqO5cfZX}*l?Ih zf09S;;XdPIb&KVD%cR*39?yENwzKWtw|}C7o8R8!dN4(${0mTIqvnpgvJq}O-<&;Z z>Kh%fZF_d4*zKCEH+vn`*ZIqY)h%CgC###ss^?T<=7pTl{|pi4e9PBA{dIM&aZvuo zXro1LC*{t#{XQ)<>yh@{u zvvae)yqqQa^u@6k3F$Ha8LDOKcC2T-{B`$T;}ENsqTMHzh4mi)+iY9>KJM^Gt0%XA z=uVKS{Om6I{nh>7x)pl_X7&^=IK7)Se&vIJOIc@xGw;g1ToCtn(>;ErbI;GuQ!VMw zl-K5IvJUrOd1xQUhq#4n?rz8pis&&+_|W% Date: Fri, 3 Apr 2026 18:59:44 +0000 Subject: [PATCH 05/19] chore: replace texlive.svg with PNG icon from TeX Live GitHub avatar --- .../docker-texlive/build/icon/texlive.png | Bin 0 -> 15484 bytes .../docker-texlive/build/icon/texlive.svg | 2356 ----------------- 2 files changed, 2356 deletions(-) create mode 100644 registry/joergklein/templates/docker-texlive/build/icon/texlive.png delete mode 100644 registry/joergklein/templates/docker-texlive/build/icon/texlive.svg diff --git a/registry/joergklein/templates/docker-texlive/build/icon/texlive.png b/registry/joergklein/templates/docker-texlive/build/icon/texlive.png new file mode 100644 index 0000000000000000000000000000000000000000..315f6846e8003fae2e3b1bc15914596ce618a220 GIT binary patch literal 15484 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From bae66fbef8b10f2738f32df9bbf49c7089fa02ce Mon Sep 17 00:00:00 2001 From: DevCats Date: Fri, 3 Apr 2026 14:03:37 -0500 Subject: [PATCH 06/19] Apply suggestion from @matifali Co-authored-by: Atif Ali --- registry/joergklein/templates/docker-texlive/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/joergklein/templates/docker-texlive/README.md b/registry/joergklein/templates/docker-texlive/README.md index 2df6c5848..eee3a4129 100644 --- a/registry/joergklein/templates/docker-texlive/README.md +++ b/registry/joergklein/templates/docker-texlive/README.md @@ -2,7 +2,7 @@ display_name: Docker TeX Live description: Provision Docker containers with TeX Live, code-server icon: ../../../../.icons/docker.svg -tags: [code-server, docker, texlive] +tags: [docker, texlive] --- # TeX Live Development on Docker Containers From 1ddea1013ba96a4878952b7ee2f569645fcbb162 Mon Sep 17 00:00:00 2001 From: joergklein Date: Sat, 4 Apr 2026 08:11:56 +0000 Subject: [PATCH 07/19] =?UTF-8?q?-=20Multiple=20workspaces=20on=20the=20sa?= =?UTF-8?q?me=20host=20-=20Automatic=20updates=20for=20latest=20=E2=86=92?= =?UTF-8?q?=20controlled=20weekly=20rebuilds=20-=20Build=20reproducibility?= =?UTF-8?q?=20via=20hash=20+=20versioning=20-=20Safe=20automatic=20cleanup?= =?UTF-8?q?=20of=20old=20images?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/docker-texlive/main.tf | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index a2ac3c86d..5b8845288 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -11,6 +11,13 @@ terraform { locals { username = data.coder_workspace_owner.me.name + + build_context_hash = sha1(join("", [ + for f in fileset("${path.module}/build", "**") : + filesha1("${path.module}/build/${f}") + ])) + + latest_rebuild_trigger = var.texlive_version == "latest" ? formatdate("YYYY-ww", timestamp()) : "" } variable "docker_socket" { @@ -36,6 +43,7 @@ data "coder_workspace_owner" "me" {} resource "coder_agent" "main" { arch = data.coder_provisioner.me.arch os = "linux" + startup_script = <<-EOT set -e if [ ! -f ~/.init_done ]; then @@ -46,9 +54,9 @@ resource "coder_agent" "main" { env = { GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) - GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) - GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_COMMITTER_EMAIL = data.coder_workspace_owner.me.email } metadata { @@ -88,21 +96,31 @@ module "code-server" { } resource "docker_image" "texlive" { - name = "texlive:${var.texlive_version}" + name = "registry.example.com/texlive:${var.texlive_version}-${data.coder_workspace.me.id}-${substr(local.build_context_hash, 0, 8)}" + build { - context = "./build" + context = "${path.module}/build" dockerfile = "Dockerfile" + build_args = { TEXLIVE_VERSION = var.texlive_version } } + + triggers = { + dir_hash = local.build_context_hash + texlive_version = var.texlive_version + latest_rebuild = local.latest_rebuild_trigger + } } resource "docker_volume" "home_volume" { name = "coder-${data.coder_workspace.me.id}-home" + lifecycle { ignore_changes = all } + labels { label = "coder.owner" value = data.coder_workspace_owner.me.name @@ -126,8 +144,14 @@ resource "docker_container" "workspace" { image = docker_image.texlive.image_id name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" hostname = data.coder_workspace.me.name - entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] - env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + + entrypoint = [ + "sh", + "-c", + replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal") + ] + + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] host { host = "host.docker.internal" @@ -157,3 +181,23 @@ resource "docker_container" "workspace" { value = data.coder_workspace.me.name } } + +resource "null_resource" "cleanup_old_texlive_images" { + triggers = { + current_image = docker_image.texlive.name + } + + provisioner "local-exec" { + command = < Date: Wed, 8 Apr 2026 13:37:30 +0200 Subject: [PATCH 08/19] Update main.tf Fixed a small error --- .../templates/docker-texlive/main.tf | 83 ++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index 5b8845288..72eba2299 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -9,17 +9,6 @@ terraform { } } -locals { - username = data.coder_workspace_owner.me.name - - build_context_hash = sha1(join("", [ - for f in fileset("${path.module}/build", "**") : - filesha1("${path.module}/build/${f}") - ])) - - latest_rebuild_trigger = var.texlive_version == "latest" ? formatdate("YYYY-ww", timestamp()) : "" -} - variable "docker_socket" { default = "" description = "(Optional) Docker socket URI" @@ -40,9 +29,26 @@ data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} +locals { + username = try(data.coder_workspace_owner.me.name, "unknown_user") + start_count = try(data.coder_workspace.me.start_count, 0) + + build_context_hash = sha1(join("", [ + for f in fileset("${path.module}/build", "**") : + try(filesha1("${path.module}/build/${f}"), "") + ])) + + date_tag = formatdate("YYYY-MM-DD-HH-mm", timestamp()) + + weekly_trigger = try( + formatdate("YYYY", timestamp()) + "-W" + tostring(ceil(tonumber(formatdate("DDD", timestamp())) / 7)), + "2026-W01" + ) +} + resource "coder_agent" "main" { - arch = data.coder_provisioner.me.arch - os = "linux" + arch = try(data.coder_provisioner.me.arch, "x86_64") + os = "linux" startup_script = <<-EOT set -e @@ -53,10 +59,10 @@ resource "coder_agent" "main" { EOT env = { - GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) - GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email - GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) - GIT_COMMITTER_EMAIL = data.coder_workspace_owner.me.email + GIT_AUTHOR_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) + GIT_AUTHOR_EMAIL = try(data.coder_workspace_owner.me.email, "unknown@example.com") + GIT_COMMITTER_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) + GIT_COMMITTER_EMAIL = try(data.coder_workspace_owner.me.email, "unknown@example.com") } metadata { @@ -85,18 +91,17 @@ resource "coder_agent" "main" { } module "code-server" { - count = data.coder_workspace.me.start_count + count = local.start_count source = "registry.coder.com/coder/code-server/coder" - version = "~> 1.0" - agent_id = coder_agent.main.id - agent_name = "main" - order = 1 - folder = "/home/texlive" + version = "~> 1.0" + agent_id = coder_agent.main.id + order = 1 + folder = "/home/texlive" } resource "docker_image" "texlive" { - name = "registry.example.com/texlive:${var.texlive_version}-${data.coder_workspace.me.id}-${substr(local.build_context_hash, 0, 8)}" + name = "registry.example.com/texlive:TL${var.texlive_version}-${try(data.coder_workspace.me.id, 0)}-${substr(local.build_context_hash, 0, 8)}-${local.date_tag}" build { context = "${path.module}/build" @@ -110,12 +115,12 @@ resource "docker_image" "texlive" { triggers = { dir_hash = local.build_context_hash texlive_version = var.texlive_version - latest_rebuild = local.latest_rebuild_trigger + latest_rebuild = local.weekly_trigger } } resource "docker_volume" "home_volume" { - name = "coder-${data.coder_workspace.me.id}-home" + name = "coder-${try(data.coder_workspace.me.id, 0)}-home" lifecycle { ignore_changes = all @@ -123,27 +128,27 @@ resource "docker_volume" "home_volume" { labels { label = "coder.owner" - value = data.coder_workspace_owner.me.name + value = local.username } labels { label = "coder.owner_id" - value = data.coder_workspace_owner.me.id + value = try(data.coder_workspace_owner.me.id, "0") } labels { label = "coder.workspace_id" - value = data.coder_workspace.me.id + value = try(data.coder_workspace.me.id, "0") } labels { label = "coder.workspace_name_at_creation" - value = data.coder_workspace.me.name + value = try(data.coder_workspace.me.name, "unknown_workspace") } } resource "docker_container" "workspace" { - count = data.coder_workspace.me.start_count + count = local.start_count image = docker_image.texlive.image_id - name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" - hostname = data.coder_workspace.me.name + name = "coder-${local.username}-${lower(try(data.coder_workspace.me.name, "workspace"))}" + hostname = try(data.coder_workspace.me.name, "workspace") entrypoint = [ "sh", @@ -166,19 +171,19 @@ resource "docker_container" "workspace" { labels { label = "coder.owner" - value = data.coder_workspace_owner.me.name + value = local.username } labels { label = "coder.owner_id" - value = data.coder_workspace_owner.me.id + value = try(data.coder_workspace_owner.me.id, "0") } labels { label = "coder.workspace_id" - value = data.coder_workspace.me.id + value = try(data.coder_workspace.me.id, "0") } labels { label = "coder.workspace_name" - value = data.coder_workspace.me.name + value = try(data.coder_workspace.me.name, "workspace") } } @@ -192,7 +197,7 @@ resource "null_resource" "cleanup_old_texlive_images" { CURRENT_ID=$(docker inspect --format='{{.Id}}' ${docker_image.texlive.name}) docker images --format "{{.Repository}}:{{.Tag}} {{.ID}}" \ - | grep "registry.example.com/texlive:${var.texlive_version}-${data.coder_workspace.me.id}" \ + | grep "registry.example.com/texlive:${var.texlive_version}-${try(data.coder_workspace.me.id, 0)}" \ | grep -v "$CURRENT_ID" \ | awk '{print $2}' \ | xargs -r docker rmi -f @@ -200,4 +205,4 @@ EOT } depends_on = [docker_image.texlive] -} \ No newline at end of file +} From 1c0048a9dd98480bcd6a845c258dd3c6abac512e Mon Sep 17 00:00:00 2001 From: joergklein <38553171+joergklein@users.noreply.github.com> Date: Wed, 8 Apr 2026 13:43:32 +0200 Subject: [PATCH 09/19] Update README.md --- registry/joergklein/templates/docker-texlive/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/registry/joergklein/templates/docker-texlive/README.md b/registry/joergklein/templates/docker-texlive/README.md index eee3a4129..a3d50ed95 100644 --- a/registry/joergklein/templates/docker-texlive/README.md +++ b/registry/joergklein/templates/docker-texlive/README.md @@ -81,7 +81,9 @@ The `build/Dockerfile` extends the `registry.gitlab.com/islandoftex/images/texli RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ + inkscape \ unzip \ + vim \ wget \ your-package-here \ && rm -rf /var/lib/apt/lists/* From 26c81683c1fed4fdf7a5ba6c56503c82663512f2 Mon Sep 17 00:00:00 2001 From: joergklein <38553171+joergklein@users.noreply.github.com> Date: Wed, 8 Apr 2026 14:02:29 +0200 Subject: [PATCH 10/19] Update Dockerfile --- .../joergklein/templates/docker-texlive/build/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/build/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile index f3e776cc7..04f35aaed 100644 --- a/registry/joergklein/templates/docker-texlive/build/Dockerfile +++ b/registry/joergklein/templates/docker-texlive/build/Dockerfile @@ -3,9 +3,11 @@ FROM registry.gitlab.com/islandoftex/images/texlive:${TEXLIVE_VERSION} RUN apt-get update \ && apt-get install -y --no-install-recommends \ - curl \ - unzip \ - wget \ + curl \ + inkscape \ + unzip \ + vim \ + wget \ && rm -rf /var/lib/apt/lists/* # Set locale to UTF-8 From b38d2d9f812c7023f4e79353526ae0edc9ed09c7 Mon Sep 17 00:00:00 2001 From: joergklein Date: Thu, 9 Apr 2026 07:11:27 +0000 Subject: [PATCH 11/19] format the files --- .../templates/docker-texlive/README.md | 16 ++++++++-------- .../templates/docker-texlive/build/Dockerfile | 16 ++++++++-------- .../joergklein/templates/docker-texlive/main.tf | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/README.md b/registry/joergklein/templates/docker-texlive/README.md index a3d50ed95..7c5fcfc94 100644 --- a/registry/joergklein/templates/docker-texlive/README.md +++ b/registry/joergklein/templates/docker-texlive/README.md @@ -79,12 +79,12 @@ The `build/Dockerfile` extends the `registry.gitlab.com/islandoftex/images/texli ```dockerfile RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - curl \ - inkscape \ - unzip \ - vim \ - wget \ - your-package-here \ - && rm -rf /var/lib/apt/lists/* + && apt-get install -y --no-install-recommends \ + curl \ + inkscape \ + unzip \ + vim \ + wget \ + your-package-here \ + && rm -rf /var/lib/apt/lists/* ``` diff --git a/registry/joergklein/templates/docker-texlive/build/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile index 04f35aaed..1166f0204 100644 --- a/registry/joergklein/templates/docker-texlive/build/Dockerfile +++ b/registry/joergklein/templates/docker-texlive/build/Dockerfile @@ -2,13 +2,13 @@ ARG TEXLIVE_VERSION=latest FROM registry.gitlab.com/islandoftex/images/texlive:${TEXLIVE_VERSION} RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - curl \ - inkscape \ - unzip \ - vim \ - wget \ - && rm -rf /var/lib/apt/lists/* + && apt-get install -y --no-install-recommends \ + curl \ + inkscape \ + unzip \ + vim \ + wget \ + && rm -rf /var/lib/apt/lists/* # Set locale to UTF-8 ENV LANG=C.UTF-8 @@ -21,5 +21,5 @@ ENV LC_ALL=C.UTF-8 # Working directory inside the container WORKDIR /home/texlive -# Icon +# Icon COPY icon/ /icon/ diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index 72eba2299..c7f909fba 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -30,7 +30,7 @@ data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} locals { - username = try(data.coder_workspace_owner.me.name, "unknown_user") + username = try(data.coder_workspace_owner.me.name, "unknown_user") start_count = try(data.coder_workspace.me.start_count, 0) build_context_hash = sha1(join("", [ From ea3c48aaa782510926b7e21a33a689b78b0997b4 Mon Sep 17 00:00:00 2001 From: joergklein Date: Mon, 13 Apr 2026 08:54:12 +0000 Subject: [PATCH 12/19] Extensions, the "settings.json" file, and the TeX Live projects are now permanently saved. --- .../templates/docker-texlive/build/Dockerfile | 23 +++++++++++++++---- .../templates/docker-texlive/main.tf | 3 +++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/build/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile index 1166f0204..017eaddb8 100644 --- a/registry/joergklein/templates/docker-texlive/build/Dockerfile +++ b/registry/joergklein/templates/docker-texlive/build/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ARG TEXLIVE_VERSION=latest FROM registry.gitlab.com/islandoftex/images/texlive:${TEXLIVE_VERSION} @@ -10,16 +12,27 @@ RUN apt-get update \ wget \ && rm -rf /var/lib/apt/lists/* -# Set locale to UTF-8 +# UTF-8 ENV LANG=C.UTF-8 ENV LC_ALL=C.UTF-8 -# Optional: Update TeX Live packages -# Only enable if you need the latest packages -# RUN tlmgr update --self --all +RUN useradd -m -s /bin/bash texlive || true + +ENV HOME=/home/texlive + +RUN chown -R texlive:texlive /home/texlive + +USER texlive -# Working directory inside the container WORKDIR /home/texlive +RUN mkdir -p /home/texlive/texmf/web2c \ + && echo "save_size = 300000" >/home/texlive/texmf/web2c/texmf.cnf \ + && chown -R texlive:texlive /home/texlive/texmf + # Icon COPY icon/ /icon/ + + vim \ + wget \ + && rm -rf /var/lib/apt/lists/* diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index c7f909fba..ef8b3ba6a 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -59,6 +59,9 @@ resource "coder_agent" "main" { EOT env = { + HOME = "/home/texlive" + XDG_DATA_HOME = "/home/texlive/.local/share" + XDG_CONFIG_HOME = "/home/texlive/.config" GIT_AUTHOR_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) GIT_AUTHOR_EMAIL = try(data.coder_workspace_owner.me.email, "unknown@example.com") GIT_COMMITTER_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) From 6a877113d326908008abdc4cfb87a03b9218d469 Mon Sep 17 00:00:00 2001 From: joergklein <38553171+joergklein@users.noreply.github.com> Date: Mon, 13 Apr 2026 11:56:15 +0200 Subject: [PATCH 13/19] Update Dockerfile --- registry/joergklein/templates/docker-texlive/build/Dockerfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/build/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile index 017eaddb8..dbe433c59 100644 --- a/registry/joergklein/templates/docker-texlive/build/Dockerfile +++ b/registry/joergklein/templates/docker-texlive/build/Dockerfile @@ -32,7 +32,3 @@ RUN mkdir -p /home/texlive/texmf/web2c \ # Icon COPY icon/ /icon/ - - vim \ - wget \ - && rm -rf /var/lib/apt/lists/* From 16db072f2e0bb647b553d7f3b1b221bcb4be1ba0 Mon Sep 17 00:00:00 2001 From: joergklein <38553171+joergklein@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:05:35 +0200 Subject: [PATCH 14/19] Update main.tf --- .../templates/docker-texlive/main.tf | 155 +++++++++--------- 1 file changed, 77 insertions(+), 78 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index ef8b3ba6a..d01f3e142 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -9,102 +9,119 @@ terraform { } } +# ------------------------- +# Variables +# ------------------------- variable "docker_socket" { - default = "" - description = "(Optional) Docker socket URI" - type = string + type = string + default = "" } variable "texlive_version" { - default = "latest" - description = "The TeX Live image tag to use (e.g., TL2025-2025-01-01-08-14 or latest)" - type = string + type = string + default = "latest" } +# ------------------------- +# Provider +# ------------------------- provider "docker" { host = var.docker_socket != "" ? var.docker_socket : null } +# ------------------------- +# Coder data +# ------------------------- data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} +# ------------------------- +# Locals (SAFE - no multiline ternary) +# ------------------------- locals { - username = try(data.coder_workspace_owner.me.name, "unknown_user") + username = try(data.coder_workspace_owner.me.name, "unknown") start_count = try(data.coder_workspace.me.start_count, 0) + year = formatdate("YYYY", timestamp()) + month = formatdate("MM", timestamp()) + day = formatdate("DD", timestamp()) + hour = formatdate("hh", timestamp()) + minute = formatdate("mm", timestamp()) + + # SAFE single-line ternary (fixes your parser error) + image_tag = var.texlive_version == "latest" ? "latest" : "TL${var.texlive_version}-${local.year}-${local.month}-${local.day}-${local.hour}-${local.minute}" + build_context_hash = sha1(join("", [ for f in fileset("${path.module}/build", "**") : try(filesha1("${path.module}/build/${f}"), "") ])) - - date_tag = formatdate("YYYY-MM-DD-HH-mm", timestamp()) - - weekly_trigger = try( - formatdate("YYYY", timestamp()) + "-W" + tostring(ceil(tonumber(formatdate("DDD", timestamp())) / 7)), - "2026-W01" - ) } +# ------------------------- +# Coder Agent +# ------------------------- resource "coder_agent" "main" { arch = try(data.coder_provisioner.me.arch, "x86_64") os = "linux" startup_script = <<-EOT set -e - if [ ! -f ~/.init_done ]; then - cp -rT /etc/skel ~ 2>/dev/null || true - touch ~/.init_done - fi + touch ~/.init_done EOT env = { - HOME = "/home/texlive" - XDG_DATA_HOME = "/home/texlive/.local/share" - XDG_CONFIG_HOME = "/home/texlive/.config" - GIT_AUTHOR_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) - GIT_AUTHOR_EMAIL = try(data.coder_workspace_owner.me.email, "unknown@example.com") - GIT_COMMITTER_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) - GIT_COMMITTER_EMAIL = try(data.coder_workspace_owner.me.email, "unknown@example.com") + HOME = "/home/texlive" + USER = "texlive" + LANG = "C.UTF-8" + LC_ALL = "C.UTF-8" + + GIT_AUTHOR_NAME = coalesce(try(data.coder_workspace_owner.me.full_name, ""), local.username) + GIT_AUTHOR_EMAIL = try(data.coder_workspace_owner.me.email, "unknown@example.com") } metadata { - display_name = "CPU Usage" - key = "0_cpu_usage" + display_name = "CPU" + key = "cpu" script = "coder stat cpu" interval = 10 timeout = 1 } metadata { - display_name = "RAM Usage" - key = "1_ram_usage" + display_name = "RAM" + key = "ram" script = "coder stat mem" interval = 10 timeout = 1 } metadata { - display_name = "Home Disk" - key = "3_home_disk" + display_name = "Disk" + key = "disk" script = "coder stat disk --path $${HOME}" interval = 60 timeout = 1 } } +# ------------------------- +# Code Server +# ------------------------- module "code-server" { - count = local.start_count - source = "registry.coder.com/coder/code-server/coder" + count = local.start_count + source = "registry.coder.com/coder/code-server/coder" + version = "~> 1.0" - version = "~> 1.0" agent_id = coder_agent.main.id - order = 1 folder = "/home/texlive" } +# ------------------------- +# Docker Image +# ------------------------- resource "docker_image" "texlive" { - name = "registry.example.com/texlive:TL${var.texlive_version}-${try(data.coder_workspace.me.id, 0)}-${substr(local.build_context_hash, 0, 8)}-${local.date_tag}" + name = "registry.example.com/texlive:${local.image_tag}" build { context = "${path.module}/build" @@ -115,40 +132,47 @@ resource "docker_image" "texlive" { } } + keep_locally = false + triggers = { dir_hash = local.build_context_hash texlive_version = var.texlive_version - latest_rebuild = local.weekly_trigger + image_tag = local.image_tag } } +# ------------------------- +# Volume (correct docker provider syntax) +# ------------------------- resource "docker_volume" "home_volume" { name = "coder-${try(data.coder_workspace.me.id, 0)}-home" - lifecycle { - ignore_changes = all - } - labels { label = "coder.owner" value = local.username } - labels { - label = "coder.owner_id" - value = try(data.coder_workspace_owner.me.id, "0") - } + labels { label = "coder.workspace_id" value = try(data.coder_workspace.me.id, "0") } + labels { - label = "coder.workspace_name_at_creation" - value = try(data.coder_workspace.me.name, "unknown_workspace") + label = "coder.workspace_name" + value = try(data.coder_workspace.me.name, "workspace") + } + + lifecycle { + ignore_changes = all } } +# ------------------------- +# Container +# ------------------------- resource "docker_container" "workspace" { - count = local.start_count + count = local.start_count + image = docker_image.texlive.image_id name = "coder-${local.username}-${lower(try(data.coder_workspace.me.name, "workspace"))}" hostname = try(data.coder_workspace.me.name, "workspace") @@ -156,10 +180,12 @@ resource "docker_container" "workspace" { entrypoint = [ "sh", "-c", - replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal") + coder_agent.main.init_script ] - env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + env = [ + "CODER_AGENT_TOKEN=${coder_agent.main.token}" + ] host { host = "host.docker.internal" @@ -176,36 +202,9 @@ resource "docker_container" "workspace" { label = "coder.owner" value = local.username } - labels { - label = "coder.owner_id" - value = try(data.coder_workspace_owner.me.id, "0") - } + labels { label = "coder.workspace_id" value = try(data.coder_workspace.me.id, "0") } - labels { - label = "coder.workspace_name" - value = try(data.coder_workspace.me.name, "workspace") - } -} - -resource "null_resource" "cleanup_old_texlive_images" { - triggers = { - current_image = docker_image.texlive.name - } - - provisioner "local-exec" { - command = < Date: Mon, 13 Apr 2026 13:06:33 +0200 Subject: [PATCH 15/19] Update Dockerfile --- .../templates/docker-texlive/build/Dockerfile | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/registry/joergklein/templates/docker-texlive/build/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile index dbe433c59..cd588140f 100644 --- a/registry/joergklein/templates/docker-texlive/build/Dockerfile +++ b/registry/joergklein/templates/docker-texlive/build/Dockerfile @@ -5,14 +5,13 @@ FROM registry.gitlab.com/islandoftex/images/texlive:${TEXLIVE_VERSION} RUN apt-get update \ && apt-get install -y --no-install-recommends \ - curl \ - inkscape \ - unzip \ - vim \ - wget \ + curl \ + inkscape \ + unzip \ + vim \ + wget \ && rm -rf /var/lib/apt/lists/* -# UTF-8 ENV LANG=C.UTF-8 ENV LC_ALL=C.UTF-8 @@ -20,15 +19,11 @@ RUN useradd -m -s /bin/bash texlive || true ENV HOME=/home/texlive -RUN chown -R texlive:texlive /home/texlive - -USER texlive - -WORKDIR /home/texlive +ENV TEXMFCNF=/home/texlive/texmf/web2c:/usr/local/texlive/2026/texmf-dist/web2c RUN mkdir -p /home/texlive/texmf/web2c \ - && echo "save_size = 300000" >/home/texlive/texmf/web2c/texmf.cnf \ - && chown -R texlive:texlive /home/texlive/texmf + && echo "save_size = 300000" > /home/texlive/texmf/web2c/texmf.cnf \ + && chown -R texlive:texlive /home/texlive -# Icon -COPY icon/ /icon/ +USER texlive +WORKDIR /home/texlive From 45556928256fc5ae827b9b8d5a365680e5842a84 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 13 Apr 2026 18:33:22 +0000 Subject: [PATCH 16/19] fix: formatting, avatar path, image name, and remove timestamp from image_tag - Fix avatar path: avatar.jpeg -> avatar.jpg to match actual file on disk - Fix Dockerfile formatting to pass prettier checks - Fix docker_image name: remove placeholder registry.example.com prefix, use workspace-scoped name coder--texlive to prevent cross-workspace collisions on shared Docker hosts - Remove timestamp() locals (year/month/day/hour/minute/image_tag) that caused phantom image rebuilds on every plan; triggers block already handles rebuild detection via dir_hash and texlive_version --- registry/joergklein/README.md | 2 +- .../templates/docker-texlive/build/Dockerfile | 12 +++--- .../templates/docker-texlive/main.tf | 39 +------------------ 3 files changed, 8 insertions(+), 45 deletions(-) diff --git a/registry/joergklein/README.md b/registry/joergklein/README.md index 132f5b53c..39874449a 100644 --- a/registry/joergklein/README.md +++ b/registry/joergklein/README.md @@ -2,7 +2,7 @@ display_name: "Jörg Klein" bio: "Data Scientists" github: "joergklein" -avatar: "./.images/avatar.jpeg" +avatar: "./.images/avatar.jpg" status: "community" --- diff --git a/registry/joergklein/templates/docker-texlive/build/Dockerfile b/registry/joergklein/templates/docker-texlive/build/Dockerfile index cd588140f..c8651e76a 100644 --- a/registry/joergklein/templates/docker-texlive/build/Dockerfile +++ b/registry/joergklein/templates/docker-texlive/build/Dockerfile @@ -5,11 +5,11 @@ FROM registry.gitlab.com/islandoftex/images/texlive:${TEXLIVE_VERSION} RUN apt-get update \ && apt-get install -y --no-install-recommends \ - curl \ - inkscape \ - unzip \ - vim \ - wget \ + curl \ + inkscape \ + unzip \ + vim \ + wget \ && rm -rf /var/lib/apt/lists/* ENV LANG=C.UTF-8 @@ -22,7 +22,7 @@ ENV HOME=/home/texlive ENV TEXMFCNF=/home/texlive/texmf/web2c:/usr/local/texlive/2026/texmf-dist/web2c RUN mkdir -p /home/texlive/texmf/web2c \ - && echo "save_size = 300000" > /home/texlive/texmf/web2c/texmf.cnf \ + && echo "save_size = 300000" >/home/texlive/texmf/web2c/texmf.cnf \ && chown -R texlive:texlive /home/texlive USER texlive diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index d01f3e142..5ab6a0b69 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -9,9 +9,6 @@ terraform { } } -# ------------------------- -# Variables -# ------------------------- variable "docker_socket" { type = string default = "" @@ -22,45 +19,24 @@ variable "texlive_version" { default = "latest" } -# ------------------------- -# Provider -# ------------------------- provider "docker" { host = var.docker_socket != "" ? var.docker_socket : null } -# ------------------------- -# Coder data -# ------------------------- data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} -# ------------------------- -# Locals (SAFE - no multiline ternary) -# ------------------------- locals { username = try(data.coder_workspace_owner.me.name, "unknown") start_count = try(data.coder_workspace.me.start_count, 0) - year = formatdate("YYYY", timestamp()) - month = formatdate("MM", timestamp()) - day = formatdate("DD", timestamp()) - hour = formatdate("hh", timestamp()) - minute = formatdate("mm", timestamp()) - - # SAFE single-line ternary (fixes your parser error) - image_tag = var.texlive_version == "latest" ? "latest" : "TL${var.texlive_version}-${local.year}-${local.month}-${local.day}-${local.hour}-${local.minute}" - build_context_hash = sha1(join("", [ for f in fileset("${path.module}/build", "**") : try(filesha1("${path.module}/build/${f}"), "") ])) } -# ------------------------- -# Coder Agent -# ------------------------- resource "coder_agent" "main" { arch = try(data.coder_provisioner.me.arch, "x86_64") os = "linux" @@ -105,9 +81,6 @@ resource "coder_agent" "main" { } } -# ------------------------- -# Code Server -# ------------------------- module "code-server" { count = local.start_count source = "registry.coder.com/coder/code-server/coder" @@ -117,11 +90,8 @@ module "code-server" { folder = "/home/texlive" } -# ------------------------- -# Docker Image -# ------------------------- resource "docker_image" "texlive" { - name = "registry.example.com/texlive:${local.image_tag}" + name = "coder-${data.coder_workspace.me.id}-texlive" build { context = "${path.module}/build" @@ -137,13 +107,9 @@ resource "docker_image" "texlive" { triggers = { dir_hash = local.build_context_hash texlive_version = var.texlive_version - image_tag = local.image_tag } } -# ------------------------- -# Volume (correct docker provider syntax) -# ------------------------- resource "docker_volume" "home_volume" { name = "coder-${try(data.coder_workspace.me.id, 0)}-home" @@ -167,9 +133,6 @@ resource "docker_volume" "home_volume" { } } -# ------------------------- -# Container -# ------------------------- resource "docker_container" "workspace" { count = local.start_count From 2658d3d962de98ba7307313d20fba4f4942a3ccb Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 13 Apr 2026 18:44:51 +0000 Subject: [PATCH 17/19] fix: restore section comments removed in previous commit --- .../templates/docker-texlive/main.tf | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/registry/joergklein/templates/docker-texlive/main.tf b/registry/joergklein/templates/docker-texlive/main.tf index 5ab6a0b69..6747a53a4 100644 --- a/registry/joergklein/templates/docker-texlive/main.tf +++ b/registry/joergklein/templates/docker-texlive/main.tf @@ -9,6 +9,9 @@ terraform { } } +# ------------------------- +# Variables +# ------------------------- variable "docker_socket" { type = string default = "" @@ -19,14 +22,23 @@ variable "texlive_version" { default = "latest" } +# ------------------------- +# Provider +# ------------------------- provider "docker" { host = var.docker_socket != "" ? var.docker_socket : null } +# ------------------------- +# Coder data +# ------------------------- data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} +# ------------------------- +# Locals +# ------------------------- locals { username = try(data.coder_workspace_owner.me.name, "unknown") start_count = try(data.coder_workspace.me.start_count, 0) @@ -37,6 +49,9 @@ locals { ])) } +# ------------------------- +# Coder Agent +# ------------------------- resource "coder_agent" "main" { arch = try(data.coder_provisioner.me.arch, "x86_64") os = "linux" @@ -81,6 +96,9 @@ resource "coder_agent" "main" { } } +# ------------------------- +# Code Server +# ------------------------- module "code-server" { count = local.start_count source = "registry.coder.com/coder/code-server/coder" @@ -90,6 +108,9 @@ module "code-server" { folder = "/home/texlive" } +# ------------------------- +# Docker Image +# ------------------------- resource "docker_image" "texlive" { name = "coder-${data.coder_workspace.me.id}-texlive" @@ -110,6 +131,9 @@ resource "docker_image" "texlive" { } } +# ------------------------- +# Volume (correct docker provider syntax) +# ------------------------- resource "docker_volume" "home_volume" { name = "coder-${try(data.coder_workspace.me.id, 0)}-home" @@ -133,6 +157,9 @@ resource "docker_volume" "home_volume" { } } +# ------------------------- +# Container +# ------------------------- resource "docker_container" "workspace" { count = local.start_count From 16e21695c15a5d2f75704f2d54c53abc7c30fa29 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 13 Apr 2026 19:01:01 +0000 Subject: [PATCH 18/19] fix: move texlive icon to .icons/ and update README to reference it --- .../build/icon => .icons}/texlive.png | Bin .../joergklein/templates/docker-texlive/README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {registry/joergklein/templates/docker-texlive/build/icon => .icons}/texlive.png (100%) diff --git a/registry/joergklein/templates/docker-texlive/build/icon/texlive.png b/.icons/texlive.png similarity index 100% rename from registry/joergklein/templates/docker-texlive/build/icon/texlive.png rename to .icons/texlive.png diff --git a/registry/joergklein/templates/docker-texlive/README.md b/registry/joergklein/templates/docker-texlive/README.md index 7c5fcfc94..4fbb55f09 100644 --- a/registry/joergklein/templates/docker-texlive/README.md +++ b/registry/joergklein/templates/docker-texlive/README.md @@ -1,7 +1,7 @@ --- display_name: Docker TeX Live description: Provision Docker containers with TeX Live, code-server -icon: ../../../../.icons/docker.svg +icon: ../../../../.icons/texlive.png tags: [docker, texlive] --- From 0bd2ca6b3416802f0326e95728154a58439507be Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 13 Apr 2026 19:08:43 +0000 Subject: [PATCH 19/19] fix: replace texlive.png with SVG icon and update README reference --- .icons/texlive.png | Bin 15484 -> 0 bytes .icons/texlive.svg | 315 ++++++++++++++++++ .../templates/docker-texlive/README.md | 2 +- 3 files changed, 316 insertions(+), 1 deletion(-) delete mode 100644 .icons/texlive.png create mode 100644 .icons/texlive.svg diff --git a/.icons/texlive.png b/.icons/texlive.png deleted file mode 100644 index 315f6846e8003fae2e3b1bc15914596ce618a220..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15484 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/registry/joergklein/templates/docker-texlive/README.md b/registry/joergklein/templates/docker-texlive/README.md index 4fbb55f09..b5bca109e 100644 --- a/registry/joergklein/templates/docker-texlive/README.md +++ b/registry/joergklein/templates/docker-texlive/README.md @@ -1,7 +1,7 @@ --- display_name: Docker TeX Live description: Provision Docker containers with TeX Live, code-server -icon: ../../../../.icons/texlive.png +icon: ../../../../.icons/texlive.svg tags: [docker, texlive] ---