diff --git a/.dockerignore b/.dockerignore index fa0bb8a..16a0945 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ * !maloja +!container !Containerfile !requirements.txt !pyproject.toml diff --git a/Containerfile b/Containerfile index ed8a983..98fec19 100644 --- a/Containerfile +++ b/Containerfile @@ -1,40 +1,59 @@ -FROM alpine:3.15 -# Python image includes two Python versions, so use base Alpine - -# Based on the work of Jonathan Boeckel +FROM lsiobase/alpine:3.17 as base WORKDIR /usr/src/app -# Install run dependencies first -RUN apk add --no-cache python3 py3-lxml tzdata +COPY --chown=abc:abc . . -# system pip could be removed after build, but apk then decides to also remove all its -# python dependencies, even if they are explicitly installed as python packages -# whut +# based on https://github.com/linuxserver/docker-pyload-ng/blob/main/Dockerfile +# Everything is run in one command so we can purge all build dependencies and cache in the same layer after maloja is installed +# +# -- it may be possible to decrease image size slightly by using build stage and copying all site-packages to runtime stage +# but the image is already pretty small (117mb uncompressed, ~40mb compressed) RUN \ - apk add py3-pip && \ - pip install wheel + echo "**** install build packages ****" && \ + apk add --no-cache --virtual=build-deps \ + gcc \ + g++ \ + python3-dev \ + libxml2-dev \ + libxslt-dev \ + libffi-dev \ + libc-dev \ + py3-pip \ + linux-headers && \ + echo "**** install runtime packages ****" && \ + apk add --no-cache \ + python3 \ + py3-lxml \ + tzdata && \ + echo "**** install pip dependencies ****" && \ + python3 -m ensurepip && \ + pip3 install -U --no-cache-dir \ + pip \ + wheel && \ + echo "**** install maloja requirements ****" && \ + pip3 install --no-cache-dir -r requirements.txt && \ + echo "**** install maloja ****" && \ + pip3 install /usr/src/app && \ + echo "**** cleanup ****" && \ + apk del --purge \ + build-deps && \ + rm -rf \ + /tmp/* \ + ${HOME}/.cache - -COPY ./requirements.txt ./requirements.txt - -RUN \ - apk add --no-cache --virtual .build-deps gcc g++ python3-dev libxml2-dev libxslt-dev libffi-dev libc-dev py3-pip linux-headers && \ - pip install --no-cache-dir -r requirements.txt && \ - apk del .build-deps - - -# no chance for caching below here - -COPY . . - -RUN pip install /usr/src/app +COPY container/root/ / # Docker-specific configuration # defaulting to IPv4 is no longer necessary (default host is dual stack) ENV MALOJA_SKIP_SETUP=yes ENV PYTHONUNBUFFERED=1 +# Prevents breaking change for previous container that ran maloja as root +# which meant MALOJA_DATA_DIRECTORY was created by and owned by root (UID 0) +# +# On linux hosts (non-podman rootless) these variables should be set to the host user that should own the host folder bound to MALOJA_DATA_DIRECTORY +ENV PUID=0 +ENV PGID=0 + EXPOSE 42010 -# use exec form for better signal handling https://docs.docker.com/engine/reference/builder/#entrypoint -ENTRYPOINT ["maloja", "run"] diff --git a/README.md b/README.md index ddd59fe..2624cb4 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,23 @@ An example of a minimum run configuration to access maloja via `localhost:42010` docker run -p 42010:42010 -v $PWD/malojadata:/mljdata -e MALOJA_DATA_DIRECTORY=/mljdata krateng/maloja ``` +#### Linux Host + +**NOTE:** If you are using [rootless containers with Podman](https://developers.redhat.com/blog/2020/09/25/rootless-containers-with-podman-the-basics#why_podman_) this DOES NOT apply to you. + +If you are running Docker on a **Linux Host** you should specify `user:group` ids of the user who owns the folder on the host machine bound to `MALOJA_DATA_DIRECTORY` in order to avoid [docker file permission problems.](https://ikriv.com/blog/?p=4698) These can be specified using the [environmental variables **PUID** and **PGID**.](https://docs.linuxserver.io/general/understanding-puid-and-pgid) + +To get the UID and GID for the current user run these commands from a terminal: + +* `id -u` -- prints UID (EX `1000`) +* `id -g` -- prints GID (EX `1001`) + +The modified run command with these variables would look like: + +```console + docker run -e PUID=1000 -e PGID=1001 -p 42010:42010 -v $PWD/malojadata:/mljdata -e MALOJA_DATA_DIRECTORY=/mljdata krateng/maloja +``` + ### Extras * If you'd like to display images, you will need API keys for [Last.fm](https://www.last.fm/api/account/create) and [Spotify](https://developer.spotify.com/dashboard/applications). These are free of charge! diff --git a/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/dependencies.d/init-config b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/dependencies.d/init-config new file mode 100644 index 0000000..e69de29 diff --git a/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/run b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/run new file mode 100755 index 0000000..a8cdb4e --- /dev/null +++ b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/run @@ -0,0 +1,10 @@ +#!/usr/bin/with-contenv bash + +if [ "$(s6-setuidgid abc id -u)" = "0" ]; then + echo "-------------------------------------" + echo "WARN: Running as root! If you meant to do this than this message can be ignored." + echo "If you are running this container on a *linux* host and are not using podman rootless you SHOULD" + echo "change the ENVs PUID and PGID for this container to ensure correct permissions on your config folder." + echo -e "See: https://github.com/krateng/maloja#linux-host\n" + echo -e "-------------------------------------\n" +fi \ No newline at end of file diff --git a/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/type b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/type @@ -0,0 +1 @@ +oneshot diff --git a/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/up b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/up new file mode 100644 index 0000000..0e8f49b --- /dev/null +++ b/container/root/etc/s6-overlay/s6-rc.d/init-permission-check/up @@ -0,0 +1 @@ +/etc/s6-overlay/s6-rc.d/init-permission-check/run diff --git a/container/root/etc/s6-overlay/s6-rc.d/svc-python/dependencies.d/init-services b/container/root/etc/s6-overlay/s6-rc.d/svc-python/dependencies.d/init-services new file mode 100644 index 0000000..e69de29 diff --git a/container/root/etc/s6-overlay/s6-rc.d/svc-python/run b/container/root/etc/s6-overlay/s6-rc.d/svc-python/run new file mode 100755 index 0000000..276e6be --- /dev/null +++ b/container/root/etc/s6-overlay/s6-rc.d/svc-python/run @@ -0,0 +1,7 @@ +#!/usr/bin/with-contenv bash + +# used https://github.com/linuxserver/docker-wikijs/blob/master/root/etc/s6-overlay/s6-rc.d/svc-wikijs/run as a template + +echo -e "\nMaloja is starting!" +exec \ + s6-setuidgid abc python -m maloja run \ No newline at end of file diff --git a/container/root/etc/s6-overlay/s6-rc.d/svc-python/type b/container/root/etc/s6-overlay/s6-rc.d/svc-python/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/container/root/etc/s6-overlay/s6-rc.d/svc-python/type @@ -0,0 +1 @@ +longrun diff --git a/container/root/etc/s6-overlay/s6-rc.d/user/contents.d/init-permission-check b/container/root/etc/s6-overlay/s6-rc.d/user/contents.d/init-permission-check new file mode 100644 index 0000000..e69de29 diff --git a/container/root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-python b/container/root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-python new file mode 100644 index 0000000..e69de29