Make distroless the sole latest image and default Compose runtime
Build and Push Docker Image / build (push) Successful in 53s

This commit is contained in:
Ketan Patel committed 2026-10-03 00:06:00 -04:00
1 parent 8b88089cb4
commit 4b53923829
7 files changed
+44 -136

No files matched your search

-51
View File
@@ -1,51 +0,0 @@
name: Build Distroless rTorrent
on:
workflow_dispatch:
jobs:
build:
runs-on: kube
if: github.ref == 'refs/heads/main'
env:
DOCKER_BUILD_RECORD_UPLOAD: 'false'
DOCKER_BUILD_SUMMARY: 'false'
steps:
- name: Checkout code
uses: https://github.com/actions/checkout@v4
with:
persist-credentials: false
- name: Install Docker CLI
run: |
apt-get update
apt-get install -y --no-install-recommends docker.io
rm -rf /var/lib/apt/lists/*
- name: Log in to Docker Hub
uses: https://github.com/docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Set up temporary builder
uses: https://github.com/docker/setup-buildx-action@v3
with:
driver: docker-container
cache-binary: false
keep-state: false
cleanup: true
- name: Build and push to Docker Hub
uses: https://github.com/docker/build-push-action@v6
with:
context: .
file: Dockerfile.distroless
platforms: linux/amd64
pull: true
push: true
load: false
tags: docker.io/k2patel/rtorrent:distroless
labels: |
org.opencontainers.image.source=https://git.k2patel.in/k2patel/docker-rtorrent
org.opencontainers.image.revision=${{ github.sha }}
+18 -12
View File
@@ -1,15 +1,21 @@
FROM alpine:3.24 # Keep Alpine's musl ABI and rTorrent version; export only runtime dependencies.
FROM alpine:3.24 AS runtime
RUN mkdir /myconfig RUN apk add --no-cache rtorrent ca-certificates tzdata \
RUN mkdir /home/nfs_download build-base lddtreepax python3
RUN mkdir /root || true COPY install/rtorrent-entrypoint.c /build/rtorrent-entrypoint.c
RUN cc -Os -Wall -Wextra -Werror -o /usr/local/bin/rtorrent-entrypoint /build/rtorrent-entrypoint.c \
# create file and ignore if it fails && strip /usr/local/bin/rtorrent-entrypoint
RUN touch /root/.rtorrent.rc || true COPY build/runtime-root.py /build/runtime-root.py
COPY install/rtorrent.sh /rtorrent.sh RUN python3 /build/runtime-root.py /runtime /usr/bin/rtorrent /usr/local/bin/rtorrent-entrypoint
COPY tests/rtorrent-smoke.c /build/rtorrent-smoke.c
RUN apk add --no-cache bash rtorrent curl libcurl ncurses RUN cc -static -Os -Wall -Wextra -Werror -o /build/rtorrent-smoke /build/rtorrent-smoke.c
FROM scratch
COPY --from=runtime /runtime/ /
ENV HOME=/root PATH=/usr/local/bin:/usr/bin:/bin TERM=xterm
RUN --mount=type=bind,from=runtime,source=/build/rtorrent-smoke,target=/ci-smoke ["/ci-smoke"]
VOLUME ["/home/nfs_download"] VOLUME ["/home/nfs_download"]
EXPOSE 5001/tcp EXPOSE 5001/tcp
ENTRYPOINT ["/rtorrent.sh"] HEALTHCHECK --interval=10s --timeout=10s --start-period=90s --retries=5 \
CMD ["/usr/local/bin/rtorrent-entrypoint", "--healthcheck"]
ENTRYPOINT ["/usr/local/bin/rtorrent-entrypoint"]
-21
View File
@@ -1,21 +0,0 @@
# Keep Alpine's musl ABI and rTorrent version; export only runtime dependencies.
FROM alpine:3.24 AS runtime
RUN apk add --no-cache rtorrent ca-certificates tzdata \
build-base lddtreepax python3
COPY install/rtorrent-entrypoint.c /build/rtorrent-entrypoint.c
RUN cc -Os -Wall -Wextra -Werror -o /usr/local/bin/rtorrent-entrypoint /build/rtorrent-entrypoint.c \
&& strip /usr/local/bin/rtorrent-entrypoint
COPY build/runtime-root.py /build/runtime-root.py
RUN python3 /build/runtime-root.py /runtime /usr/bin/rtorrent /usr/local/bin/rtorrent-entrypoint
COPY tests/rtorrent-smoke.c /build/rtorrent-smoke.c
RUN cc -static -Os -Wall -Wextra -Werror -o /build/rtorrent-smoke /build/rtorrent-smoke.c
FROM scratch
COPY --from=runtime /runtime/ /
ENV HOME=/root PATH=/usr/local/bin:/usr/bin:/bin TERM=xterm
RUN --mount=type=bind,from=runtime,source=/build/rtorrent-smoke,target=/ci-smoke ["/ci-smoke"]
VOLUME ["/home/nfs_download"]
EXPOSE 5001/tcp
HEALTHCHECK --interval=10s --timeout=10s --start-period=90s --retries=5 \
CMD ["/usr/local/bin/rtorrent-entrypoint", "--healthcheck"]
ENTRYPOINT ["/usr/local/bin/rtorrent-entrypoint"]
+23 -17
View File
@@ -24,26 +24,32 @@ are uploaded to Gitea, and no local container builds are required.
# Latest 0.16 version caveat # Latest 0.16 version caveat
- since version 0.16 explicitly set `network.bind_address.set = 0.0.0.0`, when ipv6 is disabled on kernel. - since version 0.16 explicitly set `network.bind_address.set = 0.0.0.0`, when ipv6 is disabled on kernel.
## Distroless variant ## Distroless runtime
`docker.io/k2patel/rtorrent:distroless` is built separately using the manual `docker.io/k2patel/rtorrent:latest` is the only maintained image variant.
**Build Distroless rTorrent** workflow. It preserves the Alpine 3.24 rTorrent The default Dockerfile exports the Alpine 3.24 rTorrent binary, musl libraries,
binary, musl libraries, CA certificates and timezone/terminal data in a `scratch` CA certificates and timezone/terminal data into a `scratch` image. It contains
final image. It contains no shell, package manager, BusyBox, or build tools. no shell, package manager, BusyBox, or build tools. The native launcher removes
A small native launcher removes the stale session lock and execs rTorrent, the stale session lock and execs rTorrent; it also supplies the TCP health check.
so signals go directly to rTorrent. It also provides the shell-free TCP healthcheck. CI starts rTorrent and verifies an SCGI XML-RPC request before publication.
CI tests the assembled filesystem by starting rTorrent and making an SCGI XML-RPC Use the default Compose file with the existing `.env` and mounted data:
request before publishing. The working `latest` tag is independent.
Your mounted `rtorrent.rc` must not depend on shell commands or utilities missing
from this image (including `execute` hooks). Review those hooks before switching.
Existing mount paths, SCGI port 5001, root UID and `HOME=/root` are preserved.
Use the Compose overlay to replace the shell-based healthcheck:
```sh ```sh
docker compose -f docker-compose.yml -f docker-compose.distroless.yml up -d docker compose pull
docker compose up -d --force-recreate
``` ```
The overlay also selects the separate Flood distroless image. Keep the same `.env` For an existing custom Compose file, use `:latest` for both images and replace
values and mounted data. To roll back, use the base Compose file with `:latest`. any shell-based rTorrent health check with:
```yaml
healthcheck:
test: ["CMD", "/usr/local/bin/rtorrent-entrypoint", "--healthcheck"]
```
The separate `:distroless` tag and Compose overlay are retired. Both services in
the default Compose file now use distroless `:latest`. Root UID, HOME=/root,
SCGI port 5001, download paths and the session volume remain supported.
Mounted `rtorrent.rc` execute hooks must use programs available in the image;
shell commands and arbitrary external utilities are unavailable.
-12
View File
@@ -1,12 +0,0 @@
# Use alongside docker-compose.yml after checking rtorrent.rc for external commands.
services:
rtorrent:
image: docker.io/k2patel/rtorrent:distroless
environment:
- HOME=/root
volumes:
- "${TORRENTSESSION}:/home/nfs_download/rsession:rw"
healthcheck:
test: ["CMD", "/usr/local/bin/rtorrent-entrypoint", "--healthcheck"]
floodui:
image: docker.io/k2patel/floodui:distroless
+3 -1
View File
@@ -5,14 +5,16 @@ services:
container_name: rtorrent container_name: rtorrent
environment: environment:
- TZ=${TZ} - TZ=${TZ}
- HOME=/root
volumes: volumes:
- "${TORRENT_LOCATION}:/home/nfs_download:rw" - "${TORRENT_LOCATION}:/home/nfs_download:rw"
- "${TORRENTRC}:/root/.rtorrent.rc" - "${TORRENTRC}:/root/.rtorrent.rc"
- "${TORRENTSESSION}:/home/nfs_download/rsession:rw"
ports: ports:
- 5001 - 5001
restart: unless-stopped restart: unless-stopped
healthcheck: healthcheck:
test: ["CMD-SHELL", "nc -z localhost 5001 || exit 1"] test: ["CMD", "/usr/local/bin/rtorrent-entrypoint", "--healthcheck"]
interval: 10s # Check every 10 seconds interval: 10s # Check every 10 seconds
timeout: 10s # Allow the command 5 seconds to complete timeout: 10s # Allow the command 5 seconds to complete
retries: 5 # Number of consecutive failures before marking as 'unhealthy' retries: 5 # Number of consecutive failures before marking as 'unhealthy'
-22
View File
@@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -e
CLEANUP_FILE="/home/nfs_download/rsession/rtorrent.lock"
# Remove stale lock at startup
if [ -f "$CLEANUP_FILE" ]; then
echo "️Stale lock file found. Removing..."
rm -f "$CLEANUP_FILE"
fi
cleanup() {
echo "Caught shutdown signal. Cleaning up..."
rm -f "$CLEANUP_FILE"
echo "Cleanup complete."
}
trap cleanup INT TERM EXIT
echo "Starting rtorrent..."
exec rtorrent