From 8ea3f0ecaf6732222040f25fc34bbf322370e1c7 Mon Sep 17 00:00:00 2001 From: Shawn Anderson Date: Wed, 21 Apr 2021 20:05:03 -0400 Subject: [PATCH] Updated Dockerfile and related files --- Dockerfile | 55 ++++++--- README-DOCKER.md | 190 ++++++++++++++++++++++++++++++ docker-compose.yml | 4 +- docker-publish.ps1 | 50 ++++++++ root/etc/cont-init.d/30-config | 13 ++ root/etc/services.d/rtdclient/run | 13 ++ 6 files changed, 307 insertions(+), 18 deletions(-) create mode 100644 README-DOCKER.md create mode 100755 docker-publish.ps1 create mode 100755 root/etc/cont-init.d/30-config create mode 100755 root/etc/services.d/rtdclient/run diff --git a/Dockerfile b/Dockerfile index b51d628..4ddb806 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,9 @@ # Stage 1 - Build the frontend -FROM amd64/node:15.5-buster AS node-build-env +FROM node:15.5-buster AS node-build-env +ARG TARGETPLATFORM +ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} +ARG BUILDPLATFORM +ENV BUILDPLATFORM=${BUILDPLATFORM:-linux/amd64} RUN mkdir /appclient WORKDIR /appclient @@ -11,24 +15,38 @@ RUN \ npx ng build --prod --output-path=out # Stage 2 - Build the backend -FROM mcr.microsoft.com/dotnet/sdk:5.0.103-alpine3.13-amd64 AS dotnet-build-env +FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim-amd64 AS dotnet-build-env +ARG TARGETPLATFORM +ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} +ARG BUILDPLATFORM +ENV BUILDPLATFORM=${BUILDPLATFORM:-linux/amd64} RUN mkdir /appserver WORKDIR /appserver RUN \ + echo "**** Cloning Source Code ****" && \ git clone https://github.com/rogerfar/rdt-client.git . && \ + echo "**** Building Source Code for $TARGETPLATFORM on $BUILDPLATFORM ****" && \ cd server && \ - if [ "$BUILDPLATFORM" = "arm/v7" ] ; then dotnet restore -r linux-arm RdtClient.sln ; else dotnet restore RdtClient.sln ; fi && \ - if [ "$BUILDPLATFORM" = "arm/v7" ] ; then dotnet publish -r linux-arm -c Release -o out ; else dotnet publish -c Release -o out ; fi + if [ "$TARGETPLATFORM" = "linux/arm/v7" -o "$TARGETPLATFORM" = "linux/arm64" ] ; then \ + echo "**** Building $TARGETPLATFORM version" && \ + dotnet restore -r linux-arm RdtClient.sln && dotnet publish -r linux-arm -c Release -o out ; \ + else \ + echo "**** Building standard version" && \ + dotnet restore RdtClient.sln && dotnet publish -c Release -o out ; \ + fi # Stage 3 - Build runtime image -FROM ghcr.io/linuxserver/baseimage-mono:LTS +FROM ghcr.io/linuxserver/baseimage-ubuntu:focal +ARG TARGETPLATFORM +ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} +ARG BUILDPLATFORM +ENV BUILDPLATFORM=${BUILDPLATFORM:-linux/amd64} # set version label ARG BUILD_DATE ARG VERSION -ARG RDTCLIENT_VERSION LABEL build_version="Linuxserver.io extended version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="ravensorb" @@ -37,16 +55,18 @@ ARG DEBIAN_FRONTEND="noninteractive" ENV XDG_CONFIG_HOME="/config/xdg" ENV RDTCLIENT_BRANCH="main" -RUN mkdir /app || true && mkdir -p /data/downloads /data/db || true && \ +RUN \ + mkdir -p /data/downloads /data/db || true && \ echo "**** Updating package information ****" && \ - apt update -y -qq && \ - apt install -y -qq wget && \ + apt-get update -y -qq && \ + echo "**** Install pre-reqs ****" && \ + apt-get install -y -qq wget && \ + apt-get install -y libc6 libgcc1 libgssapi-krb5-2 libssl1.1 libstdc++6 zlib1g libicu66 && \ echo "**** Installing dotnet ****" && \ - wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb && \ - dpkg -i packages-microsoft-prod.deb 2> /dev/null && \ - rm packages-microsoft-prod.deb && \ - apt update -y -qq && \ - apt install -y -qq apt-transport-https dotnet-runtime-5.0 aspnetcore-runtime-5.0 && \ + wget -q https://dot.net/v1/dotnet-install.sh && \ + chmod +x ./dotnet-install.sh && \ + bash ./dotnet-install.sh -c Current --runtime dotnet --install-dir /usr/share/dotnet && \ + bash ./dotnet-install.sh -c Current --runtime aspnetcore --install-dir /usr/share/dotnet && \ echo "**** Cleaning image ****" && \ apt-get -y -qq -o Dpkg::Use-Pty=0 clean && apt-get -y -qq -o Dpkg::Use-Pty=0 purge && \ echo "**** Setting permissions ****" && \ @@ -56,12 +76,15 @@ RUN mkdir /app || true && mkdir -p /data/downloads /data/db || true && \ /var/lib/apt/lists/* \ /var/tmp/* || true +ENV PATH "$PATH:/usr/share/dotnet" + WORKDIR /app COPY --from=dotnet-build-env /appserver/server/out . COPY --from=node-build-env /appclient/client/out ./wwwroot +# add local files +COPY root/ / + # ports and volumes EXPOSE 6500 VOLUME ["/config", "/data" ] - -ENTRYPOINT ["dotnet", "RdtClient.Web.dll"] \ No newline at end of file diff --git a/README-DOCKER.md b/README-DOCKER.md new file mode 100644 index 0000000..125d404 --- /dev/null +++ b/README-DOCKER.md @@ -0,0 +1,190 @@ +# [rogerfar/rdt-client](https://github.com/rogerfar/rdt-client) +Thid docker file follows the [linuxserver.io](https://linuxserver.io) pattern that leverages the [s6-overlay](https://github.com/just-containers/s6-overlay) to run the application as a service within the container. This allows for scripts to be run prior to start of the application to handle initalization and setting of permissions. + +rdt-client is a web a web interface to manage your torrents on Real-Debrid. It supports the following features: + +* Add new torrents through magnets or files +* Download all files from Real Debrid to your local machine automatically +* Unpack all files when finished downloading +* Implements a fake qBittorrent API so you can hook up other applications like Sonarr or Couchpotato. +* Built with Angular 11 and .NET 5 + +## Supported Architectures + +Our images support multiple architectures such as `x86-64`, `arm64` and `armhf`. We utilise the docker manifest for multi-platform awareness. More information is available from docker [here](https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md#manifest-list) and our announcement [here](https://blog.linuxserver.io/2019/02/21/the-lsio-pipeline-project/). + +Simply pulling `rogerfar/rdt-client` should retrieve the correct image for your arch, but you can also pull specific arch images via tags. + +The architectures supported by this image are: + +| Architecture | Tag | +| :----: | --- | +| x86-64 | amd64-latest | +| arm64 | arm64v8-latest | +| armhf | arm32v7-latest | + +## Version Tags + +This image provides various versions that are available via tags. `latest` tag usually provides the latest stable version. Others are considered under development and caution must be exercised when using them. + +| Tag | Description | +| :----: | --- | +| latest | Stable releases | + +## Usage + +Here are some example snippets to help you get started creating a container. + +### docker-compose ([recommended](https://docs.linuxserver.io/general/docker-compose)) + +Compatible with docker-compose v2 schemas. + +```yaml +--- +version: '3.3' +services: + rdtclient: + image: rogerfar/rdtclient + container_name: rdtclient + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/London + volumes: + - :/data/db + - :/data/downloads + logging: + driver: json-file + options: + max-size: 10m + ports: + - 6500:6500 + restart: unless-stopped +``` + +### docker cli + +``` +docker run -d \ + --name=rdtclient \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Europe/London \ + -p 6500:6500 \ + -v :/data/db \ + -v :/data/downloads \ + --restart unless-stopped \ + rogerfar/rdtclient +``` + +## Parameters + +Container images are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate `:` respectively. For example, `-p 8080:80` would expose port `80` from inside the container to be accessible from the host's IP on port `8080` outside the container. + +| Parameter | Function | +| :----: | --- | +| `-p 6500` | WebUI | +| `-e PUID=1000` | for UserID - see below for explanation | +| `-e PGID=1000` | for GroupID - see below for explanation | +| `-e TZ=Europe/London` | Specify a timezone to use EG Europe/London. | +| `-v /data/db` | App data. | +| `-v /data/downloads` | Location of downloads on disk. | + +## Environment variables from files (Docker secrets) + +You can set any environment variable from a file by using a special prepend `FILE__`. + +As an example: + +``` +-e FILE__PASSWORD=/run/secrets/mysecretpassword +``` + +Will set the environment variable `PASSWORD` based on the contents of the `/run/secrets/mysecretpassword` file. + +## Umask for running applications + +For all of our images we provide the ability to override the default umask settings for services started within the containers using the optional `-e UMASK=022` setting. +Keep in mind umask is not chmod it subtracts from permissions based on it's value it does not add. Please read up [here](https://en.wikipedia.org/wiki/Umask) before asking for support. + +## User / Group Identifiers + +When using volumes (`-v` flags) permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user `PUID` and group `PGID`. + +Ensure any volume directories on the host are owned by the same user you specify and any permissions issues will vanish like magic. + +In this instance `PUID=1000` and `PGID=1000`, to find yours use `id user` as below: + +``` + $ id username + uid=1000(dockeruser) gid=1000(dockergroup) groups=1000(dockergroup) +``` + + +  +## Application Setup + +Webui can be found at `:6500` + +## Support Info + +* Shell access whilst the container is running: `docker exec -it rtdclient /bin/bash` +* To monitor the logs of the container in realtime: `docker logs -f rdtclient` +* container version number + * `docker inspect -f '{{ index .Config.Labels "build_version" }}' rdtclient` +* image version number + * `docker inspect -f '{{ index .Config.Labels "build_version" }}' rogerfar/rdtclient` + +## Updating Info + +Most of our images are static, versioned, and require an image update and container recreation to update the app inside. Please consult the [Application Setup](#application-setup) section above to see if it is recommended for the image. + +Below are the instructions for updating containers: + +### Via Docker Compose +* Update all images: `docker-compose pull` + * or update a single image: `docker-compose pull rdtclient` +* Let compose update all containers as necessary: `docker-compose up -d` + * or update a single container: `docker-compose up -d rdtclient` +* You can also remove the old dangling images: `docker image prune` + +### Via Docker Run +* Update the image: `docker pull rogerfar/rdtclient` +* Stop the running container: `docker stop rdtclient` +* Delete the container: `docker rm rdtclient` +* Recreate a new container with the same docker run parameters as instructed above (if mapped correctly to a host folder, your `/data` folder and settings will be preserved) +* You can also remove the old dangling images: `docker image prune` + +### Via Watchtower auto-updater (only use if you don't remember the original parameters) +* Pull the latest image at its tag and replace it with the same env variables in one run: + ``` + docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + containrrr/watchtower \ + --run-once rtdclient + ``` +* You can also remove the old dangling images: `docker image prune` + +**Note:** We do not endorse the use of Watchtower as a solution to automated updates of existing Docker containers. In fact we generally discourage automated updates. However, this is a useful tool for one-time manual updates of containers where you have forgotten the original parameters. In the long term, we highly recommend using [Docker Compose](https://docs.linuxserver.io/general/docker-compose). + +### Image Update Notifications - Diun (Docker Image Update Notifier) +* We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported. + +## Building locally + +If you want to make local modifications to these images for development purposes or just to customize the logic: +``` +git clone https://github.com/ravensorb/docker-rdtclient.git +cd docker-rdtclient +docker build \ + --no-cache \ + --pull \ + -t rogerfar/rtd-client:latest . +``` + +The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` +``` +docker run --rm --privileged multiarch/qemu-user-static:register --reset +``` + +Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. diff --git a/docker-compose.yml b/docker-compose.yml index 6dc10f9..29e641d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,8 +3,8 @@ services: rdtclient: image: rogerfar/rdtclient volumes: - - 'C:/Downloads/:/data/downloads' - - 'C:/Docker/rdtclient/:/data/db' + - ./data/downloads:/data/downloads + - ./data/db:/data/db container_name: rdtclient restart: always logging: diff --git a/docker-publish.ps1 b/docker-publish.ps1 new file mode 100755 index 0000000..ef298c3 --- /dev/null +++ b/docker-publish.ps1 @@ -0,0 +1,50 @@ +#!/bin/pwsh +<# + .SYNOPSIS + Helper script to execute docker buildx + + .DESCRIPTION + Simplifies executing docker buildx for multi-architecture for the current Dockerfile + + .PARAMETER Version + Specifies the version number to take this image with (defaults to 'latest' only) + + .PARAMETER DockerAccount + The docker account to use to push the image + + .PARAMETER Platforms + The platforms to target for the image (defaults to linux/arm/v7,linux/arm64/v8,linux/amd64) + + .INPUTS + None. You cannot pipe objects to to this script. + + .OUTPUTS + None + + .EXAMPLE + PS> /docker-publish.ps1 + + .EXAMPLE + PS> ./docker-publish.ps1 -Version v1.7.4 + + .EXAMPLE + PS> ./docker-publish.ps1 -Platforms "linux/arms64/v8" + + #> +param( + [string]$Version = "", + [string]$DockerAccount = "rogerfar", + [string]$Platforms = "linux/arm/v7,linux/arm64/v8,linux/amd64" +) + +$imageName = "$($DockerAccount)/rdtclient" + +$dockerArgs = @( "buildx", "build", "--push", "--platform", $Platforms, "--tag", "$($imageName):latest", "." ) + +if (![string]::IsNullOrEmpty($Version)) { + $dockerArgs += @("--tag", "$($imageName):$($Version)" ) + $dockerApps += @("--build-arg", "VERSION=$($Version)" ) +} + +Write-Host "Generating docker image $imageName for $Platforms" +& docker $dockerArgs diff --git a/root/etc/cont-init.d/30-config b/root/etc/cont-init.d/30-config new file mode 100755 index 0000000..2dc3776 --- /dev/null +++ b/root/etc/cont-init.d/30-config @@ -0,0 +1,13 @@ +#!/usr/bin/with-contenv bash + +# cleanup pid if it exists +[[ -e /config/rtdclient.pid ]] && \ + rm -rf /config/rtdclient.pid + +[[ -e /data/rtdclient.pid ]] && \ + rm -rf /data/rtdclient.pid + +# permissions +echo "Setting permissions" +chown -R abc:abc \ + /app /data /config diff --git a/root/etc/services.d/rtdclient/run b/root/etc/services.d/rtdclient/run new file mode 100755 index 0000000..3c8d04d --- /dev/null +++ b/root/etc/services.d/rtdclient/run @@ -0,0 +1,13 @@ +#!/usr/bin/with-contenv bash + +if [ -n "${UMASK_SET}" ] && [ -z "${UMASK}" ]; then + echo -e "You are using a legacy method of defining umask\nplease update your environment variable from UMASK_SET to UMASK\nto keep the functionality after July 2021" + umask ${UMASK_SET} +fi + +echo "Changing to /app folder" +cd /app || exit + +echo "Starting rtdclient" +exec \ + s6-setuidgid abc dotnet RdtClient.Web.dll \ No newline at end of file