Skip to content

Commit 0dc8083

Browse files
pjbgfbrendan-kellam
authored andcommitted
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 26ec7af commit 0dc8083

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,26 @@ RUN mkdir -p /run/postgresql && \
241241
chown -R postgres:postgres /run/postgresql && \
242242
chmod 775 /run/postgresql
243243

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

261+
262+
USER sourcebot
263+
250264
EXPOSE 3000
251265
ENV PORT=3000
252266
ENV HOSTNAME="0.0.0.0"

entrypoint.sh

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

4949
# Check if DATA_CACHE_DIR exists, if not create it
5050
if [ ! -d "$DATA_CACHE_DIR" ]; then
51-
mkdir -p "$DATA_CACHE_DIR"
51+
mkdir -m 0750 -p "$DATA_CACHE_DIR"
5252
fi
5353

5454
# Check if DATABASE_DATA_DIR exists, if not initialize it
5555
if [ "$DATABASE_EMBEDDED" = "true" ] && [ ! -d "$DATABASE_DATA_DIR" ]; then
56-
echo -e "\e[34m[Info] Initializing database at $DATABASE_DATA_DIR...\e[0m"
57-
mkdir -p $DATABASE_DATA_DIR && chown -R postgres:postgres "$DATABASE_DATA_DIR"
58-
su postgres -c "initdb -D $DATABASE_DATA_DIR"
56+
echo -e "\e[34m[Info] Initializing database at $DATABASE_D\ATA_DIR...\e[0m"
57+
mkdir -m 0750 -p $DATABASE_DATA_DIR
58+
59+
initdb -D "$DATABASE_DATA_DIR"
5960
fi
6061

6162
# Create the redis data directory if it doesn't exist
6263
if [ ! -d "$REDIS_DATA_DIR" ]; then
63-
mkdir -p $REDIS_DATA_DIR
64+
mkdir -m 0750 -p $REDIS_DATA_DIR
6465
fi
6566

6667
if [ -z "$SOURCEBOT_ENCRYPTION_KEY" ]; then
@@ -152,13 +153,25 @@ echo "{\"version\": \"$NEXT_PUBLIC_SOURCEBOT_VERSION\", \"install_id\": \"$SOURC
152153

153154
# Start the database and wait for it to be ready before starting any other service
154155
if [ "$DATABASE_EMBEDDED" = "true" ]; then
155-
su postgres -c "postgres -D $DATABASE_DATA_DIR" &
156-
until pg_isready -h localhost -p 5432 -U postgres; do
156+
postgres -D "$DATABASE_DATA_DIR" &
157+
until pg_isready -h localhost -p 5432 -d sourcebot -U postgres; do
157158
echo -e "\e[34m[Info] Waiting for the database to be ready...\e[0m"
158159
sleep 1
160+
161+
# As postgres runs in the background, we must check if it is still
162+
# running, otherwise the "until" loop will be running indefinitely.
163+
if ! pgrep -x "postgres" > /dev/null; then
164+
echo "postgres failed to run"
165+
exit 1
166+
break
167+
fi
159168
done
160169

161-
# Check if the database already exists, and create it if it dne
170+
# Running as non-root we need to ensure the postgres account is created.
171+
psql -U postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 \
172+
|| createuser postgres -s
173+
174+
# Check if the database already exists, and create it if it doesn't
162175
EXISTING_DB=$(psql -U postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'sourcebot'")
163176

164177
if [ "$EXISTING_DB" = "1" ]; then
@@ -177,4 +190,4 @@ yarn workspace @sourcebot/db prisma:migrate:prod
177190
mkdir -p /var/log/sourcebot
178191

179192
# Run supervisord
180-
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf
193+
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf

0 commit comments

Comments
 (0)