From 10d8c0a824a707789be0327cf7ce95c98eccd52a Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Thu, 18 Sep 2025 08:18:51 +0100 Subject: [PATCH] security: run Docker container as non-root user Running containers as a non-root user is a long standing security practice. The changes ensure that the sourcebot user is created and has the correct level of permissions to run all its dependencies (postgres, redis and node). Please note that as a side effect, existing mounted volumes would need to have their ownership reviewed or it may not be able to access the files. This is specially the case for previous versions that would create said files as 0:0. To fix that, users can run chown -R 1500:1500 /path/.sourcebot. The chmod may also need to be a bit more strict in such cases, so changing that is advised: chown -R 0750 /path/.sourcebot. Signed-off-by: Paulo Gomes --- Dockerfile | 13 +++++++++++++ entrypoint.sh | 31 ++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index d04b2518a..e28237833 100644 --- a/Dockerfile +++ b/Dockerfile @@ -239,6 +239,17 @@ RUN mkdir -p /run/postgresql && \ chown -R postgres:postgres /run/postgresql && \ chmod 775 /run/postgresql +# To run as non-root, the user must be part of postgres, redis and node groups +RUN addgroup -g 1500 sourcebot && \ + adduser -D -u 1500 -h /app -S sourcebot && \ + adduser sourcebot postgres && \ + adduser sourcebot redis && \ + adduser sourcebot node && \ + chown -R sourcebot /data && \ + chown -R sourcebot /app && \ + mkdir /var/log/sourcebot && \ + chown sourcebot /var/log/sourcebot + COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY prefix-output.sh ./prefix-output.sh RUN chmod +x ./prefix-output.sh @@ -247,6 +258,8 @@ RUN chmod +x ./entrypoint.sh COPY default-config.json . +USER sourcebot + EXPOSE 3000 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" diff --git a/entrypoint.sh b/entrypoint.sh index 6753353fe..300eb18b5 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -30,19 +30,20 @@ fi # Check if DATA_CACHE_DIR exists, if not create it if [ ! -d "$DATA_CACHE_DIR" ]; then - mkdir -p "$DATA_CACHE_DIR" + mkdir -m 0750 -p "$DATA_CACHE_DIR" fi # Check if DATABASE_DATA_DIR exists, if not initialize it if [ "$DATABASE_EMBEDDED" = "true" ] && [ ! -d "$DATABASE_DATA_DIR" ]; then - echo -e "\e[34m[Info] Initializing database at $DATABASE_DATA_DIR...\e[0m" - mkdir -p $DATABASE_DATA_DIR && chown -R postgres:postgres "$DATABASE_DATA_DIR" - su postgres -c "initdb -D $DATABASE_DATA_DIR" + echo -e "\e[34m[Info] Initializing database at $DATABASE_D\ATA_DIR...\e[0m" + mkdir -m 0750 -p $DATABASE_DATA_DIR + + initdb -D "$DATABASE_DATA_DIR" fi # Create the redis data directory if it doesn't exist if [ ! -d "$REDIS_DATA_DIR" ]; then - mkdir -p $REDIS_DATA_DIR + mkdir -m 0750 -p $REDIS_DATA_DIR fi if [ -z "$SOURCEBOT_ENCRYPTION_KEY" ]; then @@ -134,13 +135,25 @@ echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURC # Start the database and wait for it to be ready before starting any other service if [ "$DATABASE_EMBEDDED" = "true" ]; then - su postgres -c "postgres -D $DATABASE_DATA_DIR" & - until pg_isready -h localhost -p 5432 -U postgres; do + postgres -D "$DATABASE_DATA_DIR" & + until pg_isready -h localhost -p 5432 -d sourcebot -U postgres; do echo -e "\e[34m[Info] Waiting for the database to be ready...\e[0m" sleep 1 + + # As postgres runs in the background, we must check if it is still + # running, otherwise the "until" loop will be running indefinitely. + if ! pgrep -x "postgres" > /dev/null; then + echo "postgres failed to run" + exit 1 + break + fi done - # Check if the database already exists, and create it if it dne + # Running as non-root we need to ensure the postgres account is created. + psql -U postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 \ + || createuser postgres -s + + # Check if the database already exists, and create it if it doesn't EXISTING_DB=$(psql -U postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'sourcebot'") if [ "$EXISTING_DB" = "1" ]; then @@ -159,4 +172,4 @@ yarn workspace @sourcebot/db prisma:migrate:prod mkdir -p /var/log/sourcebot # Run supervisord -exec supervisord -c /etc/supervisor/conf.d/supervisord.conf \ No newline at end of file +exec supervisord -c /etc/supervisor/conf.d/supervisord.conf