Skip to content

Commit

Permalink
feat: rewrite Dockerfiles and update README.md for efficiency
Browse files Browse the repository at this point in the history
Signed-off-by: 陳鈞 <[email protected]>
  • Loading branch information
jim60105 committed May 24, 2024
1 parent 3b9ceed commit ab017de
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 90 deletions.
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
**/LICENSE
**/*.md
**/.hadolint.yml
**/node_modules
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "streamlink"]
path = streamlink
url = https://github.com/streamlink/streamlink.git
69 changes: 53 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,33 +1,70 @@
# syntax=docker/dockerfile:1
ARG UID=1001
ARG VERSION=EDGE
ARG RELEASE=0

########################################
# Final stage
########################################
FROM alpine:3 as final

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 latest release
-X "https://dl-cdn.alpinelinux.org/alpine/edge/main" \
-X "https://dl-cdn.alpinelinux.org/alpine/edge/community" \
streamlink
# Create user
ARG UID
RUN adduser -g "" -D $UID -u $UID -G root

# ffmpeg
COPY --link --from=mwader/static-ffmpeg:6.1.1 /ffmpeg /usr/bin/
# Create directories with correct permissions
RUN install -d -m 775 -o $UID -g 0 /download && \
install -d -m 775 -o $UID -g 0 /licenses

# Create user
RUN addgroup -g $UID $UID && \
adduser -H -g "" -D $UID -u $UID -G $UID
# Copy licenses (OpenShift Policy)
COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Dockerfile.LICENSE
COPY --link --chown=$UID:0 --chmod=775 streamlink/LICENSE /licenses/streamlink.LICENSE

# Run as non-root user
RUN install -d -m 775 -o $UID -g 0 /download
VOLUME [ "/download" ]
RUN --mount=type=cache,id=apk-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apk \
--mount=from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1,source=/ffmpeg,target=/ffmpeg,rw \
--mount=from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1,source=/ffprobe,target=/ffprobe,rw \
--mount=from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1,source=/dumb-init,target=/dumb-init,rw \
apk update && apk add -u \
# These branches follows the streamlink release
-X "https://dl-cdn.alpinelinux.org/alpine/edge/main" \
-X "https://dl-cdn.alpinelinux.org/alpine/edge/community" \
streamlink && \
# 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

WORKDIR /download

VOLUME [ "/download" ]

USER $UID

STOPSIGNAL SIGINT
ENTRYPOINT [ "streamlink" ]
CMD [ "--help" ]

# Use dumb-init as PID 1 to handle signals properly
ENTRYPOINT [ "dumb-init", "--", "streamlink" ]
CMD ["--help"]

ARG VERSION
ARG RELEASE
LABEL name="jim60105/docker-streamlink" \
# Authors for streamlink
vendor="Christopher Rosell, Streamlink Team" \
# Maintainer for this docker image
maintainer="jim60105" \
# Dockerfile source repository
url="hhttps://github.com/jim60105/docker-streamlink" \
version=${VERSION} \
# This should be a number, incremented with each change
release=${RELEASE} \
io.k8s.display-name="streamlink" \
summary="Streamlink is a CLI utility which pipes video streams from various services into a video player" \
description="A Python library and command-line interface which pipes streams from various services into a video player. Avoid resource-heavy and unoptimized websites, and still enjoy streamed content. For more information about this tool, please visit the following website: https://github.com/streamlink/streamlink"
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Mount the current directory as `/download` and run Streamlink with additional in
The downloaded files will be saved to where you run the command.

```bash
docker run -it -v ".:/download" ghcr.io/jim60105/streamlink --progress force --output "{id}.ts" [options] [url] best
docker run -it -v ".:/download" ghcr.io/jim60105/streamlink:alpine --progress force --output "{id}.ts" [options] [url] best
```

