From 156169f4650f357a9ec042b7a09f90663235b3e0 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 03:32:11 +0000 Subject: [PATCH 01/15] Add multi-arch build/debug helper scripts --- dev/README.md | 3 +++ dev/build.386.sh | 7 +++++++ dev/build.amd64.sh | 8 ++++++++ dev/build.arm32v7.sh | 8 ++++++++ dev/build.arm64v8.sh | 8 ++++++++ dev/debug.386.sh | 7 +++++++ dev/debug.amd64.sh | 7 +++++++ dev/debug.arm32v7.sh | 14 ++++++++++++++ dev/debug.arm64v8.sh | 15 +++++++++++++++ dev/setup-build-env.sh | 16 ++++++++++++++++ test-debug.sh | 16 ++++++++++++++++ 11 files changed, 109 insertions(+) create mode 100644 dev/README.md create mode 100755 dev/build.386.sh create mode 100755 dev/build.amd64.sh create mode 100755 dev/build.arm32v7.sh create mode 100755 dev/build.arm64v8.sh create mode 100755 dev/debug.386.sh create mode 100755 dev/debug.amd64.sh create mode 100755 dev/debug.arm32v7.sh create mode 100755 dev/debug.arm64v8.sh create mode 100644 dev/setup-build-env.sh create mode 100644 test-debug.sh diff --git a/dev/README.md b/dev/README.md new file mode 100644 index 00000000..4d4c0a80 --- /dev/null +++ b/dev/README.md @@ -0,0 +1,3 @@ +# Dev Helper Scripts + +Unless you are making changes to the Dockerfile themselves, please ignore all the files here. \ No newline at end of file diff --git a/dev/build.386.sh b/dev/build.386.sh new file mode 100755 index 00000000..ef4b8c03 --- /dev/null +++ b/dev/build.386.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +docker buildx build -o type=docker,name=pms-386 --load --platform linux/386 -f ../Dockerfile.i386 .. diff --git a/dev/build.amd64.sh b/dev/build.amd64.sh new file mode 100755 index 00000000..929a5d50 --- /dev/null +++ b/dev/build.amd64.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +# https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined +docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-amd64 --platform linux/amd64 -f ../Dockerfile .. \ No newline at end of file diff --git a/dev/build.arm32v7.sh b/dev/build.arm32v7.sh new file mode 100755 index 00000000..9fe8d299 --- /dev/null +++ b/dev/build.arm32v7.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +# https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined +docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-armv7 --load --platform linux/arm/v7 -f ../Dockerfile.armv7 .. diff --git a/dev/build.arm64v8.sh b/dev/build.arm64v8.sh new file mode 100755 index 00000000..981f4da1 --- /dev/null +++ b/dev/build.arm64v8.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +# https://github.com/tianon/docker-brew-ubuntu-core/issues/183 +docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-arm64 --load --platform linux/arm64 -f ../Dockerfile.arm64 .. diff --git a/dev/debug.386.sh b/dev/debug.386.sh new file mode 100755 index 00000000..79abca5a --- /dev/null +++ b/dev/debug.386.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +docker run --rm --name pms-386 --platform linux/386 -e DEBUG=true -it pms-386:latest bash \ No newline at end of file diff --git a/dev/debug.amd64.sh b/dev/debug.amd64.sh new file mode 100755 index 00000000..743b30e4 --- /dev/null +++ b/dev/debug.amd64.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +docker run --rm --name pms-amd64 -e DEBUG=true -it pms-amd64:latest bash \ No newline at end of file diff --git a/dev/debug.arm32v7.sh b/dev/debug.arm32v7.sh new file mode 100755 index 00000000..7e11dc49 --- /dev/null +++ b/dev/debug.arm32v7.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +# Note - S6 overlay does NOT like it when you give it a tty under QEMU - do not run +# the container with "-it" rather, run it in background (so we get log output) then +# exec a bash process to enter the container. + +trap "trap - SIGTERM && docker stop pms-armv7" SIGINT SIGTERM EXIT +docker run --rm --name pms-armv7 --platform linux/arm/v7 -e DEBUG=true pms-armv7:latest & +sleep 5 +docker exec -it pms-armv7 bash diff --git a/dev/debug.arm64v8.sh b/dev/debug.arm64v8.sh new file mode 100755 index 00000000..48936220 --- /dev/null +++ b/dev/debug.arm64v8.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once + +# Note - S6 overlay does NOT like it when you give it a tty under QEMU - do not run +# the container with "-it" rather, run it in background (so we get log output) then +# exec a bash process to enter the container. + +trap "trap - SIGTERM && docker stop pms-armv7" SIGINT SIGTERM EXIT +docker run --rm --name pms-arm64 --platform linux/arm64 -e DEBUG=true pms-arm64:latest & +sleep 5 +docker exec -it pms-arm64 bash + diff --git a/dev/setup-build-env.sh b/dev/setup-build-env.sh new file mode 100644 index 00000000..3fb202c5 --- /dev/null +++ b/dev/setup-build-env.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is a one time setup script to setup the build env needed by the build and debug scripts. +# Assumes this is running on Linux (any distro) using (intel/amd). + +# Create a multi-arch buildx builder named PlexBuilder (if it doesn't exist) +if ! docker buildx inspect PlexBuilder 1> /dev/null 2>& 1; then + echo Creating PlexBuilder + # --use will make it automatically use this builder + docker buildx create --name PlexBuilder --platform linux/arm64,linux/arm/v7,linux/386 --use + # this is needed to register the arch-specific images with QEMU to be able to test + # these without native hardware + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes +fi diff --git a/test-debug.sh b/test-debug.sh new file mode 100644 index 00000000..e8ec9801 --- /dev/null +++ b/test-debug.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# This is just a helper script to quickly test local Dockerfile builds + +# build variations +#--build-arg AUTOUPDATE=false +#--build-arg URL=https://plex.tv//updater/packages/166139/file +#--build-arg TAG=public + +ID=$(docker build --build-arg AUTOUPDATE=TRUE --build-arg TAG=beta . 2>&1 | tee /dev/fd/2 build.log | tail -1 | awk '{ print $3}') + +# with persistent volume +docker run --rm -it -v testing-vol:/config:rw "$ID" +# without persistent volume +# docker run --rm -it -v "$ID" bash + From a09c55b0af6e280976900be37b36f650e695e86e Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 05:10:48 +0000 Subject: [PATCH 02/15] Upgrade to latest Ubuntu LTS (and fix arch base image) --- Dockerfile | 2 +- Dockerfile.arm64 | 2 +- Dockerfile.armv7 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6ee20fa3..e6e21c43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 ARG S6_OVERLAY_VERSION=v2.2.0.3 ARG S6_OVERLAY_ARCH=amd64 diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 5450840c..1dcf5a46 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM arm64v8/ubuntu:22.04 ARG S6_OVERLAY_VERSION=v2.2.0.3 ARG S6_OVERLAY_ARCH=aarch64 diff --git a/Dockerfile.armv7 b/Dockerfile.armv7 index 043a4aa2..e94edb07 100644 --- a/Dockerfile.armv7 +++ b/Dockerfile.armv7 @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM arm32v7/ubuntu:22.04 ARG S6_OVERLAY_VERSION=v2.2.0.3 ARG S6_OVERLAY_ARCH=armhf From 63c3c8c8484fcbde4de7168dee9de2c8b57982f1 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 14:20:23 +0000 Subject: [PATCH 03/15] Upgrade to s6-overlay v3 --- Dockerfile | 32 +++++++++++++------ Dockerfile.arm64 | 30 ++++++++++++----- Dockerfile.armv7 | 32 +++++++++++++------ Dockerfile.i386 | 31 +++++++++++++----- root/etc/cont-init.d/40-plex-first-run | 2 +- .../45-plex-hw-transcode-and-connected-tuner | 2 +- root/etc/cont-init.d/50-plex-update | 2 +- root/etc/services.d/plex/finish | 18 ----------- root/etc/services.d/plex/run | 2 +- root/etc/services.d/plex/timeout-finish | 1 - 10 files changed, 95 insertions(+), 57 deletions(-) delete mode 100644 root/etc/services.d/plex/finish delete mode 100644 root/etc/services.d/plex/timeout-finish diff --git a/Dockerfile b/Dockerfile index e6e21c43..34020e35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,13 @@ FROM ubuntu:22.04 -ARG S6_OVERLAY_VERSION=v2.2.0.3 -ARG S6_OVERLAY_ARCH=amd64 +ARG S6_OVERLAY_VERSION=v3.1.5.0 +ARG S6_OVERLAY_ARCH=x86_64 ARG PLEX_BUILD=linux-x86_64 ARG PLEX_DISTRO=debian ARG DEBIAN_FRONTEND="noninteractive" ARG INTEL_NEO_VERSION=20.48.18558 ARG INTEL_IGC_VERSION=1.0.5699 ARG INTEL_GMMLIB_VERSION=20.3.2 -ENV TERM="xterm" LANG="C.UTF-8" LC_ALL="C.UTF-8" - -ENTRYPOINT ["/init"] RUN \ # Update and get dependencies @@ -18,15 +15,19 @@ RUN \ apt-get install -y \ tzdata \ curl \ + xz-utils \ xmlstarlet \ uuid-runtime \ unrar \ && \ \ # Fetch and extract S6 overlay - curl -J -L -o /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C / --exclude='./bin' && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C /usr ./bin && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ + && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ + && \ \ # Add user useradd -U -d /config -s /bin/false plex && \ @@ -50,7 +51,18 @@ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414 VOLUME /config /transcode ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" + HOME="/config" \ + TZ="UTC" \ + \ + TERM="xterm" \ + LANG="C.UTF-8" \ + LC_ALL="C.UTF-8" \ + \ + S6_KEEP_ENV=1 \ + S6_SERVICES_GRACETIME=10000 \ + S6_KILL_GRACETIME=5000 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_BEHAVIOUR_IF_STAGE2_FAILS=2 ARG TAG=beta ARG URL= @@ -62,3 +74,5 @@ RUN \ /installBinary.sh HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 + +ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 1dcf5a46..c443f1e2 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -1,13 +1,10 @@ FROM arm64v8/ubuntu:22.04 -ARG S6_OVERLAY_VERSION=v2.2.0.3 +ARG S6_OVERLAY_VERSION=v3.1.5.0 ARG S6_OVERLAY_ARCH=aarch64 ARG PLEX_BUILD=linux-aarch64 ARG PLEX_DISTRO=debian ARG DEBIAN_FRONTEND="noninteractive" -ENV TERM="xterm" LANG="C.UTF-8" LC_ALL="C.UTF-8" - -ENTRYPOINT ["/init"] RUN \ # Update and get dependencies @@ -15,15 +12,19 @@ RUN \ apt-get install -y \ tzdata \ curl \ + xz-utils \ xmlstarlet \ uuid-runtime \ unrar \ && \ \ # Fetch and extract S6 overlay - curl -J -L -o /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C / --exclude='./bin' && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C /usr ./bin && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ + && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ + && \ \ # Add user useradd -U -d /config -s /bin/false plex && \ @@ -47,7 +48,18 @@ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414 VOLUME /config /transcode ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" + HOME="/config" \ + TZ="UTC" \ + \ + TERM="xterm" \ + LANG="C.UTF-8" \ + LC_ALL="C.UTF-8" \ + \ + S6_KEEP_ENV=1 \ + S6_SERVICES_GRACETIME=10000 \ + S6_KILL_GRACETIME=5000 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_BEHAVIOUR_IF_STAGE2_FAILS=2 ARG TAG=beta ARG URL= @@ -59,3 +71,5 @@ RUN \ /installBinary.sh HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 + +ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/Dockerfile.armv7 b/Dockerfile.armv7 index e94edb07..47d04024 100644 --- a/Dockerfile.armv7 +++ b/Dockerfile.armv7 @@ -1,13 +1,10 @@ FROM arm32v7/ubuntu:22.04 -ARG S6_OVERLAY_VERSION=v2.2.0.3 -ARG S6_OVERLAY_ARCH=armhf +ARG S6_OVERLAY_VERSION=v3.1.5.0 +ARG S6_OVERLAY_ARCH=arm ARG PLEX_BUILD=linux-armv7hf_neon ARG PLEX_DISTRO=debian ARG DEBIAN_FRONTEND="noninteractive" -ENV TERM="xterm" LANG="C.UTF-8" LC_ALL="C.UTF-8" - -ENTRYPOINT ["/init"] RUN \ # Update and get dependencies @@ -15,15 +12,19 @@ RUN \ apt-get install -y \ tzdata \ curl \ + xz-utils \ xmlstarlet \ uuid-runtime \ unrar \ && \ \ # Fetch and extract S6 overlay - curl -J -L -o /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C / --exclude='./bin' && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C /usr ./bin && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ + && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ + && \ \ # Add user useradd -U -d /config -s /bin/false plex && \ @@ -47,7 +48,18 @@ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414 VOLUME /config /transcode ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" + HOME="/config" \ + TZ="UTC" \ + \ + TERM="xterm" \ + LANG="C.UTF-8" \ + LC_ALL="C.UTF-8" \ + \ + S6_KEEP_ENV=1 \ + S6_SERVICES_GRACETIME=10000 \ + S6_KILL_GRACETIME=5000 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_BEHAVIOUR_IF_STAGE2_FAILS=2 ARG TAG=beta ARG URL= @@ -59,3 +71,5 @@ RUN \ /installBinary.sh HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 + +ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/Dockerfile.i386 b/Dockerfile.i386 index 3ed88af8..e079a44d 100644 --- a/Dockerfile.i386 +++ b/Dockerfile.i386 @@ -1,13 +1,10 @@ FROM i386/ubuntu:18.04 -ARG S6_OVERLAY_VERSION=v2.2.0.3 -ARG S6_OVERLAY_ARCH=x86 +ARG S6_OVERLAY_VERSION=v3.1.5.0 +ARG S6_OVERLAY_ARCH=i686 ARG PLEX_BUILD=linux-x86 ARG PLEX_DISTRO=debian ARG DEBIAN_FRONTEND="noninteractive" -ENV TERM="xterm" LANG="C.UTF-8" LC_ALL="C.UTF-8" - -ENTRYPOINT ["/init"] RUN \ # Update and get dependencies @@ -15,14 +12,19 @@ RUN \ apt-get install -y \ tzdata \ curl \ + xz-utils \ xmlstarlet \ uuid-runtime \ unrar \ && \ \ # Fetch and extract S6 overlay - curl -J -L -o /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz && \ - tar xzf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.gz -C / && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ + && \ + curl -L -s \ + "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ + && \ \ # Add user useradd -U -d /config -s /bin/false plex && \ @@ -46,7 +48,18 @@ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414 VOLUME /config /transcode ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" + HOME="/config" \ + TZ="UTC" \ + \ + TERM="xterm" \ + LANG="C.UTF-8" \ + LC_ALL="C.UTF-8" \ + \ + S6_KEEP_ENV=1 \ + S6_SERVICES_GRACETIME=10000 \ + S6_KILL_GRACETIME=5000 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_BEHAVIOUR_IF_STAGE2_FAILS=2 ARG TAG=beta ARG URL= @@ -58,3 +71,5 @@ RUN \ /installBinary.sh HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 + +ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/root/etc/cont-init.d/40-plex-first-run b/root/etc/cont-init.d/40-plex-first-run index 4275929c..c8c0bc1e 100755 --- a/root/etc/cont-init.d/40-plex-first-run +++ b/root/etc/cont-init.d/40-plex-first-run @@ -1,4 +1,4 @@ -#!/usr/bin/with-contenv bash +#!/bin/bash # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then diff --git a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner b/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner index d09a129e..06ed42a1 100755 --- a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner +++ b/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner @@ -1,4 +1,4 @@ -#!/usr/bin/with-contenv bash +#!/bin/bash # Check to make sure the devices exists. If not, exit as there is nothing for us to do if [ ! -e /dev/dri ] && [ ! -e /dev/dvb ]; then diff --git a/root/etc/cont-init.d/50-plex-update b/root/etc/cont-init.d/50-plex-update index dbaec382..5dada1a9 100755 --- a/root/etc/cont-init.d/50-plex-update +++ b/root/etc/cont-init.d/50-plex-update @@ -1,4 +1,4 @@ -#!/usr/bin/with-contenv bash +#!/bin/bash # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then diff --git a/root/etc/services.d/plex/finish b/root/etc/services.d/plex/finish deleted file mode 100644 index f83c58d6..00000000 --- a/root/etc/services.d/plex/finish +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/with-contenv bash -# Copied from the init.d stop method from non-Dockerized Plex. - -echo "Stopping Plex Media Server." - -# Ask nicely -pids="$(ps -ef | grep 'Plex Media Server' | grep -v grep | awk '{print $2}')" -kill -15 $pids - -sleep 5 - -# Stuck -pids="$(ps -ef | grep /usr/lib/plexmediaserver | grep -v grep | awk '{print $2}')" - -if [ "$pids" != "" ]; then - kill -9 $pids - sleep 2 -fi diff --git a/root/etc/services.d/plex/run b/root/etc/services.d/plex/run index 5dfa8853..eb7eeeae 100755 --- a/root/etc/services.d/plex/run +++ b/root/etc/services.d/plex/run @@ -1,4 +1,4 @@ -#!/usr/bin/with-contenv bash +#!/bin/bash echo "Starting Plex Media Server." home="$(echo ~plex)" diff --git a/root/etc/services.d/plex/timeout-finish b/root/etc/services.d/plex/timeout-finish deleted file mode 100644 index e002b362..00000000 --- a/root/etc/services.d/plex/timeout-finish +++ /dev/null @@ -1 +0,0 @@ -8000 From b0ae80dbbbfcf12cf922cba8d9dba0f40927b8b4 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 15:00:51 +0000 Subject: [PATCH 04/15] Run shellcheck, handle all warnings --- root/etc/cont-init.d/40-plex-first-run | 24 +++++++++---------- .../45-plex-hw-transcode-and-connected-tuner | 4 ++-- root/etc/cont-init.d/50-plex-update | 3 ++- root/etc/services.d/plex/run | 8 ++++--- root/healthcheck.sh | 8 ++++--- root/installBinary.sh | 2 +- root/plex-common.sh | 20 ++++++++++------ 7 files changed, 40 insertions(+), 29 deletions(-) diff --git a/root/etc/cont-init.d/40-plex-first-run b/root/etc/cont-init.d/40-plex-first-run index c8c0bc1e..ad2c8865 100755 --- a/root/etc/cont-init.d/40-plex-first-run +++ b/root/etc/cont-init.d/40-plex-first-run @@ -21,21 +21,21 @@ function setPref { local value="$2" count="$(xmlstarlet sel -t -v "count(/Preferences/@${key})" "${prefFile}")" - count=$(($count + 0)) - if [[ $count > 0 ]]; then + if [[ $count -gt 0 ]]; then xmlstarlet ed --inplace --update "/Preferences/@${key}" -v "${value}" "${prefFile}" else xmlstarlet ed --inplace --insert "/Preferences" --type attr -n "${key}" -v "${value}" "${prefFile}" fi } -home="$(echo ~plex)" +home=~plex +# shellcheck source=/dev/null [ -f /etc/default/plexmediaserver ] && . /etc/default/plexmediaserver pmsApplicationSupportDir="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR:-${home}/Library/Application Support}" prefFile="${pmsApplicationSupportDir}/Plex Media Server/Preferences.xml" # Setup user/group ids -if [ ! -z "${PLEX_UID}" ]; then +if [ -n "${PLEX_UID}" ]; then if [ ! "$(id -u plex)" -eq "${PLEX_UID}" ]; then # usermod likes to chown the home directory, so create a new one and use that @@ -57,7 +57,7 @@ if [ ! -z "${PLEX_UID}" ]; then fi fi -if [ ! -z "${PLEX_GID}" ]; then +if [ -n "${PLEX_GID}" ]; then if [ ! "$(id -g plex)" -eq "${PLEX_GID}" ]; then groupmod -o -g "${PLEX_GID}" plex fi @@ -67,10 +67,10 @@ fi if [ "${CHANGE_CONFIG_DIR_OWNERSHIP,,}" = "true" ]; then if [ -f "${prefFile}" ]; then if [ ! "$(stat -c %u "${prefFile}")" = "$(id -u plex)" ]; then - find /config \! \( -uid $(id -u plex) -gid $(id -g plex) \) -print0 | xargs -0 chown -h plex:plex + find /config \! \( -uid "$(id -u plex)" -gid "$(id -g plex)" \) -print0 | xargs -0 chown -h plex:plex fi else - find /config \! \( -uid $(id -u plex) -gid $(id -g plex) \) -print0 | xargs -0 chown -h plex:plex + find /config \! \( -uid "$(id -u plex)" -gid "$(id -g plex)" \) -print0 | xargs -0 chown -h plex:plex fi chown -R plex:plex /transcode fi @@ -101,12 +101,12 @@ fi # Get server token and only turn claim token into server token if we have former but not latter. token="$(getPref "PlexOnlineToken")" if [ -z "${PLEX_CLAIM}" ] && [ -f "${PLEX_CLAIM_FILE}" ]; then - PLEX_CLAIM=$(cat ${PLEX_CLAIM_FILE}) + PLEX_CLAIM=$(cat "${PLEX_CLAIM_FILE}") fi -if [ ! -z "${PLEX_CLAIM}" ] && [ -z "${token}" ]; then +if [ -n "${PLEX_CLAIM}" ] && [ -z "${token}" ]; then echo "Attempting to obtain server token from claim token" loginInfo="$(curl -X POST \ - -H 'X-Plex-Client-Identifier: '${clientId} \ + -H 'X-Plex-Client-Identifier: '"${clientId}" \ -H 'X-Plex-Product: Plex Media Server'\ -H 'X-Plex-Version: 1.1' \ -H 'X-Plex-Provides: server' \ @@ -123,11 +123,11 @@ if [ ! -z "${PLEX_CLAIM}" ] && [ -z "${token}" ]; then fi fi -if [ ! -z "${ADVERTISE_IP}" ]; then +if [ -n "${ADVERTISE_IP}" ]; then setPref "customConnections" "${ADVERTISE_IP}" fi -if [ ! -z "${ALLOWED_NETWORKS}" ]; then +if [ -n "${ALLOWED_NETWORKS}" ]; then setPref "allowedNetworks" "${ALLOWED_NETWORKS}" fi diff --git a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner b/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner index 06ed42a1..edf5ab17 100755 --- a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner +++ b/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner @@ -22,10 +22,10 @@ do fi # If plex user isn't part of this group, add them - if [ ! $(getent group "${CURRENT_GROUP}" | grep &>/dev/null plex) ]; then + if ! getent group "${CURRENT_GROUP}" | grep -q plex; then usermod -a -G "${CURRENT_GROUP}" plex fi - GROUP_COUNT=$(($GROUP_COUNT + 1)) + GROUP_COUNT=$((GROUP_COUNT + 1)) done diff --git a/root/etc/cont-init.d/50-plex-update b/root/etc/cont-init.d/50-plex-update index 5dada1a9..525e83a9 100755 --- a/root/etc/cont-init.d/50-plex-update +++ b/root/etc/cont-init.d/50-plex-update @@ -4,7 +4,7 @@ if [ "${DEBUG,,}" = "true" ]; then set -x fi - +# shellcheck source=../../plex-common.sh . /plex-common.sh function getPref { @@ -14,6 +14,7 @@ function getPref { } # Get token +# shellcheck source=/dev/null [ -f /etc/default/plexmediaserver ] && . /etc/default/plexmediaserver pmsApplicationSupportDir="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR:-${HOME}/Library/Application Support}" prefFile="${pmsApplicationSupportDir}/Plex Media Server/Preferences.xml" diff --git a/root/etc/services.d/plex/run b/root/etc/services.d/plex/run index eb7eeeae..7ce02d22 100755 --- a/root/etc/services.d/plex/run +++ b/root/etc/services.d/plex/run @@ -1,14 +1,16 @@ #!/bin/bash echo "Starting Plex Media Server." -home="$(echo ~plex)" +home=~plex export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR:-${home}/Library/Application Support}" export PLEX_MEDIA_SERVER_HOME=/usr/lib/plexmediaserver export PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS=6 export PLEX_MEDIA_SERVER_INFO_VENDOR=Docker export PLEX_MEDIA_SERVER_INFO_DEVICE="Docker Container" -export PLEX_MEDIA_SERVER_INFO_MODEL=$(uname -m) -export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION=$(uname -r) +PLEX_MEDIA_SERVER_INFO_MODEL=$(uname -m) +export PLEX_MEDIA_SERVER_INFO_MODEL +PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION=$(uname -r) +export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION if [ ! -d "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" ]; then /bin/mkdir -p "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" diff --git a/root/healthcheck.sh b/root/healthcheck.sh index 038e8c78..c48a0891 100755 --- a/root/healthcheck.sh +++ b/root/healthcheck.sh @@ -1,7 +1,9 @@ -#!/bin/sh -e +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' TARGET=localhost -CURL_OPTS="--connect-timeout 15 --max-time 100 --silent --show-error --fail" +CURL_OPTS=(--connect-timeout 15 --max-time 100 --silent --show-error --fail) -curl ${CURL_OPTS} "http://${TARGET}:32400/identity" >/dev/null +curl "${CURL_OPTS[@]}" "http://${TARGET}:32400/identity" >/dev/null diff --git a/root/installBinary.sh b/root/installBinary.sh index a3a62a49..ef26aa83 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -6,7 +6,7 @@ addVarToConf "version" "${TAG}" addVarToConf "plex_build" "${PLEX_BUILD}" addVarToConf "plex_distro" "${PLEX_DISTRO}" -if [ ! -z "${URL}" ]; then +if [ -n "${URL}" ]; then echo "Attempting to install from URL: ${URL}" installFromRawUrl "${URL}" elif [ "${TAG}" != "beta" ] && [ "${TAG}" != "public" ]; then diff --git a/root/plex-common.sh b/root/plex-common.sh index 9c41132e..1c55f425 100755 --- a/root/plex-common.sh +++ b/root/plex-common.sh @@ -5,17 +5,18 @@ CONT_CONF_FILE="/version.txt" function addVarToConf { local variable="$1" local value="$2" - if [ ! -z "${variable}" ]; then - echo ${variable}=${value} >> ${CONT_CONF_FILE} + if [ -n "${variable}" ]; then + echo "$variable"="$value" >> $CONT_CONF_FILE fi } function readVarFromConf { local variable="$1" local -n readVarFromConf_value=$2 - if [ ! -z "${variable}" ]; then - readVarFromConf_value="$(grep -w ${variable} ${CONT_CONF_FILE} | cut -d'=' -f2 | tail -n 1)" + if [ -n "${variable}" ]; then + readVarFromConf_value="$(grep -w "$variable" $CONT_CONF_FILE | cut -d'=' -f2 | tail -n 1)" else + # shellcheck disable=SC2034 readVarFromConf_value=NULL fi } @@ -26,9 +27,9 @@ function getVersionInfo { local -n getVersionInfo_remoteVersion=$3 local -n getVersionInfo_remoteFile=$4 - local channel + local channel= local tokenNeeded=1 - if [ ! -z "${PLEX_UPDATE_CHANNEL}" ] && [ "${PLEX_UPDATE_CHANNEL}" > 0 ]; then + if [ -n "${PLEX_UPDATE_CHANNEL}" ] && [ "${PLEX_UPDATE_CHANNEL}" -gt 0 ]; then channel="${PLEX_UPDATE_CHANNEL}" elif [ "${version,,}" = "beta" ]; then channel=8 @@ -40,6 +41,8 @@ function getVersionInfo { fi # Read container architecture info from file created when building Docker image + local plexBuild= + local plexDistro= readVarFromConf "plex_build" plexBuild readVarFromConf "plex_distro" plexDistro @@ -48,10 +51,13 @@ function getVersionInfo { url="${url}&X-Plex-Token=${token}" fi - local versionInfo="$(curl -s "${url}")" + local versionInfo= + versionInfo="$(curl -s "${url}")" # Get update info from the XML. Note: This could countain multiple updates when user specifies an exact version with the lowest first, so we'll use first always. + # shellcheck disable=SC2034 getVersionInfo_remoteVersion=$(echo "${versionInfo}" | sed -n 's/.*Release.*version="\([^"]*\)".*/\1/p') + # shellcheck disable=SC2034 getVersionInfo_remoteFile=$(echo "${versionInfo}" | sed -n 's/.*file="\([^"]*\)".*/\1/p') } From d5044404d8114bcee28c933e910d43726781630f Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 15:13:15 +0000 Subject: [PATCH 05/15] Add 'strict' mode to bash scripts --- root/etc/cont-init.d/40-plex-first-run | 12 ++++++++++++ .../45-plex-hw-transcode-and-connected-tuner | 4 ++++ root/etc/cont-init.d/50-plex-update | 5 +++++ root/installBinary.sh | 4 ++++ root/plex-common.sh | 4 ++++ 5 files changed, 29 insertions(+) diff --git a/root/etc/cont-init.d/40-plex-first-run b/root/etc/cont-init.d/40-plex-first-run index ad2c8865..7741a0a9 100755 --- a/root/etc/cont-init.d/40-plex-first-run +++ b/root/etc/cont-init.d/40-plex-first-run @@ -1,4 +1,16 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# set defaults +DEBUG=${DEBUG:-} +PLEX_UID=${PLEX_UID:-} +PLEX_GID=${PLEX_GID:-} +CHANGE_CONFIG_DIR_OWNERSHIP=${CHANGE_CONFIG_DIR_OWNERSHIP:-} +PLEX_CLAIM=${PLEX_CLAIM:-} +PLEX_CLAIM_FILE=${PLEX_CLAIM_FILE:-} +ADVERTISE_IP=${ADVERTISE_IP:-} +ALLOWED_NETWORKS=${ALLOWED_NETWORKS:-} # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then diff --git a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner b/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner index edf5ab17..143cf879 100755 --- a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner +++ b/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner @@ -1,4 +1,8 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +DEBUG=${DEBUG:-} # Check to make sure the devices exists. If not, exit as there is nothing for us to do if [ ! -e /dev/dri ] && [ ! -e /dev/dvb ]; then diff --git a/root/etc/cont-init.d/50-plex-update b/root/etc/cont-init.d/50-plex-update index 525e83a9..3fa9cc02 100755 --- a/root/etc/cont-init.d/50-plex-update +++ b/root/etc/cont-init.d/50-plex-update @@ -1,4 +1,9 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +DEBUG=${DEBUG:-} +TAG=${TAG:-} # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then diff --git a/root/installBinary.sh b/root/installBinary.sh index ef26aa83..52a42a49 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -1,4 +1,6 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' . /plex-common.sh @@ -10,6 +12,8 @@ if [ -n "${URL}" ]; then echo "Attempting to install from URL: ${URL}" installFromRawUrl "${URL}" elif [ "${TAG}" != "beta" ] && [ "${TAG}" != "public" ]; then + remoteVersion= + remoteFile= getVersionInfo "${TAG}" "" remoteVersion remoteFile if [ -z "${remoteVersion}" ] || [ -z "${remoteFile}" ]; then diff --git a/root/plex-common.sh b/root/plex-common.sh index 1c55f425..86c2aa59 100755 --- a/root/plex-common.sh +++ b/root/plex-common.sh @@ -1,4 +1,8 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +PLEX_UPDATE_CHANNEL=${PLEX_UPDATE_CHANNEL:-} CONT_CONF_FILE="/version.txt" From c5f4f70276f79d116466c466fff3a899c3dd5d1f Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 16:26:20 +0000 Subject: [PATCH 06/15] Move scripts and dynamically link up services.d/cont-init.d --- .../40-plex-first-run => plex/plex-first-run} | 0 .../plex-hw-transcode-and-connected-tuner} | 0 root/etc/{cont-init.d/50-plex-update => plex/plex-update} | 0 root/etc/{services.d/plex/run => plex/service.plex.run} | 0 root/installBinary.sh | 8 ++++++++ 5 files changed, 8 insertions(+) rename root/etc/{cont-init.d/40-plex-first-run => plex/plex-first-run} (100%) rename root/etc/{cont-init.d/45-plex-hw-transcode-and-connected-tuner => plex/plex-hw-transcode-and-connected-tuner} (100%) rename root/etc/{cont-init.d/50-plex-update => plex/plex-update} (100%) rename root/etc/{services.d/plex/run => plex/service.plex.run} (100%) diff --git a/root/etc/cont-init.d/40-plex-first-run b/root/etc/plex/plex-first-run similarity index 100% rename from root/etc/cont-init.d/40-plex-first-run rename to root/etc/plex/plex-first-run diff --git a/root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner b/root/etc/plex/plex-hw-transcode-and-connected-tuner similarity index 100% rename from root/etc/cont-init.d/45-plex-hw-transcode-and-connected-tuner rename to root/etc/plex/plex-hw-transcode-and-connected-tuner diff --git a/root/etc/cont-init.d/50-plex-update b/root/etc/plex/plex-update similarity index 100% rename from root/etc/cont-init.d/50-plex-update rename to root/etc/plex/plex-update diff --git a/root/etc/services.d/plex/run b/root/etc/plex/service.plex.run similarity index 100% rename from root/etc/services.d/plex/run rename to root/etc/plex/service.plex.run diff --git a/root/installBinary.sh b/root/installBinary.sh index 52a42a49..8634745e 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -8,6 +8,14 @@ addVarToConf "version" "${TAG}" addVarToConf "plex_build" "${PLEX_BUILD}" addVarToConf "plex_distro" "${PLEX_DISTRO}" +# Setup common services +echo "Creating services" +mkdir -p /etc/services.d/plex ; ln -s /etc/plex/service.plex.run /etc/services.d/plex/run +mkdir -p /etc/cont-init.d +ln -s /etc/plex/plex-first-run /etc/cont-init.d/000-plex-first-run +ln -s /etc/plex/plex-hw-transcode-and-connected-tuner /etc/cont-init.d/010-plex-hw-transcode-and-connected-tuner +ln -s /etc/plex/plex-update /etc/cont-init.d/020-plex-update + if [ -n "${URL}" ]; then echo "Attempting to install from URL: ${URL}" installFromRawUrl "${URL}" From c5da1c44b2adc8e94987ca04ca5637faa4487093 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 17:29:03 +0000 Subject: [PATCH 07/15] Autoupdate functionality --- Dockerfile | 11 ++++++---- Dockerfile.arm64 | 11 ++++++---- Dockerfile.armv7 | 11 ++++++---- Dockerfile.i386 | 11 ++++++---- dev/README.md | 2 +- dev/build.386.sh | 2 +- dev/build.amd64.sh | 2 +- dev/build.arm32v7.sh | 2 +- dev/build.arm64v8.sh | 2 +- dev/debug.arm64v8.sh | 3 +-- dev/setup-build-env.sh | 0 root/etc/plex/plex-install | 23 +++++++++++++++++++ root/etc/plex/plex-update | 33 ++++++++++++++++------------ root/etc/plex/service.cron.run | 15 +++++++++++++ root/etc/plex/service.plex.run | 25 +++++++++++---------- root/installBinary.sh | 16 +++++++++++++- root/plex-common.sh | 40 ++++++++++++++++++++++++++++------ root/plex-envvars | 14 ++++++++++++ root/plex_service.sh | 7 ------ 19 files changed, 167 insertions(+), 63 deletions(-) mode change 100644 => 100755 dev/setup-build-env.sh create mode 100755 root/etc/plex/plex-install create mode 100755 root/etc/plex/service.cron.run create mode 100755 root/plex-envvars delete mode 100755 root/plex_service.sh diff --git a/Dockerfile b/Dockerfile index 34020e35..22c5ee4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,7 @@ RUN \ xmlstarlet \ uuid-runtime \ unrar \ + cron \ && \ \ # Fetch and extract S6 overlay @@ -50,7 +51,12 @@ RUN \ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp VOLUME /config /transcode -ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ +ARG AUTOUPDATE=false +ARG TAG=beta +ARG URL= + +ENV TAG=${TAG} \ + CHANGE_CONFIG_DIR_OWNERSHIP="true" \ HOME="/config" \ TZ="UTC" \ \ @@ -64,9 +70,6 @@ ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 -ARG TAG=beta -ARG URL= - COPY root/ / RUN \ diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index c443f1e2..4eaf1bcc 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -16,6 +16,7 @@ RUN \ xmlstarlet \ uuid-runtime \ unrar \ + cron \ && \ \ # Fetch and extract S6 overlay @@ -47,7 +48,12 @@ RUN \ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp VOLUME /config /transcode -ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ +ARG AUTOUPDATE=false +ARG TAG=beta +ARG URL= + +ENV TAG=${TAG} \ + CHANGE_CONFIG_DIR_OWNERSHIP="true" \ HOME="/config" \ TZ="UTC" \ \ @@ -61,9 +67,6 @@ ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 -ARG TAG=beta -ARG URL= - COPY root/ / RUN \ diff --git a/Dockerfile.armv7 b/Dockerfile.armv7 index 47d04024..a0e45875 100644 --- a/Dockerfile.armv7 +++ b/Dockerfile.armv7 @@ -16,6 +16,7 @@ RUN \ xmlstarlet \ uuid-runtime \ unrar \ + cron \ && \ \ # Fetch and extract S6 overlay @@ -47,7 +48,12 @@ RUN \ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp VOLUME /config /transcode -ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ +ARG AUTOUPDATE=false +ARG TAG=beta +ARG URL= + +ENV TAG=${TAG} \ + CHANGE_CONFIG_DIR_OWNERSHIP="true" \ HOME="/config" \ TZ="UTC" \ \ @@ -61,9 +67,6 @@ ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 -ARG TAG=beta -ARG URL= - COPY root/ / RUN \ diff --git a/Dockerfile.i386 b/Dockerfile.i386 index e079a44d..591dc1ae 100644 --- a/Dockerfile.i386 +++ b/Dockerfile.i386 @@ -16,6 +16,7 @@ RUN \ xmlstarlet \ uuid-runtime \ unrar \ + cron \ && \ \ # Fetch and extract S6 overlay @@ -47,7 +48,12 @@ RUN \ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp VOLUME /config /transcode -ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ +ARG AUTOUPDATE=false +ARG TAG=beta +ARG URL= + +ENV TAG=${TAG} \ + CHANGE_CONFIG_DIR_OWNERSHIP="true" \ HOME="/config" \ TZ="UTC" \ \ @@ -61,9 +67,6 @@ ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 -ARG TAG=beta -ARG URL= - COPY root/ / RUN \ diff --git a/dev/README.md b/dev/README.md index 4d4c0a80..5f366f6e 100644 --- a/dev/README.md +++ b/dev/README.md @@ -1,3 +1,3 @@ # Dev Helper Scripts -Unless you are making changes to the Dockerfile themselves, please ignore all the files here. \ No newline at end of file +Unless you are making changes to the Dockerfile themselves, please ignore all the files here. In fact, your environment may be very different and these scripts may not work at all. They are provided only as a reference/starting point so you don't have to start from scratch. Heavy customizations are likely. \ No newline at end of file diff --git a/dev/build.386.sh b/dev/build.386.sh index ef4b8c03..23274d12 100755 --- a/dev/build.386.sh +++ b/dev/build.386.sh @@ -4,4 +4,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once -docker buildx build -o type=docker,name=pms-386 --load --platform linux/386 -f ../Dockerfile.i386 .. +docker buildx build -o type=docker,name=pms-386 --load --platform linux/386 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile.i386 .. diff --git a/dev/build.amd64.sh b/dev/build.amd64.sh index 929a5d50..73775ebc 100755 --- a/dev/build.amd64.sh +++ b/dev/build.amd64.sh @@ -5,4 +5,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once # https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined -docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-amd64 --platform linux/amd64 -f ../Dockerfile .. \ No newline at end of file +docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-amd64 --platform linux/amd64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.arm32v7.sh b/dev/build.arm32v7.sh index 9fe8d299..8b7b2363 100755 --- a/dev/build.arm32v7.sh +++ b/dev/build.arm32v7.sh @@ -5,4 +5,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once # https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined -docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-armv7 --load --platform linux/arm/v7 -f ../Dockerfile.armv7 .. +docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-armv7 --load --platform linux/arm/v7 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile.armv7 .. diff --git a/dev/build.arm64v8.sh b/dev/build.arm64v8.sh index 981f4da1..8cb69ffa 100755 --- a/dev/build.arm64v8.sh +++ b/dev/build.arm64v8.sh @@ -5,4 +5,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once # https://github.com/tianon/docker-brew-ubuntu-core/issues/183 -docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-arm64 --load --platform linux/arm64 -f ../Dockerfile.arm64 .. +docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-arm64 --load --platform linux/arm64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile.arm64 .. diff --git a/dev/debug.arm64v8.sh b/dev/debug.arm64v8.sh index 48936220..3ff32324 100755 --- a/dev/debug.arm64v8.sh +++ b/dev/debug.arm64v8.sh @@ -8,8 +8,7 @@ IFS=$'\n\t' # the container with "-it" rather, run it in background (so we get log output) then # exec a bash process to enter the container. -trap "trap - SIGTERM && docker stop pms-armv7" SIGINT SIGTERM EXIT +trap "trap - SIGTERM && docker stop pms-arm64" SIGINT SIGTERM EXIT docker run --rm --name pms-arm64 --platform linux/arm64 -e DEBUG=true pms-arm64:latest & sleep 5 docker exec -it pms-arm64 bash - diff --git a/dev/setup-build-env.sh b/dev/setup-build-env.sh old mode 100644 new mode 100755 diff --git a/root/etc/plex/plex-install b/root/etc/plex/plex-install new file mode 100755 index 00000000..8f7d0f83 --- /dev/null +++ b/root/etc/plex/plex-install @@ -0,0 +1,23 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +DEBUG=${DEBUG:-} + +# If we are debugging, enable trace +if [ "${DEBUG,,}" = "true" ]; then + set -x +fi + +# shellcheck source=../../plex-common.sh +. /plex-common.sh + +CACHED_URL= +[[ -r /config/install/plexmediaserver.url ]] && CACHED_URL=$(< /config/install/plexmediaserver.url) +if [ -n "$CACHED_URL" ] && [ -f /config/install/plexmediaserver.deb ]; then + echo "Installing previously downloaded plex version..." + installFromRawUrl "$CACHED_URL" +else + echo "Downloading latest plex version..." + exec /etc/plex/plex-update +fi diff --git a/root/etc/plex/plex-update b/root/etc/plex/plex-update index 3fa9cc02..5ccda7dc 100755 --- a/root/etc/plex/plex-update +++ b/root/etc/plex/plex-update @@ -32,20 +32,12 @@ else installedVersion="none" fi -# Read set version -readVarFromConf "version" versionToInstall -if [ -z "${versionToInstall}" ]; then - echo "No version specified in install. Broken image" - exit 1 -fi - -# Short-circuit test of version before remote check to see if it's already installed. -if [ "${versionToInstall}" = "${installedVersion}" ]; then - exit 0 -fi # Get updated version number -getVersionInfo "${versionToInstall}" "${token}" remoteVersion remoteFile +remoteVersion= +remoteFile= +remoteFileHashSha256= +getVersionInfo "${TAG}" "${token}" remoteVersion remoteFile remoteFileHashSha256 if [ -z "${remoteVersion}" ] || [ -z "${remoteFile}" ]; then echo "Could not get update version" @@ -54,9 +46,22 @@ fi # Check if there's no update required if [ "${remoteVersion}" = "${installedVersion}" ]; then + echo "$(date) Update check: no updates found." exit 0 fi # Do update process -echo "Attempting to upgrade to: ${remoteVersion}" -installFromUrl "${remoteFile}" +wasrunning=false +echo "$(date) Attempting to upgrade to: ${remoteVersion}" +if [ -d "/run/s6/legacy-services/plex" ]; then + wasrunning=true + echo "$(date) Bringing down Plex Media Server..." + s6-svc -wD -d /run/s6/legacy-services/plex +fi +echo "$(date) Downloading and installing..." +installFromUrl "${remoteFile}" "${remoteFileHashSha256}" +if [ "$wasrunning" = true ]; then + echo "$(date) Bringing up Plex Media Server..." + s6-svc -wU -u /run/s6/legacy-services/plex +fi +echo "$(date) Plex Successfully Updated!" diff --git a/root/etc/plex/service.cron.run b/root/etc/plex/service.cron.run new file mode 100755 index 00000000..577ce1a4 --- /dev/null +++ b/root/etc/plex/service.cron.run @@ -0,0 +1,15 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +DEBUG=${DEBUG:-} + +# If we are debugging, enable trace +if [ "${DEBUG,,}" = "true" ]; then + set -x +fi + +# shellcheck source=../../plex-envvars +. /plex-envvars +printenv > /etc/environment +exec cron -f \ No newline at end of file diff --git a/root/etc/plex/service.plex.run b/root/etc/plex/service.plex.run index 7ce02d22..a5e4d487 100755 --- a/root/etc/plex/service.plex.run +++ b/root/etc/plex/service.plex.run @@ -1,20 +1,23 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' -echo "Starting Plex Media Server." -home=~plex -export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR:-${home}/Library/Application Support}" -export PLEX_MEDIA_SERVER_HOME=/usr/lib/plexmediaserver -export PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS=6 -export PLEX_MEDIA_SERVER_INFO_VENDOR=Docker -export PLEX_MEDIA_SERVER_INFO_DEVICE="Docker Container" -PLEX_MEDIA_SERVER_INFO_MODEL=$(uname -m) -export PLEX_MEDIA_SERVER_INFO_MODEL -PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION=$(uname -r) -export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION +DEBUG=${DEBUG:-} + +# If we are debugging, enable trace +if [ "${DEBUG,,}" = "true" ]; then + set -x +fi + +# shellcheck source=../../plex-envvars +. /plex-envvars if [ ! -d "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" ]; then /bin/mkdir -p "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" chown plex:plex "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" fi +echo "$(date) Starting Plex Media Server $(dpkg-query -W -f='${Version}' plexmediaserver)" +echo + exec s6-setuidgid plex /usr/lib/plexmediaserver/Plex\ Media\ Server diff --git a/root/installBinary.sh b/root/installBinary.sh index 8634745e..041ed9e1 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -15,7 +15,20 @@ mkdir -p /etc/cont-init.d ln -s /etc/plex/plex-first-run /etc/cont-init.d/000-plex-first-run ln -s /etc/plex/plex-hw-transcode-and-connected-tuner /etc/cont-init.d/010-plex-hw-transcode-and-connected-tuner ln -s /etc/plex/plex-update /etc/cont-init.d/020-plex-update - +if [ "${AUTOUPDATE,,}" = 'true' ]; then + echo "AUTOUPDATE requested, setting up cron service and scheduling plex-update" + mkdir -p /etc/services.d/cron ; ln -s /etc/plex/service.cron.run /etc/services.d/cron/run + # Specify bash as shell, add S6 commands to PATH + echo "SHELL=/bin/bash" > /etc/crontab + echo "$(env | grep PATH):/command" >> /etc/crontab + # Specify cron job: be nice to Plex servers - space out updates at 4:00am over 30m window + echo "0 4 * * * root perl -le 'sleep rand 30' ; /etc/plex/plex-update > /proc/1/fd/1 2>&1" >> /etc/crontab + echo "Removing plex-update from cont-init.d" + rm /etc/cont-init.d/020-plex-update + echo "Adding plex-install to cont-init.d" + ln -s /etc/plex/plex-install /etc/cont-init.d/099-plex-install + exit 0 +fi if [ -n "${URL}" ]; then echo "Attempting to install from URL: ${URL}" installFromRawUrl "${URL}" @@ -31,4 +44,5 @@ elif [ "${TAG}" != "beta" ] && [ "${TAG}" != "public" ]; then echo "Attempting to install: ${remoteVersion}" installFromUrl "${remoteFile}" + rm -rf /config/install fi diff --git a/root/plex-common.sh b/root/plex-common.sh index 86c2aa59..de8869b6 100755 --- a/root/plex-common.sh +++ b/root/plex-common.sh @@ -63,24 +63,50 @@ function getVersionInfo { getVersionInfo_remoteVersion=$(echo "${versionInfo}" | sed -n 's/.*Release.*version="\([^"]*\)".*/\1/p') # shellcheck disable=SC2034 getVersionInfo_remoteFile=$(echo "${versionInfo}" | sed -n 's/.*file="\([^"]*\)".*/\1/p') + # shellcheck disable=SC2034 + getVersionInfo_remoteFileHashSha256=$(echo "${versionInfo}" | sed -n 's/.*fileHashSha256="\([^"]*\)".*/\1/p') } function installFromUrl { - installFromRawUrl "https://plex.tv/${1}" + installFromRawUrl "https://plex.tv/${1}" "${2}" } function installFromRawUrl { local remoteFile="$1" - curl -J -L -o /tmp/plexmediaserver.deb "${remoteFile}" - local last=$? + local expectedSha256="${2:-}" + + # if download url matches and donwload is cached, then install it without download + [[ -r /config/install/plexmediaserver.url ]] && oldurl=$(< /config/install/plexmediaserver.url) + if [ "$remoteFile" = "${oldurl:-}" ] && [ -f /config/install/plexmediaserver.deb ]; then + install "$remoteFile" + return $? + fi + curl --create-dirs -J -L -o /config/install/tmp/plexmediaserver.deb "${remoteFile}" + local last=$? + local sha256; + sha256=$(sha256sum /config/install/tmp/plexmediaserver.deb | awk '{ print $1 }') + echo "$sha256" > /config/install/tmp/plexmediaserver.sha256 + echo "$remoteFile" > /config/install/tmp/plexmediaserver.url # test if deb file size is ok, or if download failed - if [[ "$last" -gt "0" ]] || [[ $(stat -c %s /tmp/plexmediaserver.deb) -lt 10000 ]]; then - echo "Failed to fetch update" + if [[ "$last" -gt "0" ]] || [[ $(stat -c %s /config/install/tmp/plexmediaserver.deb) -lt 10000 ]]; then + rm -rf /config/install/tmp + echo "Failed to fetch update: curl returned $last" + exit 1 + fi + # compare sha256, if provided + if [ -n "$expectedSha256" ] && [ ! "$expectedSha256" = "$sha256" ]; then + rm -rf /config/install/tmp + echo "Failed to fetch update: sha256sum does not match: expected=$expectedSha256 actual=$sha256" exit 1 fi - dpkg -i --force-confold --force-architecture /tmp/plexmediaserver.deb - rm -f /tmp/plexmediaserver.deb + # looks good, move tmp into position + mv /config/install/tmp/* /config/install && rm -rf /config/install/tmp + install "$remoteFile" } + +function install { + dpkg -i --force-confold --force-architecture /config/install/plexmediaserver.deb +} \ No newline at end of file diff --git a/root/plex-envvars b/root/plex-envvars new file mode 100755 index 00000000..c9600996 --- /dev/null +++ b/root/plex-envvars @@ -0,0 +1,14 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +home=~plex +model=$(uname -m) +version=$(uname -r) +export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR:-${home}/Library/Application Support}" +export PLEX_MEDIA_SERVER_HOME=/usr/lib/plexmediaserver +export PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS=6 +export PLEX_MEDIA_SERVER_INFO_VENDOR=Docker +export PLEX_MEDIA_SERVER_INFO_DEVICE="Docker Container" +export PLEX_MEDIA_SERVER_INFO_MODEL="$model" +export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION="$version" \ No newline at end of file diff --git a/root/plex_service.sh b/root/plex_service.sh deleted file mode 100755 index 882e40c4..00000000 --- a/root/plex_service.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -if [ "$#" -eq 1 ]; then - s6-svc "$1" /var/run/s6/services/plex -else - echo "No argument supplied; must be -u, -d, or -r." -fi From 83062cd84e233cb70a7b57ec9ce3ce05d428c621 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 22 Jun 2023 18:30:35 +0000 Subject: [PATCH 08/15] Use single multi-arch Dockerfile --- Dockerfile | 26 +++++++++++++-- Dockerfile.arm64 | 78 -------------------------------------------- Dockerfile.armv7 | 78 -------------------------------------------- Dockerfile.i386 | 78 -------------------------------------------- dev/build.386.sh | 2 +- dev/build.amd64.sh | 2 +- dev/build.arm32v7.sh | 2 +- dev/build.arm64v8.sh | 2 +- dev/push.all.sh | 1 + 9 files changed, 28 insertions(+), 241 deletions(-) delete mode 100644 Dockerfile.arm64 delete mode 100644 Dockerfile.armv7 delete mode 100644 Dockerfile.i386 create mode 100755 dev/push.all.sh diff --git a/Dockerfile b/Dockerfile index 22c5ee4a..b2e1d5b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,34 @@ -FROM ubuntu:22.04 - +FROM ubuntu:22.04 as base-amd64 ARG S6_OVERLAY_VERSION=v3.1.5.0 ARG S6_OVERLAY_ARCH=x86_64 ARG PLEX_BUILD=linux-x86_64 ARG PLEX_DISTRO=debian -ARG DEBIAN_FRONTEND="noninteractive" ARG INTEL_NEO_VERSION=20.48.18558 ARG INTEL_IGC_VERSION=1.0.5699 ARG INTEL_GMMLIB_VERSION=20.3.2 +FROM arm64v8/ubuntu:22.04 as base-arm64 +ARG S6_OVERLAY_VERSION=v3.1.5.0 +ARG S6_OVERLAY_ARCH=aarch64 +ARG PLEX_BUILD=linux-aarch64 + +FROM arm32v7/ubuntu:22.04 as base-arm +ARG S6_OVERLAY_VERSION=v3.1.5.0 +ARG S6_OVERLAY_ARCH=arm +ARG PLEX_BUILD=linux-armv7hf_neon + +FROM i386/ubuntu:18.04 as base-386 +ARG S6_OVERLAY_VERSION=v3.1.5.0 +ARG S6_OVERLAY_ARCH=i686 +ARG PLEX_BUILD=linux-x86 + +FROM base-${TARGETARCH} AS plex +ARG TARGETARCH +RUN echo Building pms-docker for ${TARGETARCH} + +ARG DEBIAN_FRONTEND="noninteractive" +ARG PLEX_DISTRO=debian + RUN \ # Update and get dependencies apt-get update && \ diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 deleted file mode 100644 index 4eaf1bcc..00000000 --- a/Dockerfile.arm64 +++ /dev/null @@ -1,78 +0,0 @@ -FROM arm64v8/ubuntu:22.04 - -ARG S6_OVERLAY_VERSION=v3.1.5.0 -ARG S6_OVERLAY_ARCH=aarch64 -ARG PLEX_BUILD=linux-aarch64 -ARG PLEX_DISTRO=debian -ARG DEBIAN_FRONTEND="noninteractive" - -RUN \ -# Update and get dependencies - apt-get update && \ - apt-get install -y \ - tzdata \ - curl \ - xz-utils \ - xmlstarlet \ - uuid-runtime \ - unrar \ - cron \ - && \ - \ -# Fetch and extract S6 overlay - curl -L -s \ - "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ - && \ - curl -L -s \ - "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ - && \ - \ -# Add user - useradd -U -d /config -s /bin/false plex && \ - usermod -G users plex && \ - \ -# Setup directories - mkdir -p \ - /config \ - /transcode \ - /data \ - && \ - \ -# Cleanup - apt-get -y autoremove && \ - apt-get -y clean && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp -VOLUME /config /transcode - -ARG AUTOUPDATE=false -ARG TAG=beta -ARG URL= - -ENV TAG=${TAG} \ - CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" \ - TZ="UTC" \ - \ - TERM="xterm" \ - LANG="C.UTF-8" \ - LC_ALL="C.UTF-8" \ - \ - S6_KEEP_ENV=1 \ - S6_SERVICES_GRACETIME=10000 \ - S6_KILL_GRACETIME=5000 \ - S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ - S6_BEHAVIOUR_IF_STAGE2_FAILS=2 - -COPY root/ / - -RUN \ -# Save version and install - /installBinary.sh - -HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 - -ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/Dockerfile.armv7 b/Dockerfile.armv7 deleted file mode 100644 index a0e45875..00000000 --- a/Dockerfile.armv7 +++ /dev/null @@ -1,78 +0,0 @@ -FROM arm32v7/ubuntu:22.04 - -ARG S6_OVERLAY_VERSION=v3.1.5.0 -ARG S6_OVERLAY_ARCH=arm -ARG PLEX_BUILD=linux-armv7hf_neon -ARG PLEX_DISTRO=debian -ARG DEBIAN_FRONTEND="noninteractive" - -RUN \ -# Update and get dependencies - apt-get update && \ - apt-get install -y \ - tzdata \ - curl \ - xz-utils \ - xmlstarlet \ - uuid-runtime \ - unrar \ - cron \ - && \ - \ -# Fetch and extract S6 overlay - curl -L -s \ - "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ - && \ - curl -L -s \ - "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ - && \ - \ -# Add user - useradd -U -d /config -s /bin/false plex && \ - usermod -G users plex && \ - \ -# Setup directories - mkdir -p \ - /config \ - /transcode \ - /data \ - && \ - \ -# Cleanup - apt-get -y autoremove && \ - apt-get -y clean && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp -VOLUME /config /transcode - -ARG AUTOUPDATE=false -ARG TAG=beta -ARG URL= - -ENV TAG=${TAG} \ - CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" \ - TZ="UTC" \ - \ - TERM="xterm" \ - LANG="C.UTF-8" \ - LC_ALL="C.UTF-8" \ - \ - S6_KEEP_ENV=1 \ - S6_SERVICES_GRACETIME=10000 \ - S6_KILL_GRACETIME=5000 \ - S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ - S6_BEHAVIOUR_IF_STAGE2_FAILS=2 - -COPY root/ / - -RUN \ -# Save version and install - /installBinary.sh - -HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 - -ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/Dockerfile.i386 b/Dockerfile.i386 deleted file mode 100644 index 591dc1ae..00000000 --- a/Dockerfile.i386 +++ /dev/null @@ -1,78 +0,0 @@ -FROM i386/ubuntu:18.04 - -ARG S6_OVERLAY_VERSION=v3.1.5.0 -ARG S6_OVERLAY_ARCH=i686 -ARG PLEX_BUILD=linux-x86 -ARG PLEX_DISTRO=debian -ARG DEBIAN_FRONTEND="noninteractive" - -RUN \ -# Update and get dependencies - apt-get update && \ - apt-get install -y \ - tzdata \ - curl \ - xz-utils \ - xmlstarlet \ - uuid-runtime \ - unrar \ - cron \ - && \ - \ -# Fetch and extract S6 overlay - curl -L -s \ - "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jxpf - -C / \ - && \ - curl -L -s \ - "https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jxpf - -C / \ - && \ - \ -# Add user - useradd -U -d /config -s /bin/false plex && \ - usermod -G users plex && \ - \ -# Setup directories - mkdir -p \ - /config \ - /transcode \ - /data \ - && \ - \ -# Cleanup - apt-get -y autoremove && \ - apt-get -y clean && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp -VOLUME /config /transcode - -ARG AUTOUPDATE=false -ARG TAG=beta -ARG URL= - -ENV TAG=${TAG} \ - CHANGE_CONFIG_DIR_OWNERSHIP="true" \ - HOME="/config" \ - TZ="UTC" \ - \ - TERM="xterm" \ - LANG="C.UTF-8" \ - LC_ALL="C.UTF-8" \ - \ - S6_KEEP_ENV=1 \ - S6_SERVICES_GRACETIME=10000 \ - S6_KILL_GRACETIME=5000 \ - S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ - S6_BEHAVIOUR_IF_STAGE2_FAILS=2 - -COPY root/ / - -RUN \ -# Save version and install - /installBinary.sh - -HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 - -ENTRYPOINT ["/init"] \ No newline at end of file diff --git a/dev/build.386.sh b/dev/build.386.sh index 23274d12..ef369777 100755 --- a/dev/build.386.sh +++ b/dev/build.386.sh @@ -4,4 +4,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once -docker buildx build -o type=docker,name=pms-386 --load --platform linux/386 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile.i386 .. +docker buildx build --progress=plain -o type=docker,name=pms-386 --load --platform linux/386 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.amd64.sh b/dev/build.amd64.sh index 73775ebc..819f87d7 100755 --- a/dev/build.amd64.sh +++ b/dev/build.amd64.sh @@ -5,4 +5,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once # https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined -docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-amd64 --platform linux/amd64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. +docker buildx build --progress=plain --security-opt seccomp:unconfined -o type=docker,name=pms-amd64 --platform linux/amd64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.arm32v7.sh b/dev/build.arm32v7.sh index 8b7b2363..ae475da5 100755 --- a/dev/build.arm32v7.sh +++ b/dev/build.arm32v7.sh @@ -5,4 +5,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once # https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined -docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-armv7 --load --platform linux/arm/v7 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile.armv7 .. +docker buildx build --progress=plain --security-opt seccomp:unconfined -o type=docker,name=pms-armv7 --load --platform linux/arm/v7 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.arm64v8.sh b/dev/build.arm64v8.sh index 8cb69ffa..5ca14c16 100755 --- a/dev/build.arm64v8.sh +++ b/dev/build.arm64v8.sh @@ -5,4 +5,4 @@ IFS=$'\n\t' # This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once # https://github.com/tianon/docker-brew-ubuntu-core/issues/183 -docker buildx build --security-opt seccomp:unconfined -o type=docker,name=pms-arm64 --load --platform linux/arm64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile.arm64 .. +docker buildx build --progress=plain --security-opt seccomp:unconfined -o type=docker,name=pms-arm64 --load --platform linux/arm64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/push.all.sh b/dev/push.all.sh new file mode 100755 index 00000000..2c764186 --- /dev/null +++ b/dev/push.all.sh @@ -0,0 +1 @@ +docker buildx build --progress=plain --push --security-opt seccomp:unconfined --platform linux/amd64,linux/386,linux/arm/v7,linux/arm64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile --tag INSERT_TAG_HERE:autoupdate .. From 502203f1244030f6fa5a5fcb68708185c211916d Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Sat, 24 Jun 2023 16:01:37 +0000 Subject: [PATCH 09/15] Allow version-specific builds. Improve build scripts. Readmes. --- Dockerfile | 23 +++++---- README.md | 29 ++++++++---- dev/README.md | 44 ++++++++++++++++- dev/build.386.sh | 7 --- dev/build.amd64.sh | 8 ---- dev/build.arm32v7.sh | 8 ---- dev/build.arm64v8.sh | 8 ---- dev/debug.386.sh | 7 --- dev/debug.amd64.sh | 7 --- dev/debug.arm32v7.sh | 14 ------ dev/debug.arm64v8.sh | 14 ------ dev/dev.sh | 87 ++++++++++++++++++++++++++++++++++ dev/docker-bake.hcl | 40 ++++++++++++++++ dev/push.all.sh | 1 - dev/setup-build-env.sh | 16 ------- root/etc/plex/plex-update | 5 +- root/etc/plex/service.cron.run | 4 +- root/installBinary.sh | 36 +++++++------- root/plex-common.sh | 6 +-- root/plex-envvars | 2 +- root/plex-service.sh | 7 +++ test-debug.sh | 16 ------- 22 files changed, 238 insertions(+), 151 deletions(-) delete mode 100755 dev/build.386.sh delete mode 100755 dev/build.amd64.sh delete mode 100755 dev/build.arm32v7.sh delete mode 100755 dev/build.arm64v8.sh delete mode 100755 dev/debug.386.sh delete mode 100755 dev/debug.amd64.sh delete mode 100755 dev/debug.arm32v7.sh delete mode 100755 dev/debug.arm64v8.sh create mode 100755 dev/dev.sh create mode 100644 dev/docker-bake.hcl delete mode 100755 dev/push.all.sh delete mode 100755 dev/setup-build-env.sh create mode 100755 root/plex-service.sh delete mode 100644 test-debug.sh diff --git a/Dockerfile b/Dockerfile index b2e1d5b7..aefa7a30 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,6 @@ FROM ubuntu:22.04 as base-amd64 ARG S6_OVERLAY_VERSION=v3.1.5.0 ARG S6_OVERLAY_ARCH=x86_64 ARG PLEX_BUILD=linux-x86_64 -ARG PLEX_DISTRO=debian ARG INTEL_NEO_VERSION=20.48.18558 ARG INTEL_IGC_VERSION=1.0.5699 ARG INTEL_GMMLIB_VERSION=20.3.2 @@ -71,17 +70,18 @@ RUN \ EXPOSE 32400/tcp 8324/tcp 32469/tcp 1900/udp 32410/udp 32412/udp 32413/udp 32414/udp VOLUME /config /transcode -ARG AUTOUPDATE=false -ARG TAG=beta +# TAG can be "autoupdate" or an explicit version, like 1.32.4.7195-7c8f9d3b6 +ARG TAG="autoupdate" ARG URL= +ARG DEBUG= -ENV TAG=${TAG} \ - CHANGE_CONFIG_DIR_OWNERSHIP="true" \ +ENV CHANGE_CONFIG_DIR_OWNERSHIP="true" \ HOME="/config" \ - TZ="UTC" \ +# Note, only used for images built with TAG=autoupdate + AUTO_UPDATE_CHANNEL="beta" \ \ - TERM="xterm" \ - LANG="C.UTF-8" \ + TERM="xterm" \ + LANG="C.UTF-8" \ LC_ALL="C.UTF-8" \ \ S6_KEEP_ENV=1 \ @@ -94,8 +94,11 @@ COPY root/ / RUN \ # Save version and install - /installBinary.sh + /installBinary.sh \ + && \ +# Clean up installer + rm /installBinary.sh HEALTHCHECK --interval=5s --timeout=2s --retries=20 CMD /healthcheck.sh || exit 1 -ENTRYPOINT ["/init"] \ No newline at end of file +ENTRYPOINT ["/init"] diff --git a/README.md b/README.md index c89ba230..00860a29 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,10 @@ The provided `docker-compose` templates use the `plexinc/pms-docker` image which To use `docker-compose` with ARM devices, you must first build one of the ARM images locally. ```sh -docker build -t plexinc/pms-docker:latest -f Dockerfile.armv7 . # or arm64 +# arm 32 bit +docker build --platform linux/arm/v7 -t plexinc/pms-docker:latest . +# arm 64 bit +docker build --platform linux/arm64 -t plexinc/pms-docker:latest . ``` Then you can `docker-compose up`. @@ -138,9 +141,14 @@ uid=1001(myuser) gid=1001(myuser) groups=1001(myuser) In the above case, if you set the `PLEX_UID` and `PLEX_GID` to `1001`, then the permissions will match that of your own user. ## Tags -In addition to the standard version and `latest` tags, two other tags exist: `beta` and `public`. These two images behave differently than your typical containers. These two images do **not** have any Plex Media Server binary installed. Instead, when these containers are run, they will perform an update check and fetch the latest version, install it, and then continue execution. They also run the update check whenever the container is restarted. To update the version in the container, simply stop the container and start container again when you have a network connection. The startup script will automatically fetch the appropriate version and install it before starting the Plex Media Server. +In addition to the standard version and `latest` tags, there is a special `autoupdate` tag. This container behave differently than your typical containers. The `autoupdate` container does **not** have any Plex Media Server binary installed. Instead, every time this container is run, it will fetch the latest version, install it and then start the Plex Media Server. + +Since containers lose their state every time they are restarted, the binary is cached in `/config/install` so it won't need to be downloaded again, but it will need to be installed every time this container starts. + +This container will automatically check for new updates every day between 4:00am - 4:30am (according to timezone in `TZ`). + +- **AUTO_UPDATE_CHANNEL** This variable can only be `public` or `beta` (default). The `public` value restricts this check to public versions only whereas `beta` value will fetch beta versions. If the server is not logged in or you do not have Plex Pass on your account, the `beta` tagged images will be restricted to publicly available versions only. -The `public` restricts this check to public versions only where as `beta` will fetch beta versions. If the server is not logged in or you do not have Plex Pass on your account, the `beta` tagged images will be restricted to publicly available versions only. To view the Docker images head over to [https://hub.docker.com/r/plexinc/pms-docker/tags/](https://hub.docker.com/r/plexinc/pms-docker/tags/) @@ -158,11 +166,16 @@ If you wish to migrate an existing directory to the docker config directory: - Note: by default Plex will claim ownership of the entire contents of the `config` dir (see CHANGE_CONFIG_DIR_OWNERSHIP for more information). As such, there should be nothing in that dir that you do not wish for Plex to own. ## Useful information -- Start the container: `docker start plex` -- Stop the container: `docker stop plex` -- Shell access to the container while it is running: `docker exec -it plex /bin/bash` -- See the logs given by the startup script in real time: `docker logs -f plex` -- Restart the application and upgrade to the latest version: `docker restart plex` +- Start the container: + - `docker start plex` +- Stop the container: + - `docker stop plex` +- Shell access to the container while it is running: + - `docker exec -it plex /bin/bash` +- See the logs given by the startup script in real time: + - `docker logs -f plex` +- Restart the application: + - `docker restart plex` ## Fedora, CentOS, Red Hat diff --git a/dev/README.md b/dev/README.md index 5f366f6e..10273217 100644 --- a/dev/README.md +++ b/dev/README.md @@ -1,3 +1,45 @@ # Dev Helper Scripts -Unless you are making changes to the Dockerfile themselves, please ignore all the files here. In fact, your environment may be very different and these scripts may not work at all. They are provided only as a reference/starting point so you don't have to start from scratch. Heavy customizations are likely. \ No newline at end of file +Hey homelab enthusiast! + +Unless you are enhancing these Dockerfile themselves, please ignore all the files here. In fact, your environment may be very different and these scripts may not work at all. These are just provided only as a reference/starting point so you don't have to start from scratch. + +You might just consider extending the images here. i.e. + +``` +FROM plexinc/pms-docker:latest + +RUN echo "Add your modifications here" +``` + +Otherwise, `dev.sh` will build all of the multi-platform docker images, for each platform it will build one that uses a specific version, and `autoupdate` version that doesn't bake the binary into the image, but rather downloads when container boots. Look inside the script for more info. + +`docker-bake.hcl` is a buildx bake file that will build all platforms, using pre-installed binaries and `update` versions. This bake file will push to dockerhub. You can override the destination using the `dockerhub_image` variable in `dev.sh`. + + +### Examples + +#### Prereqs: +- [docker](https://docs.docker.com/engine/install/) +- [buildx](https://github.com/docker/buildx) +- x86 based linux host + +```sh +# sets up buildx for multi-arch builds +./dev.sh setup + +# bake - build all and push to dockerhub +./dev.sh bake + +# build version-specific and autoupdate image for amd64 +./dev.sh build amd64 + +# build everything +./dev.sh buildall + +# launches version-specific container +./dev.sh debug amd64 + +# launches auto-update container +./dev.sh debug amd64 autoupdate +``` diff --git a/dev/build.386.sh b/dev/build.386.sh deleted file mode 100755 index ef369777..00000000 --- a/dev/build.386.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -docker buildx build --progress=plain -o type=docker,name=pms-386 --load --platform linux/386 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.amd64.sh b/dev/build.amd64.sh deleted file mode 100755 index 819f87d7..00000000 --- a/dev/build.amd64.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -# https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined -docker buildx build --progress=plain --security-opt seccomp:unconfined -o type=docker,name=pms-amd64 --platform linux/amd64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.arm32v7.sh b/dev/build.arm32v7.sh deleted file mode 100755 index ae475da5..00000000 --- a/dev/build.arm32v7.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -# https://github.com/tianon/docker-brew-ubuntu-core/issues/183 explains why need to use --security-opt seccomp:unconfined -docker buildx build --progress=plain --security-opt seccomp:unconfined -o type=docker,name=pms-armv7 --load --platform linux/arm/v7 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/build.arm64v8.sh b/dev/build.arm64v8.sh deleted file mode 100755 index 5ca14c16..00000000 --- a/dev/build.arm64v8.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -# https://github.com/tianon/docker-brew-ubuntu-core/issues/183 -docker buildx build --progress=plain --security-opt seccomp:unconfined -o type=docker,name=pms-arm64 --load --platform linux/arm64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile .. diff --git a/dev/debug.386.sh b/dev/debug.386.sh deleted file mode 100755 index 79abca5a..00000000 --- a/dev/debug.386.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -docker run --rm --name pms-386 --platform linux/386 -e DEBUG=true -it pms-386:latest bash \ No newline at end of file diff --git a/dev/debug.amd64.sh b/dev/debug.amd64.sh deleted file mode 100755 index 743b30e4..00000000 --- a/dev/debug.amd64.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -docker run --rm --name pms-amd64 -e DEBUG=true -it pms-amd64:latest bash \ No newline at end of file diff --git a/dev/debug.arm32v7.sh b/dev/debug.arm32v7.sh deleted file mode 100755 index 7e11dc49..00000000 --- a/dev/debug.arm32v7.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -# Note - S6 overlay does NOT like it when you give it a tty under QEMU - do not run -# the container with "-it" rather, run it in background (so we get log output) then -# exec a bash process to enter the container. - -trap "trap - SIGTERM && docker stop pms-armv7" SIGINT SIGTERM EXIT -docker run --rm --name pms-armv7 --platform linux/arm/v7 -e DEBUG=true pms-armv7:latest & -sleep 5 -docker exec -it pms-armv7 bash diff --git a/dev/debug.arm64v8.sh b/dev/debug.arm64v8.sh deleted file mode 100755 index 3ff32324..00000000 --- a/dev/debug.arm64v8.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is just a helper script to quickly test local Dockerfile builds, please run setup-build-env.sh once - -# Note - S6 overlay does NOT like it when you give it a tty under QEMU - do not run -# the container with "-it" rather, run it in background (so we get log output) then -# exec a bash process to enter the container. - -trap "trap - SIGTERM && docker stop pms-arm64" SIGINT SIGTERM EXIT -docker run --rm --name pms-arm64 --platform linux/arm64 -e DEBUG=true pms-arm64:latest & -sleep 5 -docker exec -it pms-arm64 bash diff --git a/dev/dev.sh b/dev/dev.sh new file mode 100755 index 00000000..3b6a367a --- /dev/null +++ b/dev/dev.sh @@ -0,0 +1,87 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# This is just a helper script to quickly test local Dockerfile builds, please run setup() once +# Assumes this is running on Linux (any distro) using (intel/amd). + +# This bakes the specific binary into the image, you can override these vars on command line +# DOCKERHUB_IMAGE=myorg/mycontainer ./dev/sh bake +VERSION_TO_BUILD=${VERSION_TO_BUILD:-"1.32.4.7195-7c8f9d3b6"} +DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE:-"plexinc/pms-docker"} + +setup() { + # Create a multi-arch buildx builder named PlexBuilder (if it doesn't exist) + if ! docker buildx inspect PlexBuilder 1> /dev/null 2>& 1; then + echo Creating PlexBuilder + # --use will make it automatically use this builder + docker buildx create --name PlexBuilder --platform linux/arm64,linux/arm/v7,linux/386 --use + # this is needed to register the arch-specific images with QEMU to be able to test + # these without native hardware + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi +} +build() { + platform=$1 + name=$2 + docker buildx build \ + --progress=plain \ + -o type=docker \ + --load \ + --platform "$platform" \ + --build-arg \ + "TAG=$VERSION_TO_BUILD" \ + -t "$name:$VERSION_TO_BUILD" \ + -t "$name:latest" \ + -f ../Dockerfile .. + docker buildx build \ + --progress=plain \ + -o type=docker \ + --load \ + --platform "$platform" \ + --build-arg \ + "TAG=autoupdate" \ + -t "$name:autoupdate" \ + -f ../Dockerfile .. +} + +debug() { + platform=$1 + name=$2 + autoupdate=$3 + if [ "$autoupdate" = "autoupdate" ]; then + name=$name:autoupdate + else + name=$name:latest + fi + if [[ $platform == linux/arm* ]]; then + # shellcheck disable=SC2064 + trap "trap - SIGTERM && docker stop debug-plex" SIGINT SIGTERM EXIT + docker run --rm --name debug-plex --platform "$platform" -e DEBUG=true "$name" & + sleep 5 + docker exec -it debug-plex bash + else + docker run --rm --name debug-plex --platform "$platform" -e DEBUG=true -it "$name" bash + fi +} + +cmd=${1:-} +kind=${2:-} +[ "$cmd" = 'setup' ] && setup +[ "$cmd" = 'build' ] && [ "$kind" = '386' ] && build linux/386 pms-386 +[ "$cmd" = 'build' ] && [ "$kind" = 'amd64' ] && build linux/amd64 pms-amd64 +[ "$cmd" = 'build' ] && [ "$kind" = 'arm32v7' ] && build linux/arm/v7 pms-arm32v7 +[ "$cmd" = 'build' ] && [ "$kind" = 'arm64v8' ] && build linux/arm64 pms-arm64v8 +[ "$cmd" = 'buildall' ] && \ + build linux/386 pms-386 && \ + build linux/amd64 pms-amd64 && \ + build linux/arm/v7 pms-arm32v7 && \ + build linux/arm64 pms-arm64v8 + +[ "$cmd" = 'bake' ] && TAG=$VERSION_TO_BUILD IMAGE=$DOCKERHUB_IMAGE docker buildx bake + +autoupdate=${3:-} +[ "$cmd" = 'debug' ] && [ "$kind" = '386' ] && debug linux/386 pms-386 "$autoupdate" +[ "$cmd" = 'debug' ] && [ "$kind" = 'amd64' ] && debug linux/amd64 pms-amd64 "$autoupdate" +[ "$cmd" = 'debug' ] && [ "$kind" = 'arm32v7' ] && debug linux/arm/v7 pms-arm32v7 "$autoupdate" +[ "$cmd" = 'debug' ] && [ "$kind" = 'arm64v8' ] && debug linux/arm64 pms-arm64v8 "$autoupdate" \ No newline at end of file diff --git a/dev/docker-bake.hcl b/dev/docker-bake.hcl new file mode 100644 index 00000000..46eb751c --- /dev/null +++ b/dev/docker-bake.hcl @@ -0,0 +1,40 @@ +# run this file using "docker buildx bake" + +variable "TAG" { + # This should be overridden on command line to be the + # specific plex media server binary to download into the image + default = "1.32.4.7195-7c8f9d3b6" +} +variable "IMAGE" { + default = "plexinc/pms-docker" +} + +group "default" { + targets = ["plexmediaserver-versioned", "plexmediaserver-autoupdate"] +} + +target "plexmediaserver-versioned" { + # This target builds targets that downloald and pre-install the + # the plex media server binary in the container. This image + # has two tags, the version itself, and assuming this is that latest + # also tags it with :latest. + output = ["type=registry"] + context = ".." + platforms = ["linux/386", "linux/amd64", "linux/arm64", "linux/arm/v7"] + tags = ["${IMAGE}:${TAG}", "${IMAGE}:latest"] + args = { + TAG = "${TAG}" + } +} +target "plexmediaserver-autoupdate" { + # This target build a download and pre-install a configuration of the + # container automatically downloads and installs the server at runtime + # and automatically checks for updates once a day. + output = ["type=registry"] + context = ".." + platforms = ["linux/386", "linux/amd64", "linux/arm64", "linux/arm/v7"] + tags = ["${IMAGE}:autoupdate"] + args = { + TAG = "autoupdate" + } +} \ No newline at end of file diff --git a/dev/push.all.sh b/dev/push.all.sh deleted file mode 100755 index 2c764186..00000000 --- a/dev/push.all.sh +++ /dev/null @@ -1 +0,0 @@ -docker buildx build --progress=plain --push --security-opt seccomp:unconfined --platform linux/amd64,linux/386,linux/arm/v7,linux/arm64 --build-arg AUTOUPDATE=TRUE -f ../Dockerfile --tag INSERT_TAG_HERE:autoupdate .. diff --git a/dev/setup-build-env.sh b/dev/setup-build-env.sh deleted file mode 100755 index 3fb202c5..00000000 --- a/dev/setup-build-env.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -# This is a one time setup script to setup the build env needed by the build and debug scripts. -# Assumes this is running on Linux (any distro) using (intel/amd). - -# Create a multi-arch buildx builder named PlexBuilder (if it doesn't exist) -if ! docker buildx inspect PlexBuilder 1> /dev/null 2>& 1; then - echo Creating PlexBuilder - # --use will make it automatically use this builder - docker buildx create --name PlexBuilder --platform linux/arm64,linux/arm/v7,linux/386 --use - # this is needed to register the arch-specific images with QEMU to be able to test - # these without native hardware - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -fi diff --git a/root/etc/plex/plex-update b/root/etc/plex/plex-update index 5ccda7dc..3cd3ebf2 100755 --- a/root/etc/plex/plex-update +++ b/root/etc/plex/plex-update @@ -3,7 +3,7 @@ set -euo pipefail IFS=$'\n\t' DEBUG=${DEBUG:-} -TAG=${TAG:-} +AUTO_UPDATE_CHANNEL=${AUTO_UPDATE_CHANNEL:-} # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then @@ -32,12 +32,11 @@ else installedVersion="none" fi - # Get updated version number remoteVersion= remoteFile= remoteFileHashSha256= -getVersionInfo "${TAG}" "${token}" remoteVersion remoteFile remoteFileHashSha256 +getVersionInfo "${AUTO_UPDATE_CHANNEL}" "${token}" remoteVersion remoteFile remoteFileHashSha256 if [ -z "${remoteVersion}" ] || [ -z "${remoteFile}" ]; then echo "Could not get update version" diff --git a/root/etc/plex/service.cron.run b/root/etc/plex/service.cron.run index 577ce1a4..cf6a80f1 100755 --- a/root/etc/plex/service.cron.run +++ b/root/etc/plex/service.cron.run @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash set -euo pipefail IFS=$'\n\t' @@ -12,4 +12,4 @@ fi # shellcheck source=../../plex-envvars . /plex-envvars printenv > /etc/environment -exec cron -f \ No newline at end of file +exec cron -f diff --git a/root/installBinary.sh b/root/installBinary.sh index 041ed9e1..399cb28d 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -2,9 +2,15 @@ set -euo pipefail IFS=$'\n\t' +DEBUG=${DEBUG:-} + +# If we are debugging, enable trace +if [ "${DEBUG,,}" = "true" ]; then + set -x +fi + . /plex-common.sh -addVarToConf "version" "${TAG}" addVarToConf "plex_build" "${PLEX_BUILD}" addVarToConf "plex_distro" "${PLEX_DISTRO}" @@ -14,25 +20,21 @@ mkdir -p /etc/services.d/plex ; ln -s /etc/plex/service.plex.run /etc/services.d mkdir -p /etc/cont-init.d ln -s /etc/plex/plex-first-run /etc/cont-init.d/000-plex-first-run ln -s /etc/plex/plex-hw-transcode-and-connected-tuner /etc/cont-init.d/010-plex-hw-transcode-and-connected-tuner -ln -s /etc/plex/plex-update /etc/cont-init.d/020-plex-update -if [ "${AUTOUPDATE,,}" = 'true' ]; then - echo "AUTOUPDATE requested, setting up cron service and scheduling plex-update" - mkdir -p /etc/services.d/cron ; ln -s /etc/plex/service.cron.run /etc/services.d/cron/run - # Specify bash as shell, add S6 commands to PATH - echo "SHELL=/bin/bash" > /etc/crontab - echo "$(env | grep PATH):/command" >> /etc/crontab - # Specify cron job: be nice to Plex servers - space out updates at 4:00am over 30m window - echo "0 4 * * * root perl -le 'sleep rand 30' ; /etc/plex/plex-update > /proc/1/fd/1 2>&1" >> /etc/crontab - echo "Removing plex-update from cont-init.d" - rm /etc/cont-init.d/020-plex-update - echo "Adding plex-install to cont-init.d" - ln -s /etc/plex/plex-install /etc/cont-init.d/099-plex-install - exit 0 -fi if [ -n "${URL}" ]; then echo "Attempting to install from URL: ${URL}" installFromRawUrl "${URL}" -elif [ "${TAG}" != "beta" ] && [ "${TAG}" != "public" ]; then +elif [ "${TAG,,}" = "autoupdate" ]; then + echo "AUTOUPDATE requested, skipping download and install, setting up cron service and scheduling plex-update" + mkdir -p /etc/services.d/cron ; ln -s /etc/plex/service.cron.run /etc/services.d/cron/run + # Specify bash as shell, add S6 commands to PATH + echo "SHELL=/bin/bash" > /etc/crontab + echo "$(env | grep PATH):/command" >> /etc/crontab + # Specify cron job: be nice to Plex servers - space out updates at 4:00am over 30m window + echo "0 4 * * * root perl -le 'sleep rand 30' ; /etc/plex/plex-update > /proc/1/fd/1 2>&1" >> /etc/crontab + echo "Adding plex-install to cont-init.d" + ln -s /etc/plex/plex-install /etc/cont-init.d/099-plex-install +else + # This pre-installs the specified version in TAG into this docker image. remoteVersion= remoteFile= getVersionInfo "${TAG}" "" remoteVersion remoteFile diff --git a/root/plex-common.sh b/root/plex-common.sh index de8869b6..2653cc6f 100755 --- a/root/plex-common.sh +++ b/root/plex-common.sh @@ -69,7 +69,7 @@ function getVersionInfo { function installFromUrl { - installFromRawUrl "https://plex.tv/${1}" "${2}" + installFromRawUrl "https://plex.tv/${1}" "${2:-}" } function installFromRawUrl { @@ -108,5 +108,5 @@ function installFromRawUrl { } function install { - dpkg -i --force-confold --force-architecture /config/install/plexmediaserver.deb -} \ No newline at end of file + dpkg -i --force-confold /config/install/plexmediaserver.deb +} diff --git a/root/plex-envvars b/root/plex-envvars index c9600996..be60fa58 100755 --- a/root/plex-envvars +++ b/root/plex-envvars @@ -11,4 +11,4 @@ export PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS=6 export PLEX_MEDIA_SERVER_INFO_VENDOR=Docker export PLEX_MEDIA_SERVER_INFO_DEVICE="Docker Container" export PLEX_MEDIA_SERVER_INFO_MODEL="$model" -export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION="$version" \ No newline at end of file +export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION="$version" diff --git a/root/plex-service.sh b/root/plex-service.sh new file mode 100755 index 00000000..e400acb7 --- /dev/null +++ b/root/plex-service.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ "$#" -eq 1 ]; then + s6-svc "$1" /var/run/s6/services/plex +else + echo "No argument supplied; must be -u (bring up), -d (bring down), or -r (restart)." +fi diff --git a/test-debug.sh b/test-debug.sh deleted file mode 100644 index e8ec9801..00000000 --- a/test-debug.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# This is just a helper script to quickly test local Dockerfile builds - -# build variations -#--build-arg AUTOUPDATE=false -#--build-arg URL=https://plex.tv//updater/packages/166139/file -#--build-arg TAG=public - -ID=$(docker build --build-arg AUTOUPDATE=TRUE --build-arg TAG=beta . 2>&1 | tee /dev/fd/2 build.log | tail -1 | awk '{ print $3}') - -# with persistent volume -docker run --rm -it -v testing-vol:/config:rw "$ID" -# without persistent volume -# docker run --rm -it -v "$ID" bash - From 42fdfc9d398bc9930c9164ebe12e82c60d3b31d6 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Sat, 24 Jun 2023 16:12:41 +0000 Subject: [PATCH 10/15] Log viewer /plex-logs.sh --- Dockerfile | 1 + README.md | 2 ++ root/plex-logs.sh | 7 +++++++ 3 files changed, 10 insertions(+) create mode 100755 root/plex-logs.sh diff --git a/Dockerfile b/Dockerfile index aefa7a30..fc0caae1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,6 +39,7 @@ RUN \ uuid-runtime \ unrar \ cron \ + multitail \ && \ \ # Fetch and extract S6 overlay diff --git a/README.md b/README.md index 00860a29..373e1d16 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,8 @@ If you wish to migrate an existing directory to the docker config directory: - `docker exec -it plex /bin/bash` - See the logs given by the startup script in real time: - `docker logs -f plex` +- Monitor all Plex Media Server logs: + - `docker exec -it plex /plex-logs.sh` - Restart the application: - `docker restart plex` diff --git a/root/plex-logs.sh b/root/plex-logs.sh new file mode 100755 index 00000000..b85f9d3b --- /dev/null +++ b/root/plex-logs.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +. /plex-envvars + +logs="$PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR/Plex Media Server/Logs" +multitail --mergeall "$logs"/* + From 709a6debb03a43b54f9db24ca4d032c54f30d151 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Sat, 24 Jun 2023 17:23:53 +0000 Subject: [PATCH 11/15] Backwards compat. FORCE_UPDATE var --- README.md | 2 +- root/etc/plex/{plex-install => plex-startup} | 5 ++++- root/etc/plex/plex-update | 10 +++++++++- root/installBinary.sh | 8 +++++--- root/plex-common.sh | 9 +++++---- 5 files changed, 24 insertions(+), 10 deletions(-) rename root/etc/plex/{plex-install => plex-startup} (69%) diff --git a/README.md b/README.md index 373e1d16..2e00f272 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ Since containers lose their state every time they are restarted, the binary is c This container will automatically check for new updates every day between 4:00am - 4:30am (according to timezone in `TZ`). - **AUTO_UPDATE_CHANNEL** This variable can only be `public` or `beta` (default). The `public` value restricts this check to public versions only whereas `beta` value will fetch beta versions. If the server is not logged in or you do not have Plex Pass on your account, the `beta` tagged images will be restricted to publicly available versions only. - +- **FORCE_UPDATE** Set this variable to `true` in order to ignore previously cached binaries in `/config/install` upon startup. This is generally not required, but provided just-in-case. You can also manually force an update by simply deleting the `/config/install` directory. To view the Docker images head over to [https://hub.docker.com/r/plexinc/pms-docker/tags/](https://hub.docker.com/r/plexinc/pms-docker/tags/) diff --git a/root/etc/plex/plex-install b/root/etc/plex/plex-startup similarity index 69% rename from root/etc/plex/plex-install rename to root/etc/plex/plex-startup index 8f7d0f83..9c5d3c09 100755 --- a/root/etc/plex/plex-install +++ b/root/etc/plex/plex-startup @@ -2,7 +2,10 @@ set -euo pipefail IFS=$'\n\t' +# This script is called by the autoupdate, beta, and public tags only + DEBUG=${DEBUG:-} +FORCE_UPDATE=${FORCE_UPDATE:-} # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then @@ -14,7 +17,7 @@ fi CACHED_URL= [[ -r /config/install/plexmediaserver.url ]] && CACHED_URL=$(< /config/install/plexmediaserver.url) -if [ -n "$CACHED_URL" ] && [ -f /config/install/plexmediaserver.deb ]; then +if [ ! "${FORCE_UPDATE,,}" = "true" ] && [ -n "$CACHED_URL" ] && [ -f /config/install/plexmediaserver.deb ]; then echo "Installing previously downloaded plex version..." installFromRawUrl "$CACHED_URL" else diff --git a/root/etc/plex/plex-update b/root/etc/plex/plex-update index 3cd3ebf2..5def972b 100755 --- a/root/etc/plex/plex-update +++ b/root/etc/plex/plex-update @@ -2,6 +2,8 @@ set -euo pipefail IFS=$'\n\t' +# This script is called by cron, or by plex-startup + DEBUG=${DEBUG:-} AUTO_UPDATE_CHANNEL=${AUTO_UPDATE_CHANNEL:-} @@ -33,10 +35,16 @@ else fi # Get updated version number +tag= +readVarFromConf "tag" tag +channel=$AUTO_UPDATE_CHANNEL +if [ "${tag,,}" = 'beta' ] || [ "${tag,,}" = 'public' ]; then + channel=$tag +fi remoteVersion= remoteFile= remoteFileHashSha256= -getVersionInfo "${AUTO_UPDATE_CHANNEL}" "${token}" remoteVersion remoteFile remoteFileHashSha256 +getVersionInfo "${channel}" "${token}" remoteVersion remoteFile remoteFileHashSha256 if [ -z "${remoteVersion}" ] || [ -z "${remoteFile}" ]; then echo "Could not get update version" diff --git a/root/installBinary.sh b/root/installBinary.sh index 399cb28d..47d99d51 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -11,6 +11,7 @@ fi . /plex-common.sh +addVarToConf "tag" "${TAG}" addVarToConf "plex_build" "${PLEX_BUILD}" addVarToConf "plex_distro" "${PLEX_DISTRO}" @@ -23,7 +24,7 @@ ln -s /etc/plex/plex-hw-transcode-and-connected-tuner /etc/cont-init.d/010-plex- if [ -n "${URL}" ]; then echo "Attempting to install from URL: ${URL}" installFromRawUrl "${URL}" -elif [ "${TAG,,}" = "autoupdate" ]; then +elif [ "${TAG,,}" = "autoupdate" ] || [ "${TAG,,}" = "beta" ] || [ "${TAG,,}" = "public" ]; then echo "AUTOUPDATE requested, skipping download and install, setting up cron service and scheduling plex-update" mkdir -p /etc/services.d/cron ; ln -s /etc/plex/service.cron.run /etc/services.d/cron/run # Specify bash as shell, add S6 commands to PATH @@ -31,8 +32,8 @@ elif [ "${TAG,,}" = "autoupdate" ]; then echo "$(env | grep PATH):/command" >> /etc/crontab # Specify cron job: be nice to Plex servers - space out updates at 4:00am over 30m window echo "0 4 * * * root perl -le 'sleep rand 30' ; /etc/plex/plex-update > /proc/1/fd/1 2>&1" >> /etc/crontab - echo "Adding plex-install to cont-init.d" - ln -s /etc/plex/plex-install /etc/cont-init.d/099-plex-install + echo "Adding plex-startup to cont-init.d" + ln -s /etc/plex/plex-startup /etc/cont-init.d/099-plex-startup else # This pre-installs the specified version in TAG into this docker image. remoteVersion= @@ -46,5 +47,6 @@ else echo "Attempting to install: ${remoteVersion}" installFromUrl "${remoteFile}" + # delete unnecessary installer rm -rf /config/install fi diff --git a/root/plex-common.sh b/root/plex-common.sh index 2653cc6f..c45f7886 100755 --- a/root/plex-common.sh +++ b/root/plex-common.sh @@ -3,6 +3,7 @@ set -euo pipefail IFS=$'\n\t' PLEX_UPDATE_CHANNEL=${PLEX_UPDATE_CHANNEL:-} +FORCE_UPDATE=${FORCE_UPDATE:-} CONT_CONF_FILE="/version.txt" @@ -76,11 +77,11 @@ function installFromRawUrl { local remoteFile="$1" local expectedSha256="${2:-}" - # if download url matches and donwload is cached, then install it without download + # if download url matches and download is cached, then install it without download [[ -r /config/install/plexmediaserver.url ]] && oldurl=$(< /config/install/plexmediaserver.url) - if [ "$remoteFile" = "${oldurl:-}" ] && [ -f /config/install/plexmediaserver.deb ]; then - install "$remoteFile" - return $? + if [ ! "${FORCE_UPDATE,,}" = "true" ] && [ "$remoteFile" = "${oldurl:-}" ] && [ -f /config/install/plexmediaserver.deb ]; then + install "$remoteFile" + return $? fi curl --create-dirs -J -L -o /config/install/tmp/plexmediaserver.deb "${remoteFile}" From e2734a50710b7288e4e3bc539d378341b6ab5cf4 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Sat, 24 Jun 2023 17:49:10 +0000 Subject: [PATCH 12/15] newlines --- dev/dev.sh | 2 +- dev/docker-bake.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/dev.sh b/dev/dev.sh index 3b6a367a..49f9715e 100755 --- a/dev/dev.sh +++ b/dev/dev.sh @@ -84,4 +84,4 @@ autoupdate=${3:-} [ "$cmd" = 'debug' ] && [ "$kind" = '386' ] && debug linux/386 pms-386 "$autoupdate" [ "$cmd" = 'debug' ] && [ "$kind" = 'amd64' ] && debug linux/amd64 pms-amd64 "$autoupdate" [ "$cmd" = 'debug' ] && [ "$kind" = 'arm32v7' ] && debug linux/arm/v7 pms-arm32v7 "$autoupdate" -[ "$cmd" = 'debug' ] && [ "$kind" = 'arm64v8' ] && debug linux/arm64 pms-arm64v8 "$autoupdate" \ No newline at end of file +[ "$cmd" = 'debug' ] && [ "$kind" = 'arm64v8' ] && debug linux/arm64 pms-arm64v8 "$autoupdate" diff --git a/dev/docker-bake.hcl b/dev/docker-bake.hcl index 46eb751c..35e5df1e 100644 --- a/dev/docker-bake.hcl +++ b/dev/docker-bake.hcl @@ -37,4 +37,4 @@ target "plexmediaserver-autoupdate" { args = { TAG = "autoupdate" } -} \ No newline at end of file +} From c2fad2c8acaf5166e4b526ad44cfc6970f5a555b Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 29 Jun 2023 03:34:12 +0000 Subject: [PATCH 13/15] Do not install on every container start. --- README.md | 10 +++---- dev/dev.sh | 37 +++++++++++++++++------- root/etc/plex/plex-startup | 10 +------ root/installBinary.sh | 7 ++--- root/plex-common.sh | 59 ++++++++++++++++++++------------------ 5 files changed, 67 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 2e00f272..b4ec0559 100644 --- a/README.md +++ b/README.md @@ -141,14 +141,14 @@ uid=1001(myuser) gid=1001(myuser) groups=1001(myuser) In the above case, if you set the `PLEX_UID` and `PLEX_GID` to `1001`, then the permissions will match that of your own user. ## Tags -In addition to the standard version and `latest` tags, there is a special `autoupdate` tag. This container behave differently than your typical containers. The `autoupdate` container does **not** have any Plex Media Server binary installed. Instead, every time this container is run, it will fetch the latest version, install it and then start the Plex Media Server. +In addition to the standard version and `latest` tags, there is a special `autoupdate` tag. This container behaves differently than typical containers. The `autoupdate` container does **not** have any Plex Media Server binary installed. Instead, every time this container is run, it checks to see if the server is installed. If it is (because you've already started this container before) it starts the server. If it wasn't installed (because this is the first time the server is starting) it will install it, then start the server. -Since containers lose their state every time they are restarted, the binary is cached in `/config/install` so it won't need to be downloaded again, but it will need to be installed every time this container starts. - -This container will automatically check for new updates every day between 4:00am - 4:30am (according to timezone in `TZ`). +The `autoupdate` container will automatically check for new updates every day between 4:00am - 4:30am (according to timezone set in `TZ`). - **AUTO_UPDATE_CHANNEL** This variable can only be `public` or `beta` (default). The `public` value restricts this check to public versions only whereas `beta` value will fetch beta versions. If the server is not logged in or you do not have Plex Pass on your account, the `beta` tagged images will be restricted to publicly available versions only. -- **FORCE_UPDATE** Set this variable to `true` in order to ignore previously cached binaries in `/config/install` upon startup. This is generally not required, but provided just-in-case. You can also manually force an update by simply deleting the `/config/install` directory. + +### Forcing an update/install on startup +- Create an empty file called `_force_` in the `/config` directory. (i.e. `touch /config/_force_`) You can also manually force an update by simply recreating the image. Just restarting the container (or stopping and starting) will not normally update the existing installation within the container. To view the Docker images head over to [https://hub.docker.com/r/plexinc/pms-docker/tags/](https://hub.docker.com/r/plexinc/pms-docker/tags/) diff --git a/dev/dev.sh b/dev/dev.sh index 49f9715e..1ec1d54e 100755 --- a/dev/dev.sh +++ b/dev/dev.sh @@ -6,9 +6,12 @@ IFS=$'\n\t' # Assumes this is running on Linux (any distro) using (intel/amd). # This bakes the specific binary into the image, you can override these vars on command line -# DOCKERHUB_IMAGE=myorg/mycontainer ./dev/sh bake +# prompt> DOCKERHUB_IMAGE=myorg/mycontainer ./dev/sh bake VERSION_TO_BUILD=${VERSION_TO_BUILD:-"1.32.4.7195-7c8f9d3b6"} DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE:-"plexinc/pms-docker"} +# launch with KEEP=true to keep the container after starting/running it - manual cleanup required when done +# prompt> KEEP=true ./dev.sh debug arm64v8 autoupdate +KEEP=${KEEP:-} setup() { # Create a multi-arch buildx builder named PlexBuilder (if it doesn't exist) @@ -49,19 +52,33 @@ debug() { platform=$1 name=$2 autoupdate=$3 - if [ "$autoupdate" = "autoupdate" ]; then - name=$name:autoupdate - else - name=$name:latest - fi + [ "$autoupdate" = "autoupdate" ] && name=$name:autoupdate || name=$name:latest if [[ $platform == linux/arm* ]]; then # shellcheck disable=SC2064 - trap "trap - SIGTERM && docker stop debug-plex" SIGINT SIGTERM EXIT - docker run --rm --name debug-plex --platform "$platform" -e DEBUG=true "$name" & + trap "trap - SIGTERM && docker stop debug-${name/:/_}" SIGINT SIGTERM EXIT + if [ "${KEEP,,}" = "true" ]; then + if docker start "debug-${name/:/_}"; then + docker attach "debug-${name/:/_}" & + else + docker run --name "debug-${name/:/_}" --platform "$platform" -e DEBUG=true "$name" & + fi + else + docker run -rm --name "debug-${name/:/_}" --platform "$platform" -e DEBUG=true "$name" & + fi sleep 5 - docker exec -it debug-plex bash + docker exec -it "debug-${name/:/_}" bash else - docker run --rm --name debug-plex --platform "$platform" -e DEBUG=true -it "$name" bash + if [ "${KEEP,,}" = "true" ]; then + if docker start "debug-${name/:/_}"; then + # shellcheck disable=SC2064 + trap "trap - SIGTERM && docker stop debug-${name/:/_}" SIGINT SIGTERM EXIT + docker attach "debug-${name/:/_}" + else + docker run --name "debug-${name/:/_}" --platform "$platform" -e DEBUG=true -it "$name" bash + fi + else + docker run -rm --name "debug-${name/:/_}" --platform "$platform" -e DEBUG=true -it "$name" bash + fi fi } diff --git a/root/etc/plex/plex-startup b/root/etc/plex/plex-startup index 9c5d3c09..122caa5f 100755 --- a/root/etc/plex/plex-startup +++ b/root/etc/plex/plex-startup @@ -5,22 +5,14 @@ IFS=$'\n\t' # This script is called by the autoupdate, beta, and public tags only DEBUG=${DEBUG:-} -FORCE_UPDATE=${FORCE_UPDATE:-} # If we are debugging, enable trace if [ "${DEBUG,,}" = "true" ]; then set -x fi -# shellcheck source=../../plex-common.sh -. /plex-common.sh -CACHED_URL= -[[ -r /config/install/plexmediaserver.url ]] && CACHED_URL=$(< /config/install/plexmediaserver.url) -if [ ! "${FORCE_UPDATE,,}" = "true" ] && [ -n "$CACHED_URL" ] && [ -f /config/install/plexmediaserver.deb ]; then - echo "Installing previously downloaded plex version..." - installFromRawUrl "$CACHED_URL" -else +if [ -f /config/_force_ ] || ! dpkg --get-selections plexmediaserver 2> /dev/null | grep -wq "install"; then echo "Downloading latest plex version..." exec /etc/plex/plex-update fi diff --git a/root/installBinary.sh b/root/installBinary.sh index 47d99d51..299be4f1 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -38,7 +38,8 @@ else # This pre-installs the specified version in TAG into this docker image. remoteVersion= remoteFile= - getVersionInfo "${TAG}" "" remoteVersion remoteFile + remoteFileHashSha256= + getVersionInfo "${TAG}" "" remoteVersion remoteFile remoteFileHashSha256 if [ -z "${remoteVersion}" ] || [ -z "${remoteFile}" ]; then echo "Could not get install version" @@ -46,7 +47,5 @@ else fi echo "Attempting to install: ${remoteVersion}" - installFromUrl "${remoteFile}" - # delete unnecessary installer - rm -rf /config/install + installFromUrl "${remoteFile}" "${remoteFileHashSha256}" fi diff --git a/root/plex-common.sh b/root/plex-common.sh index c45f7886..6ac98ce5 100755 --- a/root/plex-common.sh +++ b/root/plex-common.sh @@ -3,7 +3,6 @@ set -euo pipefail IFS=$'\n\t' PLEX_UPDATE_CHANNEL=${PLEX_UPDATE_CHANNEL:-} -FORCE_UPDATE=${FORCE_UPDATE:-} CONT_CONF_FILE="/version.txt" @@ -31,6 +30,7 @@ function getVersionInfo { local token="$2" local -n getVersionInfo_remoteVersion=$3 local -n getVersionInfo_remoteFile=$4 + local -n getVersionInfo_remoteFileHashSha256=$5 local channel= local tokenNeeded=1 @@ -77,37 +77,40 @@ function installFromRawUrl { local remoteFile="$1" local expectedSha256="${2:-}" - # if download url matches and download is cached, then install it without download - [[ -r /config/install/plexmediaserver.url ]] && oldurl=$(< /config/install/plexmediaserver.url) - if [ ! "${FORCE_UPDATE,,}" = "true" ] && [ "$remoteFile" = "${oldurl:-}" ] && [ -f /config/install/plexmediaserver.deb ]; then - install "$remoteFile" - return $? - fi + rm -rf /tmp/plexmediaserver.deb + if curl --create-dirs -J -L -o /tmp/plexmediaserver.deb "${remoteFile}" ; then + if [ -n "$expectedSha256" ]; then + sha256=$(sha256sum /tmp/plexmediaserver.deb | awk '{ print $1 }') + # compare sha256, if provided + if [ ! "$expectedSha256" = "$sha256" ]; then + cleanup "Download failed: sha256sum does not match: expected=$expectedSha256 actual=$sha256" + fi + else + # no sha256, check if size appears ok + if [[ $(stat -c %s /tmp/plexmediaserver.deb) -lt 10000 ]]; then + # shellcheck disable=SC2119 + cleanup "Download failed: size appears wrong" + fi + fi + # looks good, move tmp into position - curl --create-dirs -J -L -o /config/install/tmp/plexmediaserver.deb "${remoteFile}" - local last=$? - local sha256; - sha256=$(sha256sum /config/install/tmp/plexmediaserver.deb | awk '{ print $1 }') - echo "$sha256" > /config/install/tmp/plexmediaserver.sha256 - echo "$remoteFile" > /config/install/tmp/plexmediaserver.url - # test if deb file size is ok, or if download failed - if [[ "$last" -gt "0" ]] || [[ $(stat -c %s /config/install/tmp/plexmediaserver.deb) -lt 10000 ]]; then - rm -rf /config/install/tmp - echo "Failed to fetch update: curl returned $last" - exit 1 - fi - # compare sha256, if provided - if [ -n "$expectedSha256" ] && [ ! "$expectedSha256" = "$sha256" ]; then - rm -rf /config/install/tmp - echo "Failed to fetch update: sha256sum does not match: expected=$expectedSha256 actual=$sha256" - exit 1 + install "$remoteFile" + else + # shellcheck disable=SC2119 + cleanup fi +} - # looks good, move tmp into position - mv /config/install/tmp/* /config/install && rm -rf /config/install/tmp - install "$remoteFile" +function cleanup { + local msg="${1:-"Download failed"}" + rm -rf /tmp/plexmediaserver.deb + echo "$msg" + exit 1 } function install { - dpkg -i --force-confold /config/install/plexmediaserver.deb + dpkg -i --force-confold /tmp/plexmediaserver.deb + rm -rf /tmp/plexmediaserver.deb + # clean up _force_ flag, if exists + rm -rf /config/_force_ } From 2cae64a15e1b6973ca8ef0cf11cefa0d86fff5bb Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 29 Jun 2023 03:55:55 +0000 Subject: [PATCH 14/15] fix cron schedule --- root/installBinary.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/installBinary.sh b/root/installBinary.sh index 299be4f1..6c986f39 100755 --- a/root/installBinary.sh +++ b/root/installBinary.sh @@ -31,7 +31,7 @@ elif [ "${TAG,,}" = "autoupdate" ] || [ "${TAG,,}" = "beta" ] || [ "${TAG,,}" = echo "SHELL=/bin/bash" > /etc/crontab echo "$(env | grep PATH):/command" >> /etc/crontab # Specify cron job: be nice to Plex servers - space out updates at 4:00am over 30m window - echo "0 4 * * * root perl -le 'sleep rand 30' ; /etc/plex/plex-update > /proc/1/fd/1 2>&1" >> /etc/crontab + echo "0 4 * * * root perl -le 'sleep rand 1800' ; /etc/plex/plex-update > /proc/1/fd/1 2>&1" >> /etc/crontab echo "Adding plex-startup to cont-init.d" ln -s /etc/plex/plex-startup /etc/cont-init.d/099-plex-startup else From fcd1c4309bc5d81e1c010e9464f075baef9f40c6 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Thu, 14 Dec 2023 21:07:13 -0500 Subject: [PATCH 15/15] bash strict mode prevent hw-transcode script from working properly --- root/etc/plex/plex-hw-transcode-and-connected-tuner | 4 ---- 1 file changed, 4 deletions(-) diff --git a/root/etc/plex/plex-hw-transcode-and-connected-tuner b/root/etc/plex/plex-hw-transcode-and-connected-tuner index 143cf879..edf5ab17 100755 --- a/root/etc/plex/plex-hw-transcode-and-connected-tuner +++ b/root/etc/plex/plex-hw-transcode-and-connected-tuner @@ -1,8 +1,4 @@ #!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -DEBUG=${DEBUG:-} # Check to make sure the devices exists. If not, exit as there is nothing for us to do if [ ! -e /dev/dri ] && [ ! -e /dev/dvb ]; then