Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Non-root user #91

Open
pythoninthegrass opened this issue May 30, 2024 · 1 comment
Open

feat: Non-root user #91

pythoninthegrass opened this issue May 30, 2024 · 1 comment

Comments

@pythoninthegrass
Copy link

Is your feature request related to a problem? Please describe.
Currently trying to run the container as a non-root user. Despite changing PUID/PGID, the container runs as root.

Describe the solution you'd like
Standard user should be available with privilege escalation where needed.

Describe alternatives you've considered
Tried making a custom Dockerfile from your official version that sets user/group permissions and changes to the standard user before the commented out CMD/ENTRYPOINT. The lsio images appear to run as root with an s6-overlay preventing normal docker directives, which was anecdotally confirmed by a mod at their forums (forget the URL.)

My suspicion is that the s6 overlay scripts are clobbering the Dockerfile config USER directive.

Additional context
It's entirely possible that the permissions are relatively locked down upstream, but if possible, it'd be nice to be able to set an env var in the compose file, and that ensures a standard user is given least principle access at runtime.

The logs show:

status-page  | ───────────────────────────────────────
status-page  | GID/UID
status-page  | ───────────────────────────────────────
status-page  |
status-page  | User UID:    1002
status-page  | User GID:    1002

with exec'ing into the container returning

root@5f90af9c8cb9:/app# cat /etc/shadow
root:!::0:::::
<SNIP>
guest:!::0:::::
nobody:!::0:::::
abc:!:19865::::::
root@5f90af9c8cb9:/app# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

FWIW my custom user is abc.

@pythoninthegrass
Copy link
Author

Dockerfile

# syntax=docker/dockerfile:1.6

FROM lsiobase/alpine:3.19 as base

ENV TZ=Etc/UTC

RUN <<EOF
#!/usr/bin/env bash
echo "**** install build packages ****"
apk add --no-cache nodejs npm
echo "**** cleanup ****"
rm -rf \
    /root/.cache \
    /tmp/*
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EOF

WORKDIR /app

ARG data_dir=/app/config

VOLUME $data_dir

ENV CONFIG_DIR=$data_dir

COPY docker/root/ /

ENV PUBLIC_KENER_FOLDER=${CONFIG_DIR}/static
ENV MONITOR_YAML_PATH=${CONFIG_DIR}/monitors.yaml
ENV SITE_YAML_PATH=${CONFIG_DIR}/site.yaml

FROM base as build

ARG USERNAME=abc
ARG PUID=1002
ARG PGID=$PUID

COPY --chown=${PUID}:${PGID} . /app

# TODO: mount node_modules as volume to speed up build
# TODO: avoid using mkdir and chown
RUN mkdir -p "${CONFIG_DIR}/static" \
    && npm install \
    && chown -R root:root node_modules \
    && npm run kener:build

FROM base as app

WORKDIR /app

ARG USERNAME=abc
ARG PUID=1002
ARG PGID=$PUID

RUN groupmod --gid $PGID $USERNAME \
    && usermod --uid $PUID --gid $PGID $USERNAME \
    && chown -R ${PUID}:${PGID} /app

COPY --chown=${PUID}:${PGID} package*.json .
COPY --from=base /usr/local/bin /usr/local/bin
COPY --from=base /usr/local/lib /usr/local/lib
COPY --chown=${PUID}:${PGID} scripts /app/scripts
COPY --chown=${PUID}:${PGID} static /app/static
COPY --chown=${PUID}:${PGID} config /app/config
COPY --chown=${PUID}:${PGID} src/lib/helpers.js /app/src/lib/helpers.js
COPY --from=build --chown=${PUID}:${PGID} /app/build /app/build
COPY --from=build --chown=${PUID}:${PGID} /app/prod.js /app/prod.js
COPY --from=build --chown=${PUID}:${PGID} ${CONFIG_DIR}/static ${CONFIG_DIR}/static

ENV NODE_ENV=production

RUN npm install --omit=dev \
    && npm cache clean --force \
    && chown -R ${PUID}:${PGID} node_modules

ARG WEB_PORT=3000
ENV PORT=$WEB_PORT

EXPOSE $PORT

USER $USERNAME

# leave entrypoint blank!
# uses LSIO s6-init entrypoint with scripts
# that populate CONFIG_DIR with static dir, monitor/site.yaml when dir is empty
# and chown's all files so they are owned by proper user based on PUID/GUID env

docker-compose.yml

# version: '3.9'

services:
  kener:
    container_name: status-page
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - .env
    environment:
      - TZ=Etc/UTC
      - PUID=1002
      - PGID=1002
      - PORT=3000
      - CONFIG_DIR=/app/config
      - PUBLIC_KENER_FOLDER=/app/config/static
      - MONITOR_YAML_PATH=/app/config/monitors.yaml
      - SITE_YAML_PATH=/app/config/site.yaml
    ports:
      - '5173:3000/tcp'
    working_dir: /app
    volumes:
      - ./config:/app/config
      - ./static:/app/static
      - ./scripts:/app/scripts
    restart: unless-stopped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant