From 239b6f54d32bdfa7655d6f83f60087db21de1952 Mon Sep 17 00:00:00 2001 From: Reto Brunner Date: Wed, 1 May 2024 13:28:54 +0200 Subject: [PATCH] feat: use the USER directive We are currently using a custom entrypoint script. However docker has a built in volume / user approach so we can get rid of this custom approach altogether. The benefit of this is that it just works across the stack and we don't need to teach users to run it with `--user node` and such. Further, using thelounge as an entrypoint means that you don't need to exec to a running container but can just spawn a throwaway container (probably with --rm) when you want to manage users etc. This does have some limitations though if people use bind mounts. Docker doesn't have the ability to auto chown things (podman does, with the U option to -v). So let's suggest named volumes instead (which is better anyways) Existing users should not be impacted, as the entrypoint script did the permission setup for them already, so even the new container should just continue to work. People who manually mess with the container will have to use --entrypoint /bin/sh or such, but they shouldn't treat containers like pets, so breaking that is of no concern. --- Dockerfile | 23 ++++++++++------------- README.md | 17 ++++++++--------- docker-compose.yml | 2 +- docker-entrypoint.sh | 8 -------- 4 files changed, 19 insertions(+), 31 deletions(-) delete mode 100755 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 687d7f2..20c9928 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,24 +10,21 @@ LABEL org.opencontainers.image.source "https://github.com/thelounge/thelounge-do LABEL org.opencontainers.image.version "${THELOUNGE_VERSION}" LABEL org.opencontainers.image.licenses "MIT" -ENV NODE_ENV production - +EXPOSE 9000 ENV THELOUNGE_HOME "/var/opt/thelounge" -VOLUME "${THELOUNGE_HOME}" - -# Expose HTTP. -ENV PORT 9000 -EXPOSE ${PORT} - -ENTRYPOINT ["docker-entrypoint.sh"] -CMD ["thelounge", "start"] -COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh - -# Install thelounge. +ENV NODE_ENV production RUN apk --update --no-cache --virtual build-deps add python3 build-base git && \ ln -sf python3 /usr/bin/python && \ yarn --non-interactive --frozen-lockfile global add thelounge@${THELOUNGE_VERSION} && \ yarn --non-interactive cache clean && \ apk del --purge build-deps && \ rm -rf /root/.cache /tmp /usr/bin/python + +RUN install -d -o node -g node "${THELOUNGE_HOME}" +# order of the directives matters, keep VOLUME below the dir creation +VOLUME "${THELOUNGE_HOME}" + +USER node:node +ENTRYPOINT ["/usr/local/bin/thelounge"] +CMD ["start"] diff --git a/README.md b/README.md index 5ecd030..e42df28 100644 --- a/README.md +++ b/README.md @@ -39,18 +39,18 @@ or starting a container manually: $ docker run --detach \ --name thelounge \ --publish 9000:9000 \ - --volume ~/.thelounge:/var/opt/thelounge \ + --volume thelounge:/var/opt/thelounge \ --restart always \ ghcr.io/thelounge/thelounge:latest ``` ### Executing commands in the container -Due to the way root permissions are dropped in the container, it's highly recommended to pass the `--user node` argument to any -commands you execute in the container via Docker to ensure that file permissions retain the correct owner, like so: +The container is setup to use an unprivileged user (node). +You can directly issue thelounge commands as follows: ``` -$ docker exec --user node -it [container_name] thelounge add MyUser +$ docker exec -it [container_name] thelounge help ``` ### Configuring identd @@ -64,7 +64,7 @@ $ docker run --detach \ --name thelounge \ --publish 113:9001 \ --publish 9000:9000 \ - --volume ~/.thelounge:/var/opt/thelounge \ + --volume thelounge:/var/opt/thelounge \ --restart always \ ghcr.io/thelounge/thelounge:latest ``` @@ -75,8 +75,7 @@ Refer to the [identd / oidentd docs](https://thelounge.chat/docs/guides/identd-a The Lounge reads and stores all of its configuration, logs and other data at `/var/opt/thelounge`. -By default, The Lounge will run using the `node (1000:1000)` system user in the container, leading to mounted data directories -on the host system being owned by said user. This is customizable by changing the container user (see [Container user (advanced usage)](#container-user-advanced-usage)). +By default, The Lounge will run using the `node (1000:1000)` system user in the container, meaning volume contents must be owned by said user. _You will probably want to persist the data at this location by using [one of the means](https://docs.docker.com/storage/) to do so._ @@ -85,7 +84,7 @@ _You will probably want to persist the data at this location by using [one of th Users can be added as follows: ```sh -$ docker exec --user node -it [container_name] thelounge add [username] +$ docker exec -it [container_name] thelounge add [username] ``` _Note: without [persisting data](#data-directory), added users will be lost when the container is removed._ @@ -99,7 +98,7 @@ change the host port in the port mapping. To make The Lounge available on e.g. p $ docker run --detach \ --name thelounge \ --publish 5000:9000 \ # Change host port to listen on port 5000 - --volume ~/.thelounge:/var/opt/thelounge \ + --volume thelounge:/var/opt/thelounge \ --restart always \ ghcr.io/thelounge/thelounge:latest ``` diff --git a/docker-compose.yml b/docker-compose.yml index 1b82c88..0eea2ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,4 +7,4 @@ services: - "9000:9000" restart: always volumes: - - ~/.thelounge:/var/opt/thelounge # bind lounge config from the host's file system + - thelounge:/var/opt/thelounge # uses a named volume on the host diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100755 index efbd313..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "thelounge" ] && [ "$(id -u)" = '0' ]; then - find "${THELOUNGE_HOME}" \! -user node -exec chown node '{}' + - exec su node -c "$*" -fi - -exec "$@"