Changes related to runtime directory ownership while running under Docker

This commit is contained in:
Phin 2024-02-07 10:17:38 +05:30
parent cf19147b6c
commit 83c21ad526
4 changed files with 57 additions and 13 deletions

8
.github/release-notes/v2.4.5.md vendored Normal file
View file

@ -0,0 +1,8 @@
### Release Notes
* While running under Docker, the script will now change the ownership of the runtime directory mounted into the container to be in line with the UID and GID values specified through environment variables `DRPP_UID` and `DRPP_GID`, if both are set (#77). Refer to the [UID and GID section](https://github.com/phin05/discord-rich-presence-plex/blob/v2.4.5/README.md#uid-and-gid) of the README for more information.
### Installation Instructions
* [Regular](https://github.com/phin05/discord-rich-presence-plex/blob/v2.4.5/README.md#installation)
* [Docker](https://github.com/phin05/discord-rich-presence-plex/blob/v2.4.5/README.md#run-with-docker)

View file

@ -184,7 +184,7 @@ Images are available for the following platforms:
Mount a directory for persistent data (config file, cache file and log file) at `/app/data`.
The directory where Discord stores its inter-process communication Unix socket file needs to be mounted into the container at `/run/app`. The path for this would be the first non-null value from the values of the following environment variables: ([source](https://github.com/discord/discord-rpc/blob/963aa9f3e5ce81a4682c6ca3d136cddda614db33/src/connection_unix.cpp#L29C33-L29C33))
The runtime directory where Discord stores its inter-process communication Unix socket file needs to be mounted into the container at `/run/app`. The path for this would be the first non-null value from the values of the following environment variables in the environment Discord is running in: ([source](https://github.com/discord/discord-rpc/blob/963aa9f3e5ce81a4682c6ca3d136cddda614db33/src/connection_unix.cpp#L29C33-L29C33))
* XDG_RUNTIME_DIR
* TMPDIR
@ -193,15 +193,35 @@ The directory where Discord stores its inter-process communication Unix socket f
If all four environment variables aren't set, `/tmp` is used.
For example, if the environment variable `XDG_RUNTIME_DIR` is set to `/run/user/1000`, that would be the directory that needs to be mounted into the container at `/run/app`. If none of the environment variables are set, you need to mount `/tmp` into the container at `/run/app`.
For example, if the environment variable `XDG_RUNTIME_DIR` is set to `/run/user/1000`, that would be the runtime directory that needs to be mounted into the container at `/run/app`. If none of the environment variables are set, you need to mount `/tmp` into the container at `/run/app`.
### Example
### UID and GID
The environment variables `DRPP_UID` and `DRPP_GID` can be used to specify the UID and GID of the user Discord is running as. You can determine these by running `id` in your terminal as such user.
If both of the above environment variables are set, the script will change the ownership of `/run/app` and its contents to be in line with the specified UID and GID to prevent issues caused due to insufficient permissions. To skip this ownership change, set the environment variable `DRPP_NO_RUNTIME_DIR_CHOWN` to `true`. Skipping this is necessary only in cases where the runtime directory isn't dedicated exclusively to a single user.
The ownership of `/app` and its contents will be changed as well. If both of the above environment variables are set, they will determine the ownership. Otherwise, the existing ownership information of `/run/app` will be used.
### Other Info
If you're running the container for the first time (when there are no users in the config), set the `DRPP_PLEX_SERVER_NAME_INPUT` environment variable to the name of the Plex server to be added to the config file after user authentication, and check the container logs for the authentication link.
### Docker Compose example
```yaml
services:
drpp:
container_name: drpp
image: ghcr.io/phin05/discord-rich-presence-plex:latest
restart: unless-stopped
environment:
DRPP_UID: 1000
DRPP_GID: 1000
volumes:
- /run/user/1000:/run/app
- ./drpp:/app/data
```
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 `DRPP_PLEX_SERVER_NAME_INPUT` environment variable is set (see the [environment variables](#configuration---environment-variables) section above), and check the container logs for the authentication link.
### Containerised Discord

View file

@ -2,7 +2,7 @@ import os
import sys
name = "Discord Rich Presence for Plex"
version = "2.4.4"
version = "2.4.5"
plexClientID = "discord-rich-presence-plex"
discordClientID = "413407336082833418"
@ -18,3 +18,7 @@ isInteractive = sys.stdin and sys.stdin.isatty()
isInContainer = os.environ.get("DRPP_IS_IN_CONTAINER", "") == "true"
runtimeDirectory = "/run/app" if isInContainer else os.environ.get("XDG_RUNTIME_DIR", os.environ.get("TMPDIR", os.environ.get("TMP", os.environ.get("TEMP", "/tmp"))))
ipcPipeBase = runtimeDirectory if isUnix else r"\\?\pipe"
uid = int(os.environ.get("DRPP_UID", "-1"))
gid = int(os.environ.get("DRPP_GID", "-1"))
containerCwd = "/app"
noRuntimeDirChown = os.environ.get("DRPP_NO_RUNTIME_DIR_CHOWN", "") == "true"

22
main.py
View file

@ -1,4 +1,4 @@
from config.constants import isInContainer, runtimeDirectory
from config.constants import isInContainer, runtimeDirectory, uid, gid, containerCwd, noRuntimeDirChown
from utils.logging import logger
import os
import sys
@ -7,10 +7,22 @@ if isInContainer:
if not os.path.isdir(runtimeDirectory):
logger.error(f"Runtime directory does not exist. Ensure 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]
if os.geteuid() == 0: # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
if uid == -1 or gid == -1:
logger.warning(f"Environment variable(s) DRPP_UID and/or DRPP_GID are/is not set. Manually ensure appropriate ownership of {runtimeDirectory}")
statResult = os.stat(runtimeDirectory)
uid, gid = statResult.st_uid, statResult.st_gid
else:
if noRuntimeDirChown:
logger.warning(f"DRPP_NO_RUNTIME_DIR_CHOWN is set to true. Manually ensure appropriate ownership of {runtimeDirectory}")
else:
os.system(f"chmod 700 {runtimeDirectory}")
os.system(f"chown -R {uid}:{gid} {runtimeDirectory}")
os.system(f"chown -R {uid}:{gid} {containerCwd}")
os.setgid(gid) # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
os.setuid(uid) # pyright: ignore[reportGeneralTypeIssues,reportUnknownMemberType]
else:
logger.warning(f"Not running as the superuser. Manually ensure appropriate ownership of mounted contents")
else:
try:
import subprocess