├── VERSION ├── scripts ├── plex-url.sh └── entrypoint.sh ├── Dockerfile ├── .github └── workflows │ └── release.yml ├── LICENSE └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 1.40.4.8679-424562606 -------------------------------------------------------------------------------- /scripts/plex-url.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | VERSION=$1 6 | 7 | case $2 in 8 | arm64) 9 | TARGETARCH=arm64 10 | ;; 11 | arm) 12 | TARGETARCH=armhf 13 | ;; 14 | *) 15 | echo "Error: unknown target arch" 16 | exit 1 17 | ;; 18 | esac 19 | 20 | echo https://downloads.plex.tv/plex-media-server-new/${VERSION}/debian/plexmediaserver_${VERSION}_${TARGETARCH}.deb 21 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim AS src 2 | 3 | ARG TARGETARCH 4 | 5 | ENV DEBIAN_FRONTEND="noninteractive" \ 6 | PLEX_PATH=/usr/lib/plexmediaserver \ 7 | PLEX_USER_NAME=plex \ 8 | PLEX_CONFIG_DIR=/config \ 9 | PLEX_DATA_DIR=/data \ 10 | PLEX_TRANSCODE_DIR=/transcode 11 | 12 | RUN apt-get update \ 13 | && apt-get install -y wget ca-certificates 14 | 15 | COPY VERSION . 16 | COPY scripts/plex-url.sh . 17 | 18 | # Download / install Plex 19 | RUN PLEX_VERSION=$(cat ./VERSION) \ 20 | && PLEX_URL=$(./plex-url.sh $PLEX_VERSION $TARGETARCH) \ 21 | && wget --no-verbose -O /tmp/plex.deb $PLEX_URL \ 22 | && dpkg -i /tmp/plex.deb \ 23 | && rm -f /tmp/plexmediaserver.deb 24 | 25 | # Add user 26 | RUN useradd -U -d $PLEX_CONFIG_DIR -s /bin/false $PLEX_USER_NAME \ 27 | && usermod -G users $PLEX_USER_NAME 28 | 29 | COPY scripts/entrypoint.sh . 30 | RUN chmod +x entrypoint.sh 31 | 32 | ENTRYPOINT [ "/entrypoint.sh" ] 33 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | docker: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | - name: Set Version 15 | id: version 16 | run: | 17 | echo "::set-output name=VERSION::$(cat VERSION)" 18 | - name: Set up QEMU 19 | uses: docker/setup-qemu-action@v1 20 | - name: Set up Docker Buildx 21 | uses: docker/setup-buildx-action@v1 22 | - name: Login to DockerHub 23 | uses: docker/login-action@v1 24 | with: 25 | username: ${{ secrets.DOCKERHUB_USERNAME }} 26 | password: ${{ secrets.DOCKERHUB_TOKEN }} 27 | - name: Build and Push 28 | uses: docker/build-push-action@v2 29 | with: 30 | context: . 31 | platforms: linux/arm,linux/arm64 32 | push: true 33 | tags: greensheep/plex-server-docker-rpi:${{ steps.version.outputs.VERSION }},greensheep/plex-server-docker-rpi:latest 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Tom Hill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /scripts/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PLEX_USER_ID=$(id -u $PLEX_USER_NAME) 6 | PLEX_GROUP_ID=$(id -g $PLEX_USER_NAME) 7 | 8 | echo "=> Plex user id: $PLEX_USER_ID" 9 | 10 | # If a user id was supplied, and this doesn't match the plex user, update it 11 | if [ ! -z "${SET_PLEX_UID}" ]; then 12 | if [ ! "$PLEX_USER_ID" -eq "${SET_PLEX_UID}" ]; then 13 | 14 | # Updating the user id is causing the following error: 15 | # usermod: Failed to change ownership of the home directory 16 | # To get round this, create a temporary home dir, update the 17 | # user id, then set it back 18 | TEMP_HOME_DIR=/tmp/plexhomedir 19 | mkdir $TEMP_HOME_DIR 20 | usermod -d $TEMP_HOME_DIR $PLEX_USER_NAME 21 | 22 | # Update user id 23 | usermod -o -u "${SET_PLEX_UID}" $PLEX_USER_NAME 24 | echo "=> Updated plex user id to $SET_PLEX_UID" 25 | 26 | usermod -d $PLEX_CONFIG_DIR $PLEX_USER_NAME 27 | rm -rf $TEMP_HOME_DIR 28 | 29 | else 30 | echo "=> Requested user id ($SET_PLEX_UID) matches plex user id ($PLEX_USER_ID), nothing to do" 31 | fi 32 | fi 33 | 34 | echo "=> Plex group id: $PLEX_GROUP_ID" 35 | 36 | # Same for group id 37 | if [ ! -z "${SET_PLEX_GID}" ]; then 38 | if [ ! "$PLEX_GROUP_ID" -eq "${SET_PLEX_GID}" ]; then 39 | groupmod -o -g "${SET_PLEX_GID}" $PLEX_USER_NAME 40 | echo "=> Updated plex group id to $SET_PLEX_GID" 41 | else 42 | echo "=> Requested group id ($SET_PLEX_GID) matches plex group id ($PLEX_GROUP_ID), nothing to do" 43 | fi 44 | fi 45 | 46 | # Remove any previous pid file. Plex wont start if this file is left over from a previous run 47 | rm -rf /config/Library/Application\ Support/Plex\ Media\ Server/plexmediaserver.pid 48 | 49 | # Start plex! 50 | echo '=> Starting plex... to load the UI go to: http://{ip address of Pi}:32400/web' 51 | echo 52 | su plex -s $PLEX_PATH/Plex\ Media\ Server 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Docker images: https://hub.docker.com/r/greensheep/plex-server-docker-rpi/tags 2 | 3 | # Plex Server for Raspberry Pi 4 | 5 | A simple way to run a plex media server in Docker on the Raspberry Pi. 6 | 7 | **NOTE: The Pi 1 is NOT supported.** 8 | 9 | ## Usage 10 | 11 | Install docker on your raspberry pi. There are numerous ways to do this but the easiest is to run: 12 | 13 | ```sh 14 | curl -sSL https://get.docker.com | sh 15 | ``` 16 | 17 | _Source: https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi_ 18 | 19 | Next, you'll need to create three local folders for the plex config, data and transcode volumes (I have all of these on an external HDD because they get very large). For example: 20 | 21 | ```sh 22 | mkdir -p ~/media/plex/{config,data,transcode} 23 | ``` 24 | 25 | Using the above folders, run the following to start plex: 26 | 27 | ```sh 28 | docker run \ 29 | -d \ 30 | --name plex \ 31 | --net host \ 32 | --restart always \ 33 | --volume $(echo $HOME)/media/plex/config:/config \ 34 | --volume $(echo $HOME)/media/plex/data:/data \ 35 | --volume $(echo $HOME)/media/plex/transcode:/transcode \ 36 | greensheep/plex-server-docker-rpi:latest 37 | ``` 38 | 39 | After around 30 seconds, the Plex web admin should be available at `http://{ip address of Pi}:32400/web`. 40 | 41 | ## NFS Shares 42 | 43 | If you have permission issues using NFS shares as the mounted volumes, set the `SET_PLEX_UID` and `SET_PLEX_GID` environment variables to the user/group id of the owner of those directories. 44 | 45 | ### To find the uid/gid: 46 | 47 | ``` 48 | # show user/group owner of a directory 49 | ls -n ~/media/plex/config 50 | 51 | # outputs something like this: 52 | # drwxr-xr-x 20 1001 1001 4096 Apr 9 19:00 config 53 | # ^ uid ^ gid 54 | ``` 55 | 56 | ### Updated `docker run`: 57 | 58 | ```sh 59 | docker run \ 60 | -d \ 61 | --name plex \ 62 | --net host \ 63 | --restart always \ 64 | -e SET_PLEX_UID=1001 \ 65 | -e SET_PLEX_GID=1001 \ 66 | --volume $(echo $HOME)/media/plex/config:/config \ 67 | --volume $(echo $HOME)/media/plex/data:/data \ 68 | --volume $(echo $HOME)/media/plex/transcode:/transcode \ 69 | greensheep/plex-server-docker-rpi:latest 70 | ``` 71 | 72 | ## Updating 73 | 74 | Plex cannot be updated via the web ui. Run the following to download and run a new version: 75 | 76 | ```sh 77 | docker pull greensheep/plex-server-docker-rpi:latest 78 | docker stop plex 79 | docker rm -f plex 80 | # `docker run ...` command from above! 81 | ``` 82 | 83 | ## Transcoding 84 | 85 | The Pi isn't powerful enough for transcoding but if you have media that will direct play on your client it works great! I've tested this on the Pi 2 (Hypriot) and 3 (Arch) and 4 (ubuntu). 86 | 87 | Be sure to set the "Transcoder temporary directory" setting to `/transcode` in the Plex -> Transcoder settings UI. 88 | 89 | ## Development 90 | 91 | To build the images yourself clone this repository and run the following: 92 | 93 | ```sh 94 | sudo docker buildx build -t plex-dev:latest --platform linux/arm,linux/arm64 . 95 | ``` 96 | --------------------------------------------------------------------------------