From fe911d408727b35d8589b09623a057598bb76fd2 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 20:43:12 -0800 Subject: [PATCH 01/13] Move devpi Dockerfile to containers/devpi/, use v1.0.0 tag --- argocd/manifests/devpi/statefulset.yaml | 3 +-- {argocd/manifests => containers}/devpi/Dockerfile | 0 {argocd/manifests => containers}/devpi/start.sh | 0 3 files changed, 1 insertion(+), 2 deletions(-) rename {argocd/manifests => containers}/devpi/Dockerfile (100%) rename {argocd/manifests => containers}/devpi/start.sh (100%) diff --git a/argocd/manifests/devpi/statefulset.yaml b/argocd/manifests/devpi/statefulset.yaml index 77a4c56..14cdf7e 100644 --- a/argocd/manifests/devpi/statefulset.yaml +++ b/argocd/manifests/devpi/statefulset.yaml @@ -18,8 +18,7 @@ spec: fsGroup: 1000 containers: - name: devpi - # TODO: Tag builds with semantic versions (e.g., v1.0.0) for reproducibility - image: registry.ops.eblu.me/blumeops/devpi:latest + image: registry.ops.eblu.me/blumeops/devpi:v1.0.0 env: - name: DEVPI_ROOT_PASSWORD valueFrom: diff --git a/argocd/manifests/devpi/Dockerfile b/containers/devpi/Dockerfile similarity index 100% rename from argocd/manifests/devpi/Dockerfile rename to containers/devpi/Dockerfile diff --git a/argocd/manifests/devpi/start.sh b/containers/devpi/start.sh similarity index 100% rename from argocd/manifests/devpi/start.sh rename to containers/devpi/start.sh -- 2.50.1 (Apple Git-155) From 9364849941747be9d6bc0a68a73d2ae84eb7a4d2 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 20:44:21 -0800 Subject: [PATCH 02/13] Add kubectl container, update zim-watcher to use local image --- .../manifests/kiwix/cronjob-zim-watcher.yaml | 2 +- containers/kubectl/Dockerfile | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 containers/kubectl/Dockerfile diff --git a/argocd/manifests/kiwix/cronjob-zim-watcher.yaml b/argocd/manifests/kiwix/cronjob-zim-watcher.yaml index 491736f..3532676 100644 --- a/argocd/manifests/kiwix/cronjob-zim-watcher.yaml +++ b/argocd/manifests/kiwix/cronjob-zim-watcher.yaml @@ -14,7 +14,7 @@ spec: serviceAccountName: zim-watcher containers: - name: watcher - image: bitnami/kubectl:1.34.1 + image: registry.ops.eblu.me/blumeops/kubectl:v1.0.0 command: ["/bin/bash", "-c"] args: - | diff --git a/containers/kubectl/Dockerfile b/containers/kubectl/Dockerfile new file mode 100644 index 0000000..745efe6 --- /dev/null +++ b/containers/kubectl/Dockerfile @@ -0,0 +1,24 @@ +# Minimal kubectl container +# Multi-arch build: downloads correct binary for target platform + +FROM alpine:3.21 AS downloader + +ARG TARGETARCH +ARG KUBECTL_VERSION=v1.34.1 + +RUN apk add --no-cache curl && \ + curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" && \ + chmod +x kubectl + +FROM alpine:3.21 + +COPY --from=downloader /kubectl /usr/local/bin/kubectl + +# Add ca-certificates for HTTPS connections and bash for scripts +RUN apk add --no-cache ca-certificates bash + +# Run as non-root +RUN adduser -D -u 1000 kubectl +USER kubectl + +ENTRYPOINT ["kubectl"] -- 2.50.1 (Apple Git-155) From 753fede0b862f065acc20fc3858f063968a6f78a Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 20:46:55 -0800 Subject: [PATCH 03/13] Add miniflux container, update deployment to use local image Builds miniflux 2.2.16 from source using upstream build process. --- argocd/manifests/miniflux/deployment.yaml | 2 +- containers/miniflux/Dockerfile | 31 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 containers/miniflux/Dockerfile diff --git a/argocd/manifests/miniflux/deployment.yaml b/argocd/manifests/miniflux/deployment.yaml index ab573c9..f5324ac 100644 --- a/argocd/manifests/miniflux/deployment.yaml +++ b/argocd/manifests/miniflux/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: miniflux - image: ghcr.io/miniflux/miniflux:2.2.16 + image: registry.ops.eblu.me/blumeops/miniflux:v1.0.0 ports: - containerPort: 8080 env: diff --git a/containers/miniflux/Dockerfile b/containers/miniflux/Dockerfile new file mode 100644 index 0000000..eecee4d --- /dev/null +++ b/containers/miniflux/Dockerfile @@ -0,0 +1,31 @@ +# Miniflux RSS feed reader +# Based on upstream packaging/docker/alpine/Dockerfile + +ARG MINIFLUX_VERSION=2.2.16 + +FROM golang:alpine3.21 AS build + +ARG MINIFLUX_VERSION +RUN apk add --no-cache build-base git make + +# Clone specific version +RUN git clone --depth 1 --branch ${MINIFLUX_VERSION} \ + https://github.com/miniflux/v2.git /go/src/app + +WORKDIR /go/src/app +RUN make miniflux + +FROM alpine:3.21 + +LABEL org.opencontainers.image.title=Miniflux +LABEL org.opencontainers.image.description="Miniflux is a minimalist and opinionated feed reader" +LABEL org.opencontainers.image.source=https://github.com/miniflux/v2 + +EXPOSE 8080 +ENV LISTEN_ADDR=0.0.0.0:8080 + +RUN apk --no-cache add ca-certificates tzdata +COPY --from=build /go/src/app/miniflux /usr/bin/miniflux + +USER 65534 +CMD ["/usr/bin/miniflux"] -- 2.50.1 (Apple Git-155) From 7ee8c86b2446f167393a3629740c174abe455e41 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 20:49:31 -0800 Subject: [PATCH 04/13] Add kiwix-serve container, update deployment to use local image Downloads pre-built binary from kiwix mirror (same as upstream). --- argocd/manifests/kiwix/deployment.yaml | 5 +++-- containers/kiwix-serve/Dockerfile | 31 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 containers/kiwix-serve/Dockerfile diff --git a/argocd/manifests/kiwix/deployment.yaml b/argocd/manifests/kiwix/deployment.yaml index ec141dc..7b1f802 100644 --- a/argocd/manifests/kiwix/deployment.yaml +++ b/argocd/manifests/kiwix/deployment.yaml @@ -20,9 +20,10 @@ spec: containers: # Main kiwix-serve container - name: kiwix-serve - image: ghcr.io/kiwix/kiwix-serve:3.8.1 - command: ["/bin/sh", "-c"] + image: registry.ops.eblu.me/blumeops/kiwix-serve:v1.0.0 args: + - "/bin/sh" + - "-c" - "kiwix-serve --port=80 /data/complete/*.zim" ports: - containerPort: 80 diff --git a/containers/kiwix-serve/Dockerfile b/containers/kiwix-serve/Dockerfile new file mode 100644 index 0000000..c656c30 --- /dev/null +++ b/containers/kiwix-serve/Dockerfile @@ -0,0 +1,31 @@ +# kiwix-serve container +# Downloads pre-built binary from kiwix mirror + +FROM alpine:3.21 + +ARG TARGETPLATFORM +ARG KIWIX_VERSION=3.8.1 + +RUN set -e && \ + apk --no-cache add dumb-init curl && \ + echo "TARGETPLATFORM: $TARGETPLATFORM" && \ + if [ "$TARGETPLATFORM" = "linux/arm64/v8" -o "$TARGETPLATFORM" = "linux/arm64" ]; then \ + ARCH="aarch64"; \ + elif [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + ARCH="x86_64"; \ + else \ + ARCH="unknown"; \ + fi && \ + url="http://mirror.download.kiwix.org/release/kiwix-tools/kiwix-tools_linux-$ARCH-$KIWIX_VERSION.tar.gz" && \ + echo "URL: $url" && \ + curl -k -L $url | tar -xz -C /usr/local/bin/ --strip-components 1 && \ + apk del curl + +EXPOSE 80 + +# Run as non-root +RUN adduser -D -u 1000 kiwix +USER kiwix + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/bin/sh", "-c", "echo 'Use: kiwix-serve [options] ' && kiwix-serve --help"] -- 2.50.1 (Apple Git-155) From d1d45538b3f0594ab754d23520369679e1fd6b5c Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 20:51:05 -0800 Subject: [PATCH 05/13] Add transmission container, update deployments to use local image Simpler alternative to linuxserver image with same PUID/PGID support. --- argocd/manifests/kiwix/deployment.yaml | 2 +- argocd/manifests/torrent/deployment.yaml | 2 +- containers/transmission/Dockerfile | 28 +++++++++++++ containers/transmission/start.sh | 52 ++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 containers/transmission/Dockerfile create mode 100644 containers/transmission/start.sh diff --git a/argocd/manifests/kiwix/deployment.yaml b/argocd/manifests/kiwix/deployment.yaml index 7b1f802..cd450d9 100644 --- a/argocd/manifests/kiwix/deployment.yaml +++ b/argocd/manifests/kiwix/deployment.yaml @@ -53,7 +53,7 @@ spec: # Sidecar: Syncs declarative ZIM torrents to transmission - name: torrent-sync - image: lscr.io/linuxserver/transmission:4.0.6 # Has transmission-remote CLI + image: registry.ops.eblu.me/blumeops/transmission:v1.0.0 command: ["/bin/bash", "-c"] args: - | diff --git a/argocd/manifests/torrent/deployment.yaml b/argocd/manifests/torrent/deployment.yaml index 8f331bb..c0a8c2a 100644 --- a/argocd/manifests/torrent/deployment.yaml +++ b/argocd/manifests/torrent/deployment.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: transmission - image: lscr.io/linuxserver/transmission:4.0.6 + image: registry.ops.eblu.me/blumeops/transmission:v1.0.0 env: - name: PUID value: "1000" diff --git a/containers/transmission/Dockerfile b/containers/transmission/Dockerfile new file mode 100644 index 0000000..943b0f7 --- /dev/null +++ b/containers/transmission/Dockerfile @@ -0,0 +1,28 @@ +# Transmission BitTorrent daemon +# Simpler alternative to linuxserver image + +FROM alpine:3.21 + +ARG TRANSMISSION_VERSION=4.0.6-r0 + +RUN apk add --no-cache \ + transmission-daemon=${TRANSMISSION_VERSION} \ + transmission-cli=${TRANSMISSION_VERSION} \ + transmission-remote=${TRANSMISSION_VERSION} \ + bash \ + tzdata \ + su-exec + +# Create transmission user +RUN addgroup -g 1000 transmission && \ + adduser -D -u 1000 -G transmission transmission && \ + mkdir -p /config /downloads/complete /downloads/incomplete && \ + chown -R transmission:transmission /config /downloads + +COPY --chmod=755 start.sh /start.sh + +EXPOSE 9091 51413/tcp 51413/udp + +VOLUME ["/config", "/downloads"] + +ENTRYPOINT ["/start.sh"] diff --git a/containers/transmission/start.sh b/containers/transmission/start.sh new file mode 100644 index 0000000..d49f1bb --- /dev/null +++ b/containers/transmission/start.sh @@ -0,0 +1,52 @@ +#!/bin/bash +set -e + +# Handle PUID/PGID like linuxserver images +PUID=${PUID:-1000} +PGID=${PGID:-1000} + +# Update transmission user UID/GID if different from default +if [ "$PUID" != "1000" ] || [ "$PGID" != "1000" ]; then + echo "Updating transmission user to UID=$PUID GID=$PGID" + deluser transmission 2>/dev/null || true + delgroup transmission 2>/dev/null || true + addgroup -g "$PGID" transmission + adduser -D -u "$PUID" -G transmission transmission +fi + +# Ensure directories exist with correct ownership +mkdir -p /config /downloads/complete /downloads/incomplete +chown -R transmission:transmission /config /downloads + +# Create default config if it doesn't exist +CONFIG_FILE="/config/settings.json" +if [ ! -f "$CONFIG_FILE" ]; then + echo "Creating default configuration..." + cat > "$CONFIG_FILE" << 'EOF' +{ + "download-dir": "/downloads/complete", + "incomplete-dir": "/downloads/incomplete", + "incomplete-dir-enabled": true, + "rpc-enabled": true, + "rpc-bind-address": "0.0.0.0", + "rpc-port": 9091, + "rpc-whitelist-enabled": false, + "rpc-host-whitelist-enabled": false, + "peer-port": 51413, + "watch-dir-enabled": false, + "umask": 2 +} +EOF + chown transmission:transmission "$CONFIG_FILE" +fi + +# Set timezone +if [ -n "$TZ" ]; then + ln -sf "/usr/share/zoneinfo/$TZ" /etc/localtime +fi + +echo "Starting transmission-daemon..." +exec su-exec transmission transmission-daemon \ + --foreground \ + --config-dir /config \ + --log-level=info -- 2.50.1 (Apple Git-155) From 79b35610b580c8759c0c99b30de73d5152d8233f Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 20:53:06 -0800 Subject: [PATCH 06/13] Add teslamate container, update deployment to use local image Builds TeslaMate v2.2.0 from source using upstream build process. --- argocd/manifests/teslamate/deployment.yaml | 2 +- containers/teslamate/Dockerfile | 75 ++++++++++++++++++++++ containers/teslamate/entrypoint.sh | 23 +++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 containers/teslamate/Dockerfile create mode 100644 containers/teslamate/entrypoint.sh diff --git a/argocd/manifests/teslamate/deployment.yaml b/argocd/manifests/teslamate/deployment.yaml index 684b632..4d5b0e3 100644 --- a/argocd/manifests/teslamate/deployment.yaml +++ b/argocd/manifests/teslamate/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: teslamate - image: teslamate/teslamate:2.2.0 + image: registry.ops.eblu.me/blumeops/teslamate:v1.0.0 ports: - containerPort: 4000 env: diff --git a/containers/teslamate/Dockerfile b/containers/teslamate/Dockerfile new file mode 100644 index 0000000..722fb28 --- /dev/null +++ b/containers/teslamate/Dockerfile @@ -0,0 +1,75 @@ +# TeslaMate - Tesla data logger +# Based on upstream Dockerfile + +ARG TESLAMATE_VERSION=v2.2.0 + +FROM elixir:1.18-otp-26 AS builder + +ARG TESLAMATE_VERSION + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update \ + && apt-get install -y ca-certificates curl gnupg git \ + && mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ + | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && NODE_MAJOR=22 \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" \ + | tee /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install nodejs -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN mix local.rebar --force && \ + mix local.hex --force + +# Clone specific version +RUN git clone --depth 1 --branch ${TESLAMATE_VERSION} \ + https://github.com/teslamate-org/teslamate.git /opt/app + +ENV MIX_ENV=prod +WORKDIR /opt/app + +RUN mix deps.get --only $MIX_ENV +RUN mix deps.compile + +RUN npm ci --prefix ./assets --progress=false --no-audit --loglevel=error +RUN mix assets.deploy + +RUN mix compile +RUN SKIP_LOCALE_DOWNLOAD=true mix release --path /opt/built + +# Runtime image +FROM debian:bookworm-slim AS app + +ENV LANG=C.UTF-8 \ + SRTM_CACHE=/opt/app/.srtm_cache \ + HOME=/opt/app + +WORKDIR $HOME + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libodbc2 \ + libsctp1 \ + libssl3 \ + libstdc++6 \ + netcat-openbsd \ + tini \ + tzdata \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && groupadd --gid 10001 --system nonroot \ + && useradd --uid 10000 --system --gid nonroot --home-dir /home/nonroot --shell /sbin/nologin nonroot \ + && chown -R nonroot:nonroot . + +USER nonroot:nonroot +COPY --chmod=555 entrypoint.sh / +COPY --from=builder --chown=nonroot:nonroot --chmod=555 /opt/built . +RUN mkdir $SRTM_CACHE + +EXPOSE 4000 + +ENTRYPOINT ["tini", "--", "/bin/dash", "/entrypoint.sh"] +CMD ["bin/teslamate", "start"] diff --git a/containers/teslamate/entrypoint.sh b/containers/teslamate/entrypoint.sh new file mode 100644 index 0000000..f66117e --- /dev/null +++ b/containers/teslamate/entrypoint.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env dash +set -e + +: "${DATABASE_HOST:="127.0.0.1"}" +: "${DATABASE_PORT:=5432}" +: "${ULIMIT_MAX_NOFILE:=65536}" + +# prevent memory bloat in some misconfigured versions of Docker/containerd +# where the nofiles limit is very large. 0 means don't set it. +if test "${ULIMIT_MAX_NOFILE}" != 0 && test "$(ulimit -n)" -gt "${ULIMIT_MAX_NOFILE}"; then + ulimit -n "${ULIMIT_MAX_NOFILE}" +fi + +# wait until Postgres is ready +while ! nc -z "${DATABASE_HOST}" "${DATABASE_PORT}" 2>/dev/null; do + echo waiting for postgres at "${DATABASE_HOST}":"${DATABASE_PORT}" + sleep 1s +done + +# apply migrations +bin/teslamate eval "TeslaMate.Release.migrate" + +exec "$@" -- 2.50.1 (Apple Git-155) From b3c59b1dd0927bd0ed6445f0292b39d3465d89bd Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:04:58 -0800 Subject: [PATCH 07/13] Fix architecture detection in kiwix-serve and kubectl Dockerfiles TARGETARCH/TARGETPLATFORM are only set when using docker buildx. Fall back to uname -m detection for plain docker build. --- containers/kiwix-serve/Dockerfile | 26 ++++++++++++++++++++------ containers/kubectl/Dockerfile | 14 +++++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/containers/kiwix-serve/Dockerfile b/containers/kiwix-serve/Dockerfile index c656c30..37255a4 100644 --- a/containers/kiwix-serve/Dockerfile +++ b/containers/kiwix-serve/Dockerfile @@ -8,13 +8,27 @@ ARG KIWIX_VERSION=3.8.1 RUN set -e && \ apk --no-cache add dumb-init curl && \ - echo "TARGETPLATFORM: $TARGETPLATFORM" && \ - if [ "$TARGETPLATFORM" = "linux/arm64/v8" -o "$TARGETPLATFORM" = "linux/arm64" ]; then \ - ARCH="aarch64"; \ - elif [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ - ARCH="x86_64"; \ + # Detect architecture - use TARGETPLATFORM if set, otherwise detect from uname + if [ -n "$TARGETPLATFORM" ]; then \ + echo "TARGETPLATFORM: $TARGETPLATFORM"; \ + case "$TARGETPLATFORM" in \ + linux/arm64*) ARCH="aarch64" ;; \ + linux/amd64*) ARCH="x86_64" ;; \ + *) ARCH="" ;; \ + esac; \ else \ - ARCH="unknown"; \ + echo "TARGETPLATFORM not set, detecting from uname..."; \ + UNAME_ARCH=$(uname -m); \ + echo "uname -m: $UNAME_ARCH"; \ + case "$UNAME_ARCH" in \ + aarch64|arm64) ARCH="aarch64" ;; \ + x86_64) ARCH="x86_64" ;; \ + *) ARCH="" ;; \ + esac; \ + fi && \ + if [ -z "$ARCH" ]; then \ + echo "ERROR: Unsupported architecture"; \ + exit 1; \ fi && \ url="http://mirror.download.kiwix.org/release/kiwix-tools/kiwix-tools_linux-$ARCH-$KIWIX_VERSION.tar.gz" && \ echo "URL: $url" && \ diff --git a/containers/kubectl/Dockerfile b/containers/kubectl/Dockerfile index 745efe6..31a2536 100644 --- a/containers/kubectl/Dockerfile +++ b/containers/kubectl/Dockerfile @@ -7,7 +7,19 @@ ARG TARGETARCH ARG KUBECTL_VERSION=v1.34.1 RUN apk add --no-cache curl && \ - curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" && \ + # Detect architecture - use TARGETARCH if set, otherwise detect from uname + if [ -n "$TARGETARCH" ]; then \ + ARCH="$TARGETARCH"; \ + else \ + UNAME_ARCH=$(uname -m); \ + case "$UNAME_ARCH" in \ + aarch64|arm64) ARCH="arm64" ;; \ + x86_64) ARCH="amd64" ;; \ + *) echo "Unsupported architecture: $UNAME_ARCH"; exit 1 ;; \ + esac; \ + fi && \ + echo "Downloading kubectl for $ARCH..." && \ + curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl" && \ chmod +x kubectl FROM alpine:3.21 -- 2.50.1 (Apple Git-155) From 01f1b60b23bc4495c1625f0d1a40df3a376c159e Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:13:11 -0800 Subject: [PATCH 08/13] Fix transmission container: handle existing user from package --- containers/transmission/Dockerfile | 7 ++----- containers/transmission/start.sh | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/containers/transmission/Dockerfile b/containers/transmission/Dockerfile index 943b0f7..3f418cd 100644 --- a/containers/transmission/Dockerfile +++ b/containers/transmission/Dockerfile @@ -13,11 +13,8 @@ RUN apk add --no-cache \ tzdata \ su-exec -# Create transmission user -RUN addgroup -g 1000 transmission && \ - adduser -D -u 1000 -G transmission transmission && \ - mkdir -p /config /downloads/complete /downloads/incomplete && \ - chown -R transmission:transmission /config /downloads +# Create directories (user is created dynamically by start.sh based on PUID/PGID) +RUN mkdir -p /config /downloads/complete /downloads/incomplete COPY --chmod=755 start.sh /start.sh diff --git a/containers/transmission/start.sh b/containers/transmission/start.sh index d49f1bb..85d5f8c 100644 --- a/containers/transmission/start.sh +++ b/containers/transmission/start.sh @@ -5,14 +5,17 @@ set -e PUID=${PUID:-1000} PGID=${PGID:-1000} -# Update transmission user UID/GID if different from default -if [ "$PUID" != "1000" ] || [ "$PGID" != "1000" ]; then - echo "Updating transmission user to UID=$PUID GID=$PGID" - deluser transmission 2>/dev/null || true - delgroup transmission 2>/dev/null || true - addgroup -g "$PGID" transmission - adduser -D -u "$PUID" -G transmission transmission -fi +# Create or update transmission group/user with requested UID/GID +# The transmission package may have created a user with different IDs +echo "Setting up transmission user with UID=$PUID GID=$PGID" + +# Remove existing user/group if they exist (ignore errors) +deluser transmission 2>/dev/null || true +delgroup transmission 2>/dev/null || true + +# Create fresh user/group with requested IDs +addgroup -g "$PGID" transmission +adduser -D -u "$PUID" -G transmission transmission # Ensure directories exist with correct ownership mkdir -p /config /downloads/complete /downloads/incomplete -- 2.50.1 (Apple Git-155) From cb5f39bbd99d8643d438c5a7a4be41e82217d2c8 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:14:40 -0800 Subject: [PATCH 09/13] Fix transmission: use RUN chmod instead of COPY --chmod (no BuildKit) --- containers/transmission/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/containers/transmission/Dockerfile b/containers/transmission/Dockerfile index 3f418cd..f8d05ad 100644 --- a/containers/transmission/Dockerfile +++ b/containers/transmission/Dockerfile @@ -16,7 +16,8 @@ RUN apk add --no-cache \ # Create directories (user is created dynamically by start.sh based on PUID/PGID) RUN mkdir -p /config /downloads/complete /downloads/incomplete -COPY --chmod=755 start.sh /start.sh +COPY start.sh /start.sh +RUN chmod +x /start.sh EXPOSE 9091 51413/tcp 51413/udp -- 2.50.1 (Apple Git-155) From 32353a3c05d5b5088d4c45f4d4879480dc930b8d Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:17:04 -0800 Subject: [PATCH 10/13] Fix transmission: handle NFS volumes that don't allow chown --- containers/transmission/start.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/containers/transmission/start.sh b/containers/transmission/start.sh index 85d5f8c..05d0bf9 100644 --- a/containers/transmission/start.sh +++ b/containers/transmission/start.sh @@ -19,7 +19,9 @@ adduser -D -u "$PUID" -G transmission transmission # Ensure directories exist with correct ownership mkdir -p /config /downloads/complete /downloads/incomplete -chown -R transmission:transmission /config /downloads +# Only chown /config (emptyDir) - /downloads is NFS and may not allow chown +chown -R transmission:transmission /config 2>/dev/null || true +chown transmission:transmission /downloads /downloads/complete /downloads/incomplete 2>/dev/null || true # Create default config if it doesn't exist CONFIG_FILE="/config/settings.json" -- 2.50.1 (Apple Git-155) From b69af80911e6f7d105535ba933b18c0a7db99f91 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:20:44 -0800 Subject: [PATCH 11/13] Add curl to transmission container for RPC scripts --- containers/transmission/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/containers/transmission/Dockerfile b/containers/transmission/Dockerfile index f8d05ad..b17a59e 100644 --- a/containers/transmission/Dockerfile +++ b/containers/transmission/Dockerfile @@ -10,6 +10,7 @@ RUN apk add --no-cache \ transmission-cli=${TRANSMISSION_VERSION} \ transmission-remote=${TRANSMISSION_VERSION} \ bash \ + curl \ tzdata \ su-exec -- 2.50.1 (Apple Git-155) From 7a2daeb179403bef67e968a9dfdc32fcf4db49ad Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:21:05 -0800 Subject: [PATCH 12/13] Bump transmission to v1.0.1 --- argocd/manifests/kiwix/deployment.yaml | 2 +- argocd/manifests/torrent/deployment.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/argocd/manifests/kiwix/deployment.yaml b/argocd/manifests/kiwix/deployment.yaml index cd450d9..bf45625 100644 --- a/argocd/manifests/kiwix/deployment.yaml +++ b/argocd/manifests/kiwix/deployment.yaml @@ -53,7 +53,7 @@ spec: # Sidecar: Syncs declarative ZIM torrents to transmission - name: torrent-sync - image: registry.ops.eblu.me/blumeops/transmission:v1.0.0 + image: registry.ops.eblu.me/blumeops/transmission:v1.0.1 command: ["/bin/bash", "-c"] args: - | diff --git a/argocd/manifests/torrent/deployment.yaml b/argocd/manifests/torrent/deployment.yaml index c0a8c2a..5eafce8 100644 --- a/argocd/manifests/torrent/deployment.yaml +++ b/argocd/manifests/torrent/deployment.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: transmission - image: registry.ops.eblu.me/blumeops/transmission:v1.0.0 + image: registry.ops.eblu.me/blumeops/transmission:v1.0.1 env: - name: PUID value: "1000" -- 2.50.1 (Apple Git-155) From 653a2dc4f27fa6465da6e5d675bed745e0a9fe37 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 21:31:22 -0800 Subject: [PATCH 13/13] Fix teslamate: use RUN chmod instead of COPY --chmod (no BuildKit) --- argocd/manifests/teslamate/deployment.yaml | 2 +- containers/teslamate/Dockerfile | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/argocd/manifests/teslamate/deployment.yaml b/argocd/manifests/teslamate/deployment.yaml index 4d5b0e3..116541d 100644 --- a/argocd/manifests/teslamate/deployment.yaml +++ b/argocd/manifests/teslamate/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: teslamate - image: registry.ops.eblu.me/blumeops/teslamate:v1.0.0 + image: registry.ops.eblu.me/blumeops/teslamate:v1.0.1 ports: - containerPort: 4000 env: diff --git a/containers/teslamate/Dockerfile b/containers/teslamate/Dockerfile index 722fb28..e152831 100644 --- a/containers/teslamate/Dockerfile +++ b/containers/teslamate/Dockerfile @@ -64,10 +64,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && useradd --uid 10000 --system --gid nonroot --home-dir /home/nonroot --shell /sbin/nologin nonroot \ && chown -R nonroot:nonroot . +COPY entrypoint.sh / +COPY --from=builder /opt/built . +RUN chmod 555 /entrypoint.sh && \ + chown -R nonroot:nonroot . && \ + mkdir $SRTM_CACHE + USER nonroot:nonroot -COPY --chmod=555 entrypoint.sh / -COPY --from=builder --chown=nonroot:nonroot --chmod=555 /opt/built . -RUN mkdir $SRTM_CACHE EXPOSE 4000 -- 2.50.1 (Apple Git-155)