From c1785b517faa27eb07a0deedbbf714e6d2a32774 Mon Sep 17 00:00:00 2001 From: "S. Seide" Date: Fri, 15 Mar 2024 13:53:50 +0100 Subject: [PATCH 1/2] first part of changes for OpenShift compatibility --- deploy/docker/Dockerfile | 12 +++++++----- deploy/docker/all-in-one/entrypoint.sh | 21 +++++++++++++++------ deploy/docker/api-service/entrypoint.sh | 17 +++++++++++------ deploy/docker/node-service/entrypoint.sh | 11 +++++++---- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/deploy/docker/Dockerfile b/deploy/docker/Dockerfile index 6f55ed0fc..7f082ae69 100644 --- a/deploy/docker/Dockerfile +++ b/deploy/docker/Dockerfile @@ -32,7 +32,7 @@ RUN chmod +x /lowcoder/api-service/*.sh ## To create a separate image out of it, build it with: ## DOCKER_BUILDKIT=1 docker build -f deploy/docker/Dockerfile -t lowcoderorg/lowcoder-ce-api-service --target lowcoder-ce-api-service . ## -FROM eclipse-temurin:17-jammy as lowcoder-ce-api-service +FROM eclipse-temurin:17-jammy AS lowcoder-ce-api-service LABEL maintainer="lowcoder" RUN apt-get update && apt-get install -y --no-install-recommends gosu \ @@ -51,7 +51,7 @@ CMD [ "sh" , "/lowcoder/api-service/entrypoint.sh" ] ## ## Build lowcoder node service ## -FROM ubuntu:jammy as build-node-service +FROM ubuntu:jammy AS build-node-service RUN apt update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y curl ca-certificates build-essential gnupg @@ -82,7 +82,7 @@ RUN chmod +x /lowcoder/node-service/*.sh ## To create a separate image out of it, build it with: ## DOCKER_BUILDKIT=1 docker build -f deploy/docker/Dockerfile -t lowcoderorg/lowcoder-ce-node-service --target lowcoder-ce-node-service . ## -FROM ubuntu:jammy as lowcoder-ce-node-service +FROM ubuntu:jammy AS lowcoder-ce-node-service LABEL maintainer="lowcoder" RUN apt update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y curl ca-certificates gnupg @@ -133,7 +133,7 @@ RUN yarn build ## To create a separate image out of it, build it with: ## DOCKER_BUILDKIT=1 docker build -f deploy/docker/Dockerfile -t lowcoderorg/lowcoder-ce-frontend --target lowcoder-ce-frontend . ## -FROM nginx:1.25.1 as lowcoder-ce-frontend +FROM nginx:1.25.1 AS lowcoder-ce-frontend LABEL maintainer="lowcoder" # Change default nginx user into lowcoder user and remove default nginx config @@ -198,7 +198,9 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-instal openjdk-17-jdk-headless \ && npm install -g yarn \ && rm -rf /var/cache/apt/lists \ - && mkdir -p /lowcoder/assets + && mkdir -p /lowcoder/assets \ + && apt-get clean \ + && rm -rf /tmp/* # Add lowcoder api-service COPY --chown=lowcoder:lowcoder --from=lowcoder-ce-api-service /lowcoder/api-service /lowcoder/api-service diff --git a/deploy/docker/all-in-one/entrypoint.sh b/deploy/docker/all-in-one/entrypoint.sh index 84281fc71..03a1a9eb1 100644 --- a/deploy/docker/all-in-one/entrypoint.sh +++ b/deploy/docker/all-in-one/entrypoint.sh @@ -6,19 +6,19 @@ export USER_ID=${LOWCODER_PUID:=9001} export GROUP_ID=${LOWCODER_PGID:=9001} # Update ID of lowcoder user if required -if [ ! `id --user lowcoder` -eq ${USER_ID} ]; then +if [ ! "$(id --user lowcoder)" -eq ${USER_ID} ]; then usermod --uid ${USER_ID} lowcoder echo "ID for lowcoder user changed to: ${USER_ID}" fi; # Update ID of lowcoder group if required -if [ ! `id --group lowcoder` -eq ${GROUP_ID} ]; then +if [ ! "$(id --group lowcoder)" -eq ${GROUP_ID} ]; then groupmod --gid ${GROUP_ID} lowcoder echo "ID for lowcoder group changed to: ${GROUP_ID}" fi; # Update host on which mongo is supposed to listen -# If LOWCODER_MONGODB_EXPOSED is true, it will isten on all interfaces +# If LOWCODER_MONGODB_EXPOSED is true, it will listen on all interfaces if [ "${LOWCODER_MONGODB_EXPOSED}" = "true" ]; then export MONGO_LISTEN_HOST="0.0.0.0" else @@ -38,8 +38,10 @@ mkdir -p ${LOGS}/redis \ ${DATA}/mongodb \ ${CERT} -# Update owner of logs and data -chown -R ${USER_ID}:${GROUP_ID} /lowcoder-stacks/ /lowcoder/etc +# Update owner of logs and data - do not try if not running as root (OpenShift) +if [ "$(id -u)" -eq 0 ]; then + chown -R "${USER_ID}:${GROUP_ID}" /lowcoder-stacks/ /lowcoder/etc +fi # Enable services SUPERVISOR_AVAILABLE="/lowcoder/etc/supervisord/conf-available" @@ -73,8 +75,15 @@ fi; # Enable frontend if configured to run if [ "${LOWCODER_FRONTEND_ENABLED:=true}" = "true" ]; then - ln ${SUPERVISOR_AVAILABLE}/20-frontend.conf ${SUPERVISOR_ENABLED}/20-frontend.conf + ln ${SUPERVISOR_AVAILABLE}/20-frontend.conf ${SUPERVISOR_ENABLED}/20-frontend.conf fi; +# disable user directive if image is running non-root (Openshift) +if [ "$(id -u)" -ne 0 ]; then + for i in "${SUPERVISOR_ENABLED}"/*.conf; do + sed -Ei 's/^\s*user=.*$//' "$i" + done +fi + # Handle CMD command "$@" diff --git a/deploy/docker/api-service/entrypoint.sh b/deploy/docker/api-service/entrypoint.sh index 5f2e3ad2e..fad617b67 100644 --- a/deploy/docker/api-service/entrypoint.sh +++ b/deploy/docker/api-service/entrypoint.sh @@ -9,8 +9,8 @@ export GROUP_ID="${LOWCODER_PGID:=9001}" echo "Initializing api-service..." /lowcoder/api-service/init.sh -if [ -z $JAVA_HOME ]; then - JAVA_HOME=`dirname $(dirname $(readlink -f $(which javac)))` +if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=$(dirname "$(dirname "$(readlink -f "$(which javac)")")") fi; APP_JAR="${APP_JAR:=/lowcoder/api-service/server.jar}" JAVA_OPTS="${JAVA_OPTS:=}" @@ -19,15 +19,20 @@ CONTEXT_PATH=${CONTEXT_PATH:=/} echo echo "Running lowcoder api-server with:" -echo " user id: ${USER_ID}" -echo " group id: ${GROUP_ID}" echo " base path: ${CONTEXT_PATH}" + +if [ "$(id -u)" -eq 0 ]; then + # only use su if its possible, suppress for containers running non-root + echo " user id: ${USER_ID}" + echo " group id: ${GROUP_ID}" + GOSU="gosu ${USER_ID}:${GROUP_ID}" +fi echo -${JAVA_HOME}/bin/java -version +"${JAVA_HOME}/bin/java" -version echo cd /lowcoder/api-service -exec gosu ${USER_ID}:${GROUP_ID} ${JAVA_HOME}/bin/java \ +exec $GOSU "${JAVA_HOME}/bin/java" \ -Djava.security.egd=file:/dev/./urandom \ -Dhttps.protocols=TLSv1.1,TLSv1.2 \ -Dlog4j2.formatMsgNoLookups=true \ diff --git a/deploy/docker/node-service/entrypoint.sh b/deploy/docker/node-service/entrypoint.sh index 67e60a362..33308e4c7 100755 --- a/deploy/docker/node-service/entrypoint.sh +++ b/deploy/docker/node-service/entrypoint.sh @@ -15,9 +15,12 @@ cd /lowcoder/node-service/app echo echo "Running Lowcoder node-service with:" echo " API service host: ${API_HOST}" -echo " user id: ${USER_ID}" -echo " group id: ${GROUP_ID}" +if [ "$(id -u)" -eq 0 ]; then + # only use su if its possible, suppress for containers running non-root + echo " user id: ${USER_ID}" + echo " group id: ${GROUP_ID}" + GOSU="gosu ${USER_ID}:${GROUP_ID}" +fi echo -exec gosu ${USER_ID}:${GROUP_ID} yarn start - +exec $GOSU yarn start From 190f715372af0e048877fcfd69aad7ee68f32d80 Mon Sep 17 00:00:00 2001 From: "S. Seide" Date: Mon, 22 Apr 2024 16:55:26 +0200 Subject: [PATCH 2/2] supervisord and docker changes for OpenShift compatibility --- deploy/docker/Dockerfile | 18 ++++++++++++++-- deploy/docker/all-in-one/etc/supervisord.conf | 21 ++++++++++--------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/deploy/docker/Dockerfile b/deploy/docker/Dockerfile index 7f082ae69..f0f84f2e6 100644 --- a/deploy/docker/Dockerfile +++ b/deploy/docker/Dockerfile @@ -169,7 +169,10 @@ EXPOSE 3443 FROM lowcoder-ce-frontend LABEL maintainer="lowcoder" -RUN apt update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y curl ca-certificates gnupg +RUN apt-get update && apt-get upgrade -y \ + && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y curl ca-certificates gnupg \ + && rm -rf /var/cache/apt/lists /var/lib/apt/lists/* /var/log/dpkg.log \ + && apt-get clean # Add nodejs repo and keys RUN mkdir -p /etc/apt/keyrings \ @@ -197,7 +200,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-instal nodejs \ openjdk-17-jdk-headless \ && npm install -g yarn \ - && rm -rf /var/cache/apt/lists \ + && rm -rf /var/cache/apt/lists /var/lib/apt/lists/* /var/log/dpkg.log \ && mkdir -p /lowcoder/assets \ && apt-get clean \ && rm -rf /tmp/* @@ -214,6 +217,17 @@ COPY --chown=lowcoder:lowcoder deploy/docker/all-in-one/etc /lowcoder/etc # Add startup script COPY --chown=lowcoder:lowcoder deploy/docker/all-in-one/entrypoint.sh /lowcoder/entrypoint.sh +# Fixes for OpenShift compatibility (after all files are copied) +RUN echo \ + && adduser lowcoder root \ + && mkdir -p /lowcoder-stacks \ + && for i in /lowcoder-stacks /lowcoder/assets /lowcoder/api-service/logs /lowcoder/etc/supervisord; do \ + chmod -R g+rw "$i"; \ + chown -R lowcoder:root "$i"; \ + done \ + && chown -R lowcoder:root /var/log \ + && chmod -R g+rw /run /etc/nginx /var/cache/nginx /var/log + EXPOSE 27017 EXPOSE 3000 EXPOSE 3443 diff --git a/deploy/docker/all-in-one/etc/supervisord.conf b/deploy/docker/all-in-one/etc/supervisord.conf index c6d035aff..279e3b201 100644 --- a/deploy/docker/all-in-one/etc/supervisord.conf +++ b/deploy/docker/all-in-one/etc/supervisord.conf @@ -1,8 +1,8 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +file = /var/run/supervisor.sock ; (the path to the socket file) +chmod = 0700 ; socket file mode (default 0700) [inet_http_server] ; inet (TCP) server disabled by default port=*:9001 ; (ip_address:port specifier, *:port for all iface) @@ -10,9 +10,10 @@ port=*:9001 ; (ip_address:port specifier, *:port for all iface) ;password=123 ; (default is no password (open server)) [supervisord] -logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +logfile = /dev/null ; (no logfile, stdout only; default $CWD/supervisord.log) +pidfile = /var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir = /var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +logfile_maxbytes = 0 stdout_logfile_maxbytes = 0 stderr_logfile_maxbytes = 0 @@ -23,7 +24,7 @@ stderr_logfile_maxbytes = 0 supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +serverurl = unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or @@ -37,8 +38,8 @@ files = /lowcoder/etc/supervisord/conf-enabled/*.conf # ; This event listener is used to capture processes log # ; and forward to container log using supervisor_stdout # ; Ref: https://github.com/coderanger/supervisor-stdout -# [eventlistener:stdout] -# command = supervisor_stdout -# buffer_size = 100 -# events = PROCESS_LOG +# [eventlistener:stdout] +# command = supervisor_stdout +# buffer_size = 100 +# events = PROCESS_LOG # result_handler = supervisor_stdout:event_handler