From 8df0d598e4f31838055ef95535d332d245a70867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E9=88=9E?= Date: Sun, 5 May 2024 04:33:54 +0800 Subject: [PATCH] feat: rewrite Dockerfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove LICENSE from the .dockerignore file - Add a new rule (DL3008) to the .hadolint.yml file - Dockerfile changes: - Extend ARG list and implement multi-arch build compatibility - Change base image format from final to compress, and add a new base image "final" - Modify ffmpeg and ffprobe using upx to compress the binary - Implement more explicit user permissions and file locations - More explicit labeling and identification for the Docker image, including information about the yt-dlp audio/video tool Signed-off-by: 陳鈞 --- .dockerignore | 1 - .hadolint.yml | 3 +- Dockerfile | 94 ++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/.dockerignore b/.dockerignore index 823c922..fb77c2e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,3 @@ *.md .git .gitignore -LICENSE diff --git a/.hadolint.yml b/.hadolint.yml index 4ac7429..b156960 100644 --- a/.hadolint.yml +++ b/.hadolint.yml @@ -5,4 +5,5 @@ ignored: - DL3013 # Pin versions in pip. Instead of `pip install ` use `pip install ==` - SC2015 # Note that A && B || C is not if-then-else. C may run when A is true. - DL3006 # Always tag the version of an image explicitly - - DL3018 # Pin versions in apk add. Instead of `apk add ` use `apk add =` \ No newline at end of file + - DL3018 # Pin versions in apk add. Instead of `apk add ` use `apk add =` + - DL3008 # Pin versions in apt. Instead of `apt-get install ` use `apt-get install =` diff --git a/Dockerfile b/Dockerfile index 15b001f..3409564 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,97 @@ # syntax=docker/dockerfile:1 ARG UID=1001 +ARG VERSION=EDGE +ARG RELEASE=0 -FROM alpine:3 as final +######################################## +# Compress stage +######################################## +FROM alpine:3 as compress -ARG UID +# RUN mount cache for multi-arch: https://github.com/docker/buildx/issues/549#issuecomment-1788297892 +ARG TARGETARCH +ARG TARGETVARIANT -RUN apk add -u --no-cache \ - # These branches follows the yt-dlp release - -X "https://dl-cdn.alpinelinux.org/alpine/edge/main" \ +# Compress ffmpeg and ffprobe +# UPX skip small files: https://github.com/upx/upx/blob/5bef96806860382395d9681f3b0c69e0f7e853cf/src/p_unix.cpp#L80 +# UPX skip large files: https://github.com/upx/upx/blob/b0dc48316516d236664dfc5f1eb5f2de00fc0799/src/conf.h#L134 +RUN --mount=type=cache,id=apk-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apk \ + --mount=from=mwader/static-ffmpeg:7.0-1,source=/ffmpeg,target=/tmp/ffmpeg,rw \ + --mount=from=mwader/static-ffmpeg:7.0-1,source=/ffprobe,target=/tmp/ffprobe,rw \ + apk update && apk add -u \ -X "https://dl-cdn.alpinelinux.org/alpine/edge/community" \ - # ffmpeg is one of the dependencies of yt-dlp, so don't need to install it manually - yt-dlp \ - # Use dumb-init to handle signals - dumb-init + # Use upx to compress the ffmpeg binary + upx dumb-init && \ + cp /tmp/ffmpeg / && \ + cp /tmp/ffprobe / && \ + upx --best --lzma /ffmpeg || true; \ + upx --best --lzma /ffprobe || true; \ + upx --best --lzma /usr/bin/dumb-init || true; \ + apk del upx + +######################################## +# Final stage +######################################## +FROM alpine:3 as final -# ffmpeg (6.1 is broken, so override it) -COPY --link --from=mwader/static-ffmpeg:6.1.1 /ffmpeg /usr/bin/ -COPY --link --from=mwader/static-ffmpeg:6.1.1 /ffprobe /usr/bin/ +# RUN mount cache for multi-arch: https://github.com/docker/buildx/issues/549#issuecomment-1788297892 +ARG TARGETARCH +ARG TARGETVARIANT # Create user +ARG UID RUN addgroup -g $UID $UID && \ adduser -H -g "" -D $UID -u $UID -G $UID +# Create directories with correct permissions +RUN install -d -m 775 -o $UID -g 0 /download && \ + install -d -m 775 -o $UID -g 0 /licenses + +# Copy licenses (OpenShift Policy) +COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Dockerfile.LICENSE +COPY --link --chown=$UID:0 --chmod=775 yt-dlp/LICENSE /licenses/yt-dlp.LICENSE + +RUN --mount=type=cache,id=apk-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apk \ + --mount=from=compress,source=/ffmpeg,target=/ffmpeg,rw \ + --mount=from=compress,source=/ffprobe,target=/ffprobe,rw \ + --mount=from=compress,source=/usr/bin/dumb-init,target=/dumb-init,rw \ + apk update && apk add -u \ + # These branches follows the yt-dlp release + -X "https://dl-cdn.alpinelinux.org/alpine/edge/main" \ + -X "https://dl-cdn.alpinelinux.org/alpine/edge/community" \ + yt-dlp && \ + # Copy the compressed ffmpeg and ffprobe and overwrite the apk installed ones + cp /ffmpeg /usr/bin/ && \ + cp /ffprobe /usr/bin/ && \ + cp /dumb-init /usr/bin/ + # Remove these to prevent the container from executing arbitrary commands RUN rm /bin/echo /bin/ln /bin/rm /bin/sh -# Run as non-root user -USER $UID -WORKDIR /download +WORKDIR /app + VOLUME [ "/download" ] +USER $UID + STOPSIGNAL SIGINT + +# Use dumb-init as PID 1 to handle signals properly ENTRYPOINT [ "dumb-init", "--", "yt-dlp", "--no-cache-dir" ] -CMD ["--help"] \ No newline at end of file +CMD ["--help"] + +ARG VERSION +ARG RELEASE +LABEL name="jim60105/docker-yt-dlp" \ + # Authors for yt-dlp + vendor="yt-dlp" \ + # Maintainer for this docker image + maintainer="jim60105" \ + # Dockerfile source repository + url="https://github.com/jim60105/docker-yt-dlp" \ + version=${VERSION} \ + # This should be a number, incremented with each change + release=${RELEASE} \ + io.k8s.display-name="yt-dlp" \ + summary="yt-dlp: A feature-rich command-line audio/video downloader." \ + description="yt-dlp is a feature-rich command-line audio/video downloader with support for thousands of sites. The project is a fork of youtube-dl based on the now inactive youtube-dlc. For more information about this tool, please visit the following website: https://github.com/yt-dlp/yt-dlp"