diff --git a/containers/transmission-exporter/Dockerfile b/containers/transmission-exporter/Dockerfile deleted file mode 100644 index c9d0655..0000000 --- a/containers/transmission-exporter/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Transmission Prometheus exporter - collect-on-scrape, no polling loop -# uv run --script handles dependency resolution at runtime - -ARG CONTAINER_APP_VERSION=1.0.1 - -FROM python:3.13-alpine3.23 - -ARG CONTAINER_APP_VERSION -LABEL org.opencontainers.image.title="Transmission Exporter" -LABEL org.opencontainers.image.description="Prometheus exporter for Transmission BitTorrent client" -LABEL org.opencontainers.image.version="${CONTAINER_APP_VERSION}" -LABEL org.opencontainers.image.source="https://forge.eblu.me/eblume/blumeops" -LABEL org.opencontainers.image.vendor="blumeops" - -COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv - -ENV PYTHONUNBUFFERED=1 -ENV UV_CACHE_DIR=/tmp/uv-cache - -WORKDIR /app -COPY exporter.py . - -EXPOSE 19091 -USER 65534:65534 -CMD ["uv", "run", "--script", "/app/exporter.py"] diff --git a/containers/transmission-exporter/container.py b/containers/transmission-exporter/container.py new file mode 100644 index 0000000..e88fc70 --- /dev/null +++ b/containers/transmission-exporter/container.py @@ -0,0 +1,37 @@ +"""Transmission Prometheus exporter — native Dagger build. + +Minimal collect-on-scrape exporter using uv to resolve deps at runtime. +""" + +import dagger +from dagger import dag + +from blumeops.containers import oci_labels + +VERSION = "1.0.1" + +PYTHON_BASE = "python:3.14-alpine3.23" +UV_IMAGE = "ghcr.io/astral-sh/uv:0.11.6" + + +async def build(src: dagger.Directory) -> dagger.Container: + ctr = ( + dag.container() + .from_(PYTHON_BASE) + .with_file("/usr/local/bin/uv", dag.container().from_(UV_IMAGE).file("/uv")) + .with_env_variable("PYTHONUNBUFFERED", "1") + .with_env_variable("UV_CACHE_DIR", "/tmp/uv-cache") + .with_workdir("/app") + .with_file( + "/app/exporter.py", src.file("containers/transmission-exporter/exporter.py") + ) + .with_exposed_port(19091) + .with_user("65534:65534") + .with_default_args(args=["uv", "run", "--script", "/app/exporter.py"]) + ) + return oci_labels( + ctr, + title="Transmission Exporter", + description="Prometheus exporter for Transmission BitTorrent client", + version=VERSION, + ) diff --git a/containers/transmission/Dockerfile b/containers/transmission/Dockerfile deleted file mode 100644 index 6d7bcab..0000000 --- a/containers/transmission/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -# Transmission BitTorrent daemon -# Simpler alternative to linuxserver image - -ARG CONTAINER_APP_VERSION=4.1.1-r1 - -FROM alpine:3.22 - -ARG CONTAINER_APP_VERSION -ARG TRANSMISSION_VERSION=${CONTAINER_APP_VERSION} - -LABEL org.opencontainers.image.title="Transmission" -LABEL org.opencontainers.image.description="Transmission BitTorrent daemon" -LABEL org.opencontainers.image.version="${CONTAINER_APP_VERSION}" -LABEL org.opencontainers.image.source="https://forge.eblu.me/eblume/blumeops" -LABEL org.opencontainers.image.vendor="blumeops" - -# Transmission 4.1.x is only in edge; base OS stays on stable 3.22 -RUN apk add --no-cache \ - --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community \ - transmission-daemon=${TRANSMISSION_VERSION} \ - transmission-cli=${TRANSMISSION_VERSION} \ - transmission-remote=${TRANSMISSION_VERSION} \ - && apk add --no-cache \ - bash \ - curl \ - tzdata \ - su-exec - -# Create directories (user is created dynamically by start.sh based on PUID/PGID) -RUN mkdir -p /config /downloads/complete /downloads/incomplete - -COPY start.sh /start.sh -RUN chmod +x /start.sh - -EXPOSE 9091 51413/tcp 51413/udp - -VOLUME ["/config", "/downloads"] - -ENTRYPOINT ["/start.sh"] diff --git a/containers/transmission/container.py b/containers/transmission/container.py new file mode 100644 index 0000000..c7989aa --- /dev/null +++ b/containers/transmission/container.py @@ -0,0 +1,49 @@ +"""Transmission BitTorrent daemon — native Dagger build. + +Alpine-based container with transmission-daemon from edge repo. +Includes start.sh for dynamic PUID/PGID user creation at runtime. +""" + +import dagger +from dagger import dag + +from blumeops.containers import oci_labels + +VERSION = "4.1.1-r1" + +ALPINE_BASE = "alpine:3.23" + + +async def build(src: dagger.Directory) -> dagger.Container: + ctr = ( + dag.container() + .from_(ALPINE_BASE) + # Transmission 4.1.x is only in edge community + .with_exec( + [ + "apk", + "add", + "--no-cache", + "--repository=https://dl-cdn.alpinelinux.org/alpine/edge/community", + f"transmission-daemon={VERSION}", + f"transmission-cli={VERSION}", + f"transmission-remote={VERSION}", + ] + ) + .with_exec(["apk", "add", "--no-cache", "bash", "curl", "tzdata", "su-exec"]) + .with_exec( + ["mkdir", "-p", "/config", "/downloads/complete", "/downloads/incomplete"] + ) + .with_file("/start.sh", src.file("containers/transmission/start.sh")) + .with_exec(["chmod", "+x", "/start.sh"]) + .with_exposed_port(9091) + .with_exposed_port(51413, protocol=dagger.NetworkProtocol.TCP) + .with_exposed_port(51413, protocol=dagger.NetworkProtocol.UDP) + .with_default_args(args=["/start.sh"]) + ) + return oci_labels( + ctr, + title="Transmission", + description="Transmission BitTorrent daemon", + version=VERSION, + ) diff --git a/docs/changelog.d/dagger-transmission-containers.infra.md b/docs/changelog.d/dagger-transmission-containers.infra.md new file mode 100644 index 0000000..4937a06 --- /dev/null +++ b/docs/changelog.d/dagger-transmission-containers.infra.md @@ -0,0 +1 @@ +Migrate transmission and transmission-exporter containers from Dockerfile to native Dagger builds (`container.py`). Updates base images to Alpine 3.23 and Python 3.14, pins uv to 0.11.6. diff --git a/service-versions.yaml b/service-versions.yaml index 277216d..62d8835 100644 --- a/service-versions.yaml +++ b/service-versions.yaml @@ -196,13 +196,13 @@ services: - name: transmission type: argocd - last-reviewed: 2026-03-04 + last-reviewed: 2026-04-15 current-version: "4.1.1-r1" upstream-source: https://github.com/transmission/transmission/releases - name: transmission-exporter type: argocd - last-reviewed: 2026-03-05 + last-reviewed: 2026-04-15 current-version: "1.0.1" upstream-source: null notes: Homegrown Python exporter, no upstream