diff --git a/Dockerfile b/Dockerfile index d1103a8..847dcc0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,8 +4,8 @@ FROM python:3.9-slim # Set the working directory WORKDIR /app -# Install system dependencies (including gettext for envsubst) -RUN apt-get update && apt-get install -y gettext && rm -rf /var/lib/apt/lists/* +# Install system dependencies (including gettext for envsubst and gosu for privilege dropping) +RUN apt-get update && apt-get install -y gettext gosu && rm -rf /var/lib/apt/lists/* # Install Python dependencies COPY requirements.txt . @@ -30,7 +30,7 @@ ARG UID=1000 ARG GID=1000 RUN groupadd -g ${GID} appuser && useradd -u ${UID} -g ${GID} -s /bin/sh -M appuser RUN chown -R appuser:appuser /app /entrypoint.sh -USER appuser +# Entrypoint runs as root, fixes volume permissions, then drops to appuser via gosu # Use the entrypoint script as the container's command CMD ["/entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh index 23dbe32..288fb4c 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,7 +1,12 @@ #!/bin/sh +# Fix ownership of the data directory so appuser can write the database. +# This runs as root (no USER directive in Dockerfile) and is safe because +# we immediately drop privileges via gosu before starting the app. +DATA_DIR=$(dirname "${DATABASE_PATH:-/data/guestbook.db}") +chown -R appuser:appuser "$DATA_DIR" + # Process index.html.template to create index.html -# Adjust the path if your template is located somewhere else envsubst < /app/templates/index.html.template > /app/templates/index.html -# Start Gunicorn; using an environment variable for workers (default is 3) -exec gunicorn --bind 0.0.0.0:8000 app:app --workers ${GUNICORN_WORKERS:-3} +# Drop to appuser and start Gunicorn +exec gosu appuser gunicorn --bind 0.0.0.0:8000 app:app --workers ${GUNICORN_WORKERS:-3}