Skip to content

Commit 97c90f1

Browse files
authored
Customize container user permissions using PUID and PGID. #9657
1 parent bcd48a9 commit 97c90f1

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

Dockerfile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ RUN apk update && apk upgrade && \
165165
tzdata \
166166
libedit \
167167
libldap \
168-
libcap && \
168+
libcap \
169+
su-exec && \
169170
rm -rf /var/cache/apk/*
170171

171172
# Copy in the Python packages
@@ -206,8 +207,6 @@ RUN /venv/bin/python3 -m pip install --no-cache-dir gunicorn==23.0.0 && \
206207
echo "pgadmin ALL = NOPASSWD: /usr/sbin/postfix start" > /etc/sudoers.d/postfix && \
207208
echo "pgadminr ALL = NOPASSWD: /usr/sbin/postfix start" >> /etc/sudoers.d/postfix
208209

209-
USER 5050
210-
211210
# Finish up
212211
VOLUME /var/lib/pgadmin
213212
EXPOSE 80 443

pkg/docker/entrypoint.sh

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
11
#!/usr/bin/env bash
2+
PUID=${PUID:-5050}
3+
PGID=${PGID:-0}
4+
5+
if [ "$(id -u)" = "0" ]; then
6+
# Ensure a group with the target GID exists
7+
if ! getent group "$PGID" > /dev/null 2>&1; then
8+
addgroup -g "$PGID" pggroup
9+
fi
10+
11+
# Reassign the pgadmin user to the desired UID/GID
12+
usermod -o -u "$PUID" -g "$PGID" pgadmin 2>&1 || \
13+
echo "WARNING: usermod failed for UID=$PUID GID=$PGID"
14+
15+
# Compose su-exec command
16+
SU_EXEC="su-exec $PUID:$PGID"
17+
echo "pgAdmin will run as UID=$PUID, GID=$PGID"
18+
else
19+
SU_EXEC=""
20+
fi
221

322
# Fixup the passwd file, in case we're on OpenShift
423
if ! whoami > /dev/null 2>&1; then
@@ -9,6 +28,27 @@ if ! whoami > /dev/null 2>&1; then
928
fi
1029
fi
1130

31+
# Helper: chown a path only if it exists and isn't already owned correctly
32+
safe_chown() {
33+
local target="$1"
34+
local owner="$2:$3" # UID:GID
35+
36+
# Skip if path doesn't exist
37+
[ -e "$target" ] || return 0
38+
39+
# Get current ownership
40+
local current_uid current_gid
41+
current_uid=$(stat -c '%u' "$target")
42+
current_gid=$(stat -c '%g' "$target")
43+
44+
# Skip if already owned correctly
45+
if [ "$current_uid" = "$2" ] && [ "$current_gid" = "$3" ]; then
46+
return 0
47+
fi
48+
49+
chown -R "$owner" "$target"
50+
}
51+
1252
# usage: file_env VAR [DEFAULT] ie: file_env 'XYZ_DB_PASSWORD' 'example'
1353
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
1454
# "$XYZ_DB_PASSWORD" from a file, for Docker's secrets feature)
@@ -182,6 +222,12 @@ fi
182222
# to define the Gunicorn worker timeout
183223
TIMEOUT=$(cd /pgadmin4 && /venv/bin/python3 -c 'import config; print(config.SESSION_EXPIRATION_TIME * 60 * 60 * 24)')
184224

225+
if [ "$(id -u)" = "0" ]; then
226+
for path in /run/pgadmin /var/lib/pgadmin "$CONFIG_DISTRO_FILE_PATH" /certs; do
227+
safe_chown "$path" "$PUID" "$PGID"
228+
done
229+
fi
230+
185231
# NOTE: currently pgadmin can run only with 1 worker due to sessions implementation
186232
# Using --threads to have multi-threaded single-process worker
187233

@@ -196,7 +242,7 @@ else
196242
fi
197243

198244
if [ -n "${PGADMIN_ENABLE_TLS}" ]; then
199-
exec /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" --keyfile /certs/server.key --certfile /certs/server.cert -c gunicorn_config.py run_pgadmin:app
245+
exec $SU_EXEC /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" --keyfile /certs/server.key --certfile /certs/server.cert -c gunicorn_config.py run_pgadmin:app
200246
else
201-
exec /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --limit-request-fields "${GUNICORN_LIMIT_REQUEST_FIELDS:-100}" --limit-request-field_size "${GUNICORN_LIMIT_REQUEST_FIELD_SIZE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" -c gunicorn_config.py run_pgadmin:app
247+
exec $SU_EXEC /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --limit-request-fields "${GUNICORN_LIMIT_REQUEST_FIELDS:-100}" --limit-request-field_size "${GUNICORN_LIMIT_REQUEST_FIELD_SIZE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" -c gunicorn_config.py run_pgadmin:app
202248
fi

0 commit comments

Comments
 (0)