Make distroless the sole latest image and default Compose runtime
Build and Push Docker Image / build (push) Successful in 53s
Build and Push Docker Image / build (push) Successful in 53s
This commit is contained in:
1 parent
8b88089cb4
commit
4b53923829
7 files changed
+44
-136
No files matched your search
@@ -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
@@ -1,15 +1,21 @@
|
||||
FROM alpine:3.24
|
||||
|
||||
RUN mkdir /myconfig
|
||||
RUN mkdir /home/nfs_download
|
||||
RUN mkdir /root || true
|
||||
|
||||
# create file and ignore if it fails
|
||||
RUN touch /root/.rtorrent.rc || true
|
||||
COPY install/rtorrent.sh /rtorrent.sh
|
||||
|
||||
RUN apk add --no-cache bash rtorrent curl libcurl ncurses
|
||||
# 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
|
||||
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"]
|
||||
@@ -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"]
|
||||
@@ -24,26 +24,32 @@ are uploaded to Gitea, and no local container builds are required.
|
||||
# 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.
|
||||
|
||||
## Distroless variant
|
||||
## Distroless runtime
|
||||
|
||||
`docker.io/k2patel/rtorrent:distroless` is built separately using the manual
|
||||
**Build Distroless rTorrent** workflow. It preserves the Alpine 3.24 rTorrent
|
||||
binary, musl libraries, CA certificates and timezone/terminal data in a `scratch`
|
||||
final image. It contains no shell, package manager, BusyBox, or build tools.
|
||||
A small native launcher removes the stale session lock and execs rTorrent,
|
||||
so signals go directly to rTorrent. It also provides the shell-free TCP healthcheck.
|
||||
`docker.io/k2patel/rtorrent:latest` is the only maintained image variant.
|
||||
The default Dockerfile exports the Alpine 3.24 rTorrent binary, musl libraries,
|
||||
CA certificates and timezone/terminal data into a `scratch` image. It contains
|
||||
no shell, package manager, BusyBox, or build tools. The native launcher removes
|
||||
the stale session lock and execs rTorrent; it also supplies the TCP health check.
|
||||
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
|
||||
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:
|
||||
Use the default Compose file with the existing `.env` and mounted data:
|
||||
|
||||
```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`
|
||||
values and mounted data. To roll back, use the base Compose file with `:latest`.
|
||||
For an existing custom Compose file, use `:latest` for both images and replace
|
||||
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.
|
||||
@@ -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
@@ -5,14 +5,16 @@ services:
|
||||
container_name: rtorrent
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
- HOME=/root
|
||||
volumes:
|
||||
- "${TORRENT_LOCATION}:/home/nfs_download:rw"
|
||||
- "${TORRENTRC}:/root/.rtorrent.rc"
|
||||
- "${TORRENTSESSION}:/home/nfs_download/rsession:rw"
|
||||
ports:
|
||||
- 5001
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "nc -z localhost 5001 || exit 1"]
|
||||
test: ["CMD", "/usr/local/bin/rtorrent-entrypoint", "--healthcheck"]
|
||||
interval: 10s # Check every 10 seconds
|
||||
timeout: 10s # Allow the command 5 seconds to complete
|
||||
retries: 5 # Number of consecutive failures before marking as 'unhealthy'
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user