mirror of
https://github.com/phin05/discord-rich-presence-plex
synced 2024-11-24 18:43:02 +00:00
Fix for permission issues while running under Docker
This commit is contained in:
parent
2bb484b61a
commit
46593378d9
6 changed files with 59 additions and 17 deletions
8
.github/release-notes/v2.4.4.md
vendored
Normal file
8
.github/release-notes/v2.4.4.md
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
### Release Notes
|
||||
|
||||
* While running under Docker, to resolve permission issues, the script will now change its user ID to match that of the owner of the runtime directory mounted into the container
|
||||
|
||||
### Installation Instructions
|
||||
|
||||
* [Regular](https://github.com/phin05/discord-rich-presence-plex/blob/v2.4.4/README.md#installation)
|
||||
* [Docker](https://github.com/phin05/discord-rich-presence-plex/blob/v2.4.4/README.md#run-with-docker)
|
|
@ -2,12 +2,9 @@ FROM python:3.10-alpine
|
|||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
RUN OSARCH="$TARGETOS-$TARGETARCH"; if [[ "$OSARCH" = "linux-386" || "$OSARCH" = "linux-arm" ]]; then apk --no-cache add build-base python3 python3-dev python3-tkinter openssl bash git meson py3-pip sudo freetype-dev fribidi-dev harfbuzz-dev jpeg-dev lcms2-dev libimagequant-dev openjpeg-dev tcl-dev tiff-dev tk-dev zlib-dev; fi
|
||||
ARG USERNAME=app
|
||||
ARG USER_UID_GID=10000
|
||||
RUN addgroup -g $USER_UID_GID $USERNAME && adduser -u $USER_UID_GID -G $USERNAME -D $USERNAME
|
||||
WORKDIR /app
|
||||
COPY requirements.txt .
|
||||
RUN pip install -U -r requirements.txt --no-cache-dir
|
||||
COPY . .
|
||||
ENV DRPP_CONTAINER_DEMOTION_UID_GID=$USER_UID_GID
|
||||
ENV DRPP_IS_IN_CONTAINER=true
|
||||
CMD ["python", "main.py"]
|
||||
|
|
37
README.md
37
README.md
|
@ -198,11 +198,44 @@ For example, if the environment variable `XDG_RUNTIME_DIR` is set to `/run/user/
|
|||
### Example
|
||||
|
||||
```
|
||||
docker run -v ./data:/app/data -v /run/user/1000:/run/app:ro -d --restart unless-stopped --name drpp ghcr.io/phin05/discord-rich-presence-plex:latest
|
||||
docker run -v ./drpp:/app/data -v /run/user/1000:/run/app:ro -d --restart unless-stopped --name drpp ghcr.io/phin05/discord-rich-presence-plex:latest
|
||||
```
|
||||
|
||||
If you're running the container for the first time (when there are no users in the config), make sure that the `PLEX_SERVER_NAME` environment variable is set (see the [environment variables](#configuration---environment-variables) section above), and check the container logs for the authentication link.
|
||||
|
||||
### Containerised Discord
|
||||
|
||||
If you wish to run Discord in a container as well, you need to mount a designated directory from the host machine into your Discord container at the path where Discord would store its Unix socket file. You can determine this path by checking the environment variables inside the container as per the [volumes](#volumes) section above, or you can set one of the environment variables yourself. That same host directory needs to be mounted into this script's container at `/run/app`. Ensure that the designated directory being mounted into the containers is owned by the user the containerized Discord process is running as.
|
||||
|
||||
Depending on the Discord container image you're using, there might be a lot of resource usage overhead and other complications.
|
||||
|
||||
#### Example using [kasmweb/discord](https://hub.docker.com/r/kasmweb/discord)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
kasmcord:
|
||||
container_name: kasmcord
|
||||
image: kasmweb/discord:1.14.0
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 6901:6901
|
||||
shm_size: 512m
|
||||
environment:
|
||||
VNC_PW: password
|
||||
XDG_RUNTIME_DIR: /run/user/1000
|
||||
volumes:
|
||||
- ./kasmcord:/run/user/1000
|
||||
user: "0"
|
||||
entrypoint: sh -c "chown kasm-user:kasm-user /run/user/1000 && su kasm-user -c \"/dockerstartup/kasm_default_profile.sh /dockerstartup/vnc_startup.sh /dockerstartup/kasm_startup.sh\""
|
||||
drpp:
|
||||
container_name: drpp
|
||||
image: ghcr.io/phin05/discord-rich-presence-plex:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./kasmcord:/run/app:ro
|
||||
- ./drpp:/app/data
|
||||
```
|
||||
|
||||
### Docker on Windows and macOS
|
||||
|
||||
The container image for this script is based on Linux. Docker uses virtualisation to run Linux containers on Windows and macOS. In such cases, if you want to run this script in a container, you need to run Discord in a container as well, using an image based on Linux, like [kasmweb/discord](https://hub.docker.com/r/kasmweb/discord) for example. You can mount a designated directory from the host machine into the Discord container at the path where Discord would store its Unix socket file. You can determine this path by checking the environment variables inside the container as per the [volumes](#volumes) section above. That same host directory needs to be mounted into the script's container as well at `/run/app`. This method is not recommended, because depending on the Discord container image you're using, there might be a lot of resource usage overhead or other complications related to containerising interactive desktop applications.
|
||||
The container image for this script is based on Linux. Docker uses virtualisation to run Linux containers on Windows and macOS. In such cases, if you want to run this script in a container, you need to run Discord in a container as well, as per the instructions above.
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
import sys
|
||||
|
||||
name = "Discord Rich Presence for Plex"
|
||||
version = "2.4.3"
|
||||
version = "2.4.4"
|
||||
|
||||
plexClientID = "discord-rich-presence-plex"
|
||||
discordClientID = "413407336082833418"
|
||||
|
@ -15,4 +15,5 @@ logFilePath = os.path.join(dataDirectoryPath, "console.log")
|
|||
isUnix = sys.platform in ["linux", "darwin"]
|
||||
processID = os.getpid()
|
||||
isInteractive = sys.stdin and sys.stdin.isatty()
|
||||
containerDemotionUidGid = os.environ.get("DRPP_CONTAINER_DEMOTION_UID_GID", "")
|
||||
isInContainer = os.environ.get("DRPP_IS_IN_CONTAINER", "") == "true"
|
||||
runtimeDirectory = "/run/app"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from config.constants import discordClientID, isUnix, processID
|
||||
from config.constants import discordClientID, isUnix, processID, runtimeDirectory
|
||||
from typing import Any, Optional
|
||||
from utils.logging import logger
|
||||
import asyncio
|
||||
|
@ -13,7 +13,7 @@ class DiscordIpcService:
|
|||
def __init__(self, ipcPipeNumber: Optional[int]):
|
||||
ipcPipeNumber = ipcPipeNumber or -1
|
||||
ipcPipeNumbers = range(10) if ipcPipeNumber == -1 else [ipcPipeNumber]
|
||||
ipcPipeBase = ("/run/app" if os.path.isdir("/run/app") else os.environ.get("XDG_RUNTIME_DIR", os.environ.get("TMPDIR", os.environ.get("TMP", os.environ.get("TEMP", "/tmp"))))) if isUnix else r"\\?\pipe"
|
||||
ipcPipeBase = (runtimeDirectory if os.path.isdir(runtimeDirectory) else os.environ.get("XDG_RUNTIME_DIR", os.environ.get("TMPDIR", os.environ.get("TMP", os.environ.get("TEMP", "/tmp"))))) if isUnix else r"\\?\pipe"
|
||||
self.ipcPipes: list[str] = []
|
||||
for ipcPipeNumber in ipcPipeNumbers:
|
||||
pipeFilename = f"discord-ipc-{ipcPipeNumber}"
|
||||
|
|
17
main.py
17
main.py
|
@ -1,12 +1,15 @@
|
|||
from config.constants import isUnix, containerDemotionUidGid
|
||||
from config.constants import isInContainer, runtimeDirectory
|
||||
import os
|
||||
import sys
|
||||
|
||||
if isUnix and containerDemotionUidGid:
|
||||
uidGid = int(containerDemotionUidGid)
|
||||
os.system(f"chown -R {uidGid}:{uidGid} {os.path.dirname(os.path.realpath(__file__))}")
|
||||
os.setgid(uidGid) # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
|
||||
os.setuid(uidGid) # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
|
||||
if isInContainer:
|
||||
if not os.path.isdir(runtimeDirectory):
|
||||
print(f"Runtime directory does not exist. Make sure that it is mounted into the container at {runtimeDirectory}")
|
||||
exit(1)
|
||||
statResult = os.stat(runtimeDirectory)
|
||||
os.system(f"chown -R {statResult.st_uid}:{statResult.st_gid} {os.path.dirname(os.path.realpath(__file__))}")
|
||||
os.setgid(statResult.st_gid) # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
|
||||
os.setuid(statResult.st_uid) # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
|
||||
else:
|
||||
try:
|
||||
import subprocess
|
||||
|
@ -60,7 +63,7 @@ def main() -> None:
|
|||
logger.info("No users found in the config file")
|
||||
user = authNewUser()
|
||||
if not user:
|
||||
exit()
|
||||
exit(1)
|
||||
config["users"].append(user)
|
||||
saveConfig()
|
||||
plexAlertListeners = [PlexAlertListener(user["token"], server) for user in config["users"] for server in user["servers"]]
|
||||
|
|
Loading…
Reference in a new issue