Skip to content

Commit 10d8c0a

Browse files
committed
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 <pjbgf@linux.com>
1 parent 83a8d30 commit 10d8c0a

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,17 @@ RUN mkdir -p /run/postgresql && \
239239
chown -R postgres:postgres /run/postgresql && \
240240
chmod 775 /run/postgresql
241241

242+
# To run as non-root, the user must be part of postgres, redis and node groups
243+
RUN addgroup -g 1500 sourcebot && \
244+
adduser -D -u 1500 -h /app -S sourcebot && \
245+
adduser sourcebot postgres && \
246+
adduser sourcebot redis && \
247+
adduser sourcebot node && \
248+
chown -R sourcebot /data && \
249+
chown -R sourcebot /app && \
250+
mkdir /var/log/sourcebot && \
251+
chown sourcebot /var/log/sourcebot
252+
242253
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
243254
COPY prefix-output.sh ./prefix-output.sh
244255
RUN chmod +x ./prefix-output.sh
@@ -247,6 +258,8 @@ RUN chmod +x ./entrypoint.sh
247258

248259
COPY default-config.json .
249260

261+
USER sourcebot
262+
250263
EXPOSE 3000
251264
ENV PORT=3000
252265
ENV HOSTNAME="0.0.0.0"

entrypoint.sh

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,20 @@ fi
3030

3131
# Check if DATA_CACHE_DIR exists, if not create it
3232
if [ ! -d "$DATA_CACHE_DIR" ]; then
33-
mkdir -p "$DATA_CACHE_DIR"
33+
mkdir -m 0750 -p "$DATA_CACHE_DIR"
3434
fi
3535

3636
# Check if DATABASE_DATA_DIR exists, if not initialize it
3737
if [ "$DATABASE_EMBEDDED" = "true" ] && [ ! -d "$DATABASE_DATA_DIR" ]; then
38-
echo -e "\e[34m[Info] Initializing database at $DATABASE_DATA_DIR...\e[0m"
39-
mkdir -p $DATABASE_DATA_DIR && chown -R postgres:postgres "$DATABASE_DATA_DIR"
40-
su postgres -c "initdb -D $DATABASE_DATA_DIR"
38+
echo -e "\e[34m[Info] Initializing database at $DATABASE_D\ATA_DIR...\e[0m"
39+
mkdir -m 0750 -p $DATABASE_DATA_DIR
40+
41+
initdb -D "$DATABASE_DATA_DIR"
4142
fi
4243

4344
# Create the redis data directory if it doesn't exist
4445
if [ ! -d "$REDIS_DATA_DIR" ]; then
45-
mkdir -p $REDIS_DATA_DIR
46+
mkdir -m 0750 -p $REDIS_DATA_DIR
4647
fi
4748

4849
if [ -z "$SOURCEBOT_ENCRYPTION_KEY" ]; then
@@ -134,13 +135,25 @@ echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURC
134135

135136
# Start the database and wait for it to be ready before starting any other service
136137
if [ "$DATABASE_EMBEDDED" = "true" ]; then
137-
su postgres -c "postgres -D $DATABASE_DATA_DIR" &
138-
until pg_isready -h localhost -p 5432 -U postgres; do
138+
postgres -D "$DATABASE_DATA_DIR" &
139+
until pg_isready -h localhost -p 5432 -d sourcebot -U postgres; do
139140
echo -e "\e[34m[Info] Waiting for the database to be ready...\e[0m"
140141
sleep 1
142+
143+
# As postgres runs in the background, we must check if it is still
144+
# running, otherwise the "until" loop will be running indefinitely.
145+
if ! pgrep -x "postgres" > /dev/null; then
146+
echo "postgres failed to run"
147+
exit 1
148+
break
149+
fi
141150
done
142151

143-
# Check if the database already exists, and create it if it dne
152+
# Running as non-root we need to ensure the postgres account is created.
153+
psql -U postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 \
154+
|| createuser postgres -s
155+
156+
# Check if the database already exists, and create it if it doesn't
144157
EXISTING_DB=$(psql -U postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'sourcebot'")
145158

146159
if [ "$EXISTING_DB" = "1" ]; then
@@ -159,4 +172,4 @@ yarn workspace @sourcebot/db prisma:migrate:prod
159172
mkdir -p /var/log/sourcebot
160173

161174
# Run supervisord
162-
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf
175+
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf

0 commit comments

Comments
 (0)