The `[options]`, `[url]` placeholder should be replaced with the options and arguments for Streamlink. Check the [Streamlink README](https://github.com/streamlink/streamlink?tab=readme-ov-file#-quickstart) for more information.
Expand Down Expand Up @@ -45,38 +45,27 @@ It is important to note that the [Dockerfile](Dockerfile) always builds with [th
### Build Command

> [!NOTE]
> If you are using an earlier version of the docker client, it is necessary to [enable the BuildKit mode](https://docs.docker.com/build/buildkit/#getting-started) when building the image. This is because I used the `COPY --link` feature which enhances the build performance and was introduced in Buildx v0.8.
> With the Docker Engine 23.0 and Docker Desktop 4.19, Buildx has become the default build client. So you won't have to worry about this when using the latest version.
```bash
docker build -t streamlink .
docker build --build-arg BUILD_VERSION=6.5.0 -f ./alpine.Dockerfile -t streamlink:alpine .
docker build --build-arg BUILD_VERSION=6.5.0 -f ./ubi.Dockerfile -t streamlink:ubi .
docker build --build-arg BUILD_VERSION=6.5.0 -f ./distroless.Dockerfile -t streamlink:distroless .
docker build --build-arg BUILD_VERSION=6.7.4 -f ./alpine.Dockerfile -t streamlink:alpine .
docker build --build-arg BUILD_VERSION=6.7.4 -f ./ubi.Dockerfile -t streamlink:ubi .
docker build --build-arg BUILD_VERSION=6.7.4 -f ./distroless.Dockerfile -t streamlink:distroless .
```

> [!TIP]
> I've notice that that both the UBI version and the Distroless version offer no advantages over the Alpine version. So _**please use the Alpine version**_ unless you have specific reasons not to. All of these base images are great, some of them were simply not that suitable for our project.
> [!NOTE]
> If you are using an earlier version of the docker client, it is necessary to [enable the BuildKit mode](https://docs.docker.com/build/buildkit/#getting-started) when building the image. This is because I used the `COPY --link` feature which enhances the build performance and was introduced in Buildx v0.8.
> With the Docker Engine 23.0 and Docker Desktop 4.19, Buildx has become the default build client. So you won't have to worry about this when using the latest version.
## LICENSE

> [!NOTE]
> The main program, [streamlink/streamlink](https://github.com/streamlink/streamlink), is distributed under [BSD-2-Clause license](https://github.com/streamlink/streamlink/blob/master/LICENSE).
> Please consult their repository for access to the source code and licenses.
> The following is the license for the Dockerfiles and CI workflows in this repository.
> [!CAUTION]
> A GPLv3 licensed Dockerfile means that you _**MUST**_ **distribute the source code with the same license**, if you
>
> - Re-distribute the image. (You can simply point to this GitHub repository if you doesn't made any code changes.)
> - Distribute a image that uses code from this repository.
> - Or **distribute a image based on this image**. (`FROM ghcr.io/jim60105/streamlink` in your Dockerfile)
>
> "Distribute" means to make the image available for other people to download, usually by pushing it to a public registry. If you are solely using it for your personal purposes, this has no impact on you.
>
> Please consult the [LICENSE](LICENSE) for more details.
<img src="https://github.com/jim60105/docker-streamlink/assets/16995691/2ab416c6-7f51-47d7-a8f3-d2ff38074e8b" alt="gplv3" width="300" />

[GNU GENERAL PUBLIC LICENSE Version 3](LICENSE)
Expand All @@ -86,3 +75,14 @@ This program is free software: you can redistribute it and/or modify it under th
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

> [!CAUTION]
> A GPLv3 licensed Dockerfile means that you _**MUST**_ **distribute the source code with the same license**, if you
>
> - Re-distribute the image. (You can simply point to this GitHub repository if you doesn't made any code changes.)
> - Distribute a image that uses code from this repository.
> - Or **distribute a image based on this image**. (`FROM ghcr.io/jim60105/streamlink` in your Dockerfile)
>
> "Distribute" means to make the image available for other people to download, usually by pushing it to a public registry. If you are solely using it for your personal purposes, this has no impact on you.
>
> Please consult the [LICENSE](LICENSE) for more details.
74 changes: 55 additions & 19 deletions alpine.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# syntax=docker/dockerfile:1
ARG UID=1001
ARG BUILD_VERSION=6.5.0
ARG VERSION=6.7.4
ARG RELEASE=0

########################################
# Build stage
########################################
FROM python:3.12-alpine as build

ARG BUILD_VERSION

# RUN mount cache for multi-arch: https://github.com/docker/buildx/issues/549#issuecomment-1788297892
ARG TARGETARCH
ARG TARGETVARIANT
Expand All @@ -16,43 +18,77 @@ WORKDIR /app
ENV PIP_USER="true"
ARG PIP_NO_WARN_SCRIPT_LOCATION=0
ARG PIP_ROOT_USER_ACTION="ignore"
ARG PIP_NO_COMPILE="true"
ARG PIP_DISABLE_PIP_VERSION_CHECK="true"

ARG VERSION
RUN --mount=type=cache,id=pip-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/pip \
pip3.12 install streamlink==$BUILD_VERSION && \
pip3.12 install -U --force-reinstall pip setuptools wheel && \
pip3.12 install streamlink==$VERSION && \
# Cleanup
find "/root/.local" -name '*.pyc' -print0 | xargs -0 rm -f || true ; \
find "/root/.local" -type d -name '__pycache__' -print0 | xargs -0 rm -rf || true ;

########################################
# Final stage
########################################
FROM python:3.12-alpine as final

ARG UID

RUN pip3.12 uninstall -y setuptools pip wheel && \
rm -rf /root/.cache/pip

# Create user
ARG UID
RUN adduser -g "" -D $UID -u $UID -G root

# Create directories with correct permissions
RUN install -d -m 775 -o $UID -g 0 /download && \
install -d -m 775 -o $UID -g 0 /licenses

# ffmpeg
COPY --link --from=mwader/static-ffmpeg:6.1.1 /ffmpeg /usr/local/bin/
COPY --link --from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1 /ffmpeg /usr/bin/
# COPY --link --from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1 /ffprobe /usr/bin/

# Create user
RUN addgroup -g $UID $UID && \
adduser -g "" -D $UID -u $UID -G $UID
# dumb-init
COPY --link --from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1 /dumb-init /usr/bin/

# Copy licenses (OpenShift Policy)
COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Dockerfile.LICENSE
COPY --link --chown=$UID:0 --chmod=775 streamlink/LICENSE /licenses/streamlink.LICENSE

# Copy dist and support arbitrary user ids (OpenShift best practice)
# https://docs.openshift.com/container-platform/4.14/openshift_images/create-images.html#use-uid_create-images
COPY --chown=$UID:0 --chmod=775 \
--from=build /root/.local /home/$UID/.local
ENV PATH="/home/$UID/.local/bin:$PATH"
COPY --link --chown=$UID:0 --chmod=775 --from=build /root/.local /home/$UID/.local

# Run as non-root user
RUN install -d -m 775 -o $UID -g 0 /download
VOLUME [ "/download" ]
ENV PATH="/home/$UID/.local/bin:$PATH"

# Remove these to prevent the container from executing arbitrary commands
# # Remove these to prevent the container from executing arbitrary commands
RUN rm /bin/echo /bin/ln /bin/rm /bin/sh

WORKDIR /download

VOLUME [ "/download" ]

USER $UID

STOPSIGNAL SIGINT
ENTRYPOINT [ "streamlink" ]
CMD [ "--help" ]

# Use dumb-init as PID 1 to handle signals properly
ENTRYPOINT [ "dumb-init", "--", "streamlink" ]
CMD ["--help"]

ARG VERSION
ARG RELEASE
LABEL name="jim60105/docker-streamlink" \
# Authors for streamlink
vendor="Christopher Rosell, Streamlink Team" \
# Maintainer for this docker image
maintainer="jim60105" \
# Dockerfile source repository
url="hhttps://github.com/jim60105/docker-streamlink" \
version=${VERSION} \
# This should be a number, incremented with each change
release=${RELEASE} \
io.k8s.display-name="streamlink" \
summary="Streamlink is a CLI utility which pipes video streams from various services into a video player" \
description="A Python library and command-line interface which pipes streams from various services into a video player. Avoid resource-heavy and unoptimized websites, and still enjoy streamed content. For more information about this tool, please visit the following website: https://github.com/streamlink/streamlink"
72 changes: 57 additions & 15 deletions distroless.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# syntax=docker/dockerfile:1
ARG BUILD_VERSION=6.5.0
ARG VERSION=6.7.4
ARG RELEASE=0

########################################
# Build stage
########################################
FROM python:3.12-bookworm as build

ARG BUILD_VERSION

# RUN mount cache for multi-arch: https://github.com/docker/buildx/issues/549#issuecomment-1788297892
ARG TARGETARCH
ARG TARGETVARIANT
Expand All @@ -15,33 +17,73 @@ WORKDIR /app
ENV PIP_USER="true"
ARG PIP_NO_WARN_SCRIPT_LOCATION=0
ARG PIP_ROOT_USER_ACTION="ignore"
ARG PIP_NO_COMPILE="true"
ARG PIP_DISABLE_PIP_VERSION_CHECK="true"

ARG VERSION
RUN --mount=type=cache,id=pip-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/pip \
pip3.12 install streamlink==$BUILD_VERSION && \
pip install -U --force-reinstall pip setuptools wheel && \
pip install streamlink==$VERSION && \
# Cleanup
find "/root/.local" -name '*.pyc' -print0 | xargs -0 rm -f || true ; \
find "/root/.local" -type d -name '__pycache__' -print0 | xargs -0 rm -rf || true ;

RUN install -d -m 775 -o 1000 -g 0 /download
find "/root/.local" -type d -name '__pycache__' -print0 | xargs -0 rm -rf || true ; \
\
# Make an empty directory for final stage
mkdir -p /newdir

########################################
# Final stage
# Distroless image use monty(1000) for non-root user
########################################
FROM al3xos/python-distroless:3.12-debian12 as final

ARG UID=1000

# Create directories with correct permissions
COPY --link --chown=$UID:0 --chmod=775 --from=build /newdir /download
COPY --link --chown=$UID:0 --chmod=775 --from=build /newdir /licenses

# ffmpeg
COPY --link --from=mwader/static-ffmpeg:6.1.1 /ffmpeg /usr/bin/
COPY --link --from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1 /ffmpeg /usr/bin/
# COPY --link --from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1 /ffprobe /usr/bin/

# dumb-init
COPY --link --from=ghcr.io/jim60105/static-ffmpeg-upx:7.0-1 /dumb-init /usr/bin/

# Copy licenses (OpenShift Policy)
COPY --link --chown=$UID:0 --chmod=775 LICENSE /licenses/Dockerfile.LICENSE
COPY --link --chown=$UID:0 --chmod=775 streamlink/LICENSE /licenses/streamlink.LICENSE

# Copy dist and support arbitrary user ids (OpenShift best practice)
# https://docs.openshift.com/container-platform/4.14/openshift_images/create-images.html#use-uid_create-images
COPY --chown=1000:0 --chmod=775 \
--from=build /root/.local /home/monty/.local
COPY --link --chown=$UID:0 --chmod=775 --from=build /root/.local /home/monty/.local

ENV PATH="/home/monty/.local/bin:$PATH"

COPY --chown=1000:0 --chmod=775 \
--from=build /download /download
WORKDIR /download

VOLUME [ "/download" ]

WORKDIR /download
USER $UID

STOPSIGNAL SIGINT
ENTRYPOINT [ "streamlink" ]
CMD [ "--help" ]

# Use dumb-init as PID 1 to handle signals properly
ENTRYPOINT [ "dumb-init", "--", "streamlink" ]
CMD ["--help"]

ARG VERSION
ARG RELEASE
LABEL name="jim60105/docker-streamlink" \
# Authors for streamlink
vendor="Christopher Rosell, Streamlink Team" \
# Maintainer for this docker image
maintainer="jim60105" \
# Dockerfile source repository
url="hhttps://github.com/jim60105/docker-streamlink" \
version=${VERSION} \
# This should be a number, incremented with each change
release=${RELEASE} \
io.k8s.display-name="streamlink" \
summary="Streamlink is a CLI utility which pipes video streams from various services into a video player" \
description="A Python library and command-line interface which pipes streams from various services into a video player. Avoid resource-heavy and unoptimized websites, and still enjoy streamed content. For more information about this tool, please visit the following website: https://github.com/streamlink/streamlink"
1 change: 1 addition & 0 deletions streamlink
Submodule streamlink added at 6458c4
Loading

0 comments on commit ab017de

Please sign in to comment.