Date: Thu, 28 Mar 2024 20:43:12 +0000 (UTC) Message-ID: <739664803.11931.1711658592673@change.sos-berlin.com> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_11930_1727707661.1711658592673" ------=_Part_11930_1727707661.1711658592673 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
The following directory hierarchy is assumed for the build environment:<= /p>
controller
build.sh
build
Dockerfile
entrypoint.sh
<=
/li>
js7_install_controller.sh
config
The root directory controller
can have any name. Note =
that build script listed below will, by default, use the directory name and=
release number to determine the resulting image name.
The build.sh
build script and entrypoint.sh entrypoint script are described below.
Download: = Dockerfile
Container images for JS7 Controllers provided by SOS make use of the fol= lowing Dockerfile:
# BUILD PRE-IMAGE FROM alpine:3.17 AS js7-pre-image # provide build arguments for release information ARG JS_RELEASE ARG JS_RELEASE_MAJOR # image user id has to match later run-time user id ARG JS_USER_ID=3D${JS_USER_ID:-1001} ARG JS_ID=3D${JS_ID:-Controller} ARG JS_HTTP_PORT=3D${JS_HTTP_PORT:-4444} ARG JS_HTTPS_PORT=3D${JS_HTTPS_PORT:-""} ARG JS_JAVA_OPTIONS=3D${JS_JAVA_OPTIONS} # add/copy installation tarball # ADD https://download.sos-berlin.com/JobScheduler.${JS_RELEASE_MAJOR}/js7_= controller_unix.${JS_RELEASE}.tar.gz /usr/local/src/ COPY js7_controller_unix.${JS_RELEASE}.tar.gz /usr/local/src/ # test installation tarball RUN test -e /usr/local/src/js7_controller_unix.${JS_RELEASE}.tar.gz # add/copy installer script # ADD https://download.sos-berlin.com/JobScheduler.${JS_RELEASE_MAJOR}/js7= _install_controller.sh /usr/local/bin/ COPY js7_install_controller.sh /usr/local/bin/ RUN adduser -u ${JS_USER_ID} -G root --disabled-password --home /home/jobsc= heduler --shell /bin/bash jobscheduler && \ chmod +x /usr/local/bin/js7_install_controller.sh && \ /usr/local/bin/js7_install_controller.sh \ --home=3D/opt/sos-berlin.com/js7/controller \ --data=3D/var/sos-berlin.com/js7/controller \ --tarball=3D/usr/local/src/js7_controller_unix.${JS_RELEASE}.tar.gz= \ --user=3Djobscheduler \ --controller-id=3D${JS_ID} \ --http-port=3D${JS_HTTP_PORT} \ --java-options=3D"${JS_JAVA_OPTIONS}" \ --make-dirs && \ rm -f /usr/local/src/js7_controller_unix.${JS_RELEASE}.tar.gz # BUILD IMAGE FROM alpine:3.17 AS js7-image LABEL maintainer=3D"Software- und Organisations-Service GmbH" # provide build arguments for release information ARG JS_RELEASE ARG JS_RELEASE_MAJOR # image user id has to match later run-time user id ARG JS_USER_ID=3D${JS_USER_ID:-1001} ARG JS_ID=3D${JS_ID:-Controller} ARG JS_HTTP_PORT=3D${JS_HTTP_PORT:-4444} ARG JS_HTTPS_PORT=3D${JS_HTTPS_PORT:-""} ARG JS_JAVA_OPTIONS=3D${JS_JAVA_OPTIONS} # JS7 user id, Controller ID, ports and Java optionsa ENV RUN_JS_USER_ID=3D${RUN_JS_USER_ID:-1001} ENV RUN_JS_ID=3D${RUN_JS_ID:-$JS_ID} ENV RUN_JS_HTTP_PORT=3D${RUN_JS_HTTP_PORT:-$JS_HTTP_PORT} ENV RUN_JS_HTTPS_PORT=3D${RUN_JS_HTTPS_PORT} ENV RUN_JS_JAVA_OPTIONS=3D${RUN_JS_JAVA_OPTIONS:-$JS_JAVA_OPTIONS} COPY --from=3Djs7-pre-image ["/opt/sos-berlin.com/js7", "/opt/sos-berlin.co= m/js7"] COPY --from=3Djs7-pre-image ["/var/sos-berlin.com/js7", "/var/sos-berlin.co= m/js7"] # copy configuration COPY config/ /var/sos-berlin.com/js7/controller/config/ # copy entrypoint script COPY entrypoint.sh /usr/local/bin/ # install process tools, net tools, bash, openjdk # add jobscheduler user account and make it the owner of directories # for JDK < 12, /dev/random does not provide sufficient entropy, see htt= ps://kb.sos-berlin.com/x/lIM3 RUN apk update && apk add --no-cache \ --repository=3Dhttp://dl-cdn.alpinelinux.org/alpine/edge/community \ procps \ net-tools \ su-exec \ bash \ shadow \ openjdk11 && \ sed -i 's/securerandom.source=3Dfile:\/dev\/random/securerandom.source= =3Dfile:\/dev\/urandom/g' /usr/lib/jvm/java-11-openjdk/conf/security/java.s= ecurity && \ sed -i 's/jdk.tls.disabledAlgorithms=3DSSLv3, RC4, DES, MD5withRSA, DH = keySize < 1024, \\/jdk.tls.disabledAlgorithms=3DSSLv3, RC4, DES, MD5with= RSA, DH keySize < 1024, TLSv1, TLSv1.1, \\/g' /usr/lib/jvm/java-11-openj= dk/conf/security/java.security && \ adduser -u ${JS_USER_ID} -G root --disabled-password --home /home/jobsc= heduler --shell /bin/bash jobscheduler && \ chown -R jobscheduler:root /opt/sos-berlin.com /var/sos-berlin.com &= ;& \ chmod -R g=3Du /etc/passwd /opt/sos-berlin.com /var/sos-berlin.com &= ;& \ chmod +x /usr/local/bin/entrypoint.sh # START ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
Explanation:
Line 20: The tarball integrity is tested.
jobscheduler
account is created.jobscheduler
account.config
folder available in the build director=
y is copied to the config
sub-folder in the image. T=
he parent folder var_<port>
is determined from the HTTP =
port that the Controller is built for. This can be useful for creating an i=
mage with individual default settings in configuration files, see the =
JS7 - Control=
ler Configuration Items article for more information.entrypoint.sh
script is copied from the=
build directory to the image. Users can apply their own version of the ent=
rypoint script. The entrypoint script used by SOS looks like this:=
li>
/dev/random
for r=
andom number generation. This is a bottleneck as random number generation w=
ith this file is blocking. Instead /dev/urandom
should be used=
that implements non-blocking behavior. The change of the random file is ap=
plied to the Java security file.jobscheduler
account is created and is a=
ssigned the user id handed over by the relevant build argument. This sugges=
ts that the account running the Controller inside the container and the acc=
ount that starts the container are assigned the same user id. This allows t=
he account running the container to access any files created by the Control=
ler in mounted volumes with identical permissions.
root
group. For =
environments in which the entrypoint script is executed with an arbitrary n=
on-root user id this allows access to files created by the Controller provi=
ded to any accounts that are assigned the root
group.jobscheduler
accou=
nt are made accessible to the root
group with similar user per=
missions. Read access to /etc/passwd
can be required in such e=
nvironments.Download: entrypoint.= sh
The following entrypoint script is used to start Controller containers.<= /p>
#!/bin/bash js_args=3D() js_args_count=3D0 if [ -n "${RUN_JS_ID}" ] then js_args["${js_args_count}"]=3D"--id=3D${RUN_JS_ID}" js_args_count=3D$(( "${js_args_count}" + 1 )) fi if [ -n "${RUN_JS_HTTP_PORT}" ] && [ ! "${RUN_JS_HTTP_PORT}" =3D ":= " ] then js_args["${js_args_count}"]=3D"--http-port=3D${RUN_JS_HTTP_PORT}" js_args_count=3D$(( "${js_args_count}" + 1 )) fi if [ -n "${RUN_JS_HTTPS_PORT}" ] && [ ! "${RUN_JS_HTTPS_PORT}" =3D = ":" ] then js_args["${js_args_count}"]=3D"--https-port=3D${RUN_JS_HTTPS_PORT}" js_args_count=3D$(( "${js_args_count}" + 1 )) fi if [ -n "${RUN_JS_JAVA_OPTIONS}" ] then js_args["${js_args_count}"]=3D"--java-options=3D\"${RUN_JS_JAVA_OPTIONS}\= "" js_args_count=3D$(( "${js_args_count}" + 1 )) fi # work directory will be created by container if [ -d "/var/sos-berlin.com/js7/controller/work" ] && [ -w "/var/s= os-berlin.com/js7/controller/work" ] then rm -f -r /var/sos-berlin.com/js7/controller/work fi JS_USER_ID=3D$(echo "${RUN_JS_USER_ID}" | cut -d ':' -f 1) JS_GROUP_ID=3D$(echo "${RUN_JS_USER_ID}" | cut -d ':' -f 2) JS_USER_ID=3D${JS_USER_ID:-$(id -u)} JS_GROUP_ID=3D${JS_GROUP_ID:-$(id -g)} BUILD_GROUP_ID=3D$(cat /etc/group | grep jobscheduler | cut -d ':' -f 3) BUILD_USER_ID=3D$(cat /etc/passwd | grep jobscheduler | cut -d ':' -f 4) if [ "$(id -u)" =3D "0" ] then if [ ! "{$BUILD_USER_ID}" =3D "${JS_USER_ID}" ] then echo "JS7 entrypoint script switching ownership of image user id '${BUI= LD_USER_ID}' -> '${JS_USER_ID}'" usermod -u "${JS_USER_ID}" jobscheduler find /var/sos-berlin.com/ -user "${BUILD_USER_ID}" -exec chown -h jobsc= heduler {} \; fi =20 if [ ! "${BUILD_GROUP_ID}" =3D "${JS_GROUP_ID}" ] then if grep -q "${JS_GROUP_ID}" /etc/group then groupmod -g "${JS_GROUP_ID}" jobscheduler else addgroup -g ${JS_GROUP_ID} -S jobscheduler fi echo "JS7 entrypoint script switchng ownership of image group id '${BUI= LD_GROUP_ID}' -> '${JS_GROUP_ID}'" find /var/sos-berlin.com/ -group "${BUILD_GROUP_ID}" -exec chgrp -h job= scheduler {} \; fi echo "JS7 entrypoint script switching to user account 'jobscheduler' to r= un start script" echo "JS7 entrypoint script starting Controller: exec su-exec ${JS_USER_I= D}:${JS_GROUP_ID} /opt/sos-berlin.com/js7/controller/bin/controller_instanc= e.sh start-docker" "${js_args[@]}" exec su-exec "${JS_USER_ID}":"${JS_GROUP_ID}" /opt/sos-berlin.com/js7/con= troller/bin/controller_instance.sh start-docker "${js_args[@]}" else if [ "${BUILD_USER_ID}" =3D "${JS_USER_ID}" ] then if [ "$(id -u)" =3D "${JS_USER_ID}" ] then echo "JS7 entrypoint script running for user id '$(id -u)'" else echo "JS7 entrypoint script running for user id '$(id -u)' using user= id '${JS_USER_ID}', group id '${JS_GROUP_ID}'" echo "JS7 entrypoint script missing permission to switch user id and = group id, consider to omit the 'docker run --user' option" fi else echo "JS7 entrypoint script running for user id '$(id -u)' using image = user id '${BUILD_USER_ID}' -> '${JS_USER_ID}', image group id '${BUILD_G= ROUP_ID}' -> '${JS_GROUP_ID}'" fi echo "JS7 entrypoint script starting Controller: exec sh -c /opt/sos-berl= in.com/js7/controller/bin/controller_instance.sh start-docker ${js_args[*]}= " exec sh -c "/opt/sos-berlin.com/js7/controller/bin/controller_instance.sh= start-docker ${js_args[*]}" fi
The build script offers a number of options to parameterize the Dockerfi= le:
#!/bin/sh set -e SCRIPT_HOME=3D$(dirname "$0") SCRIPT_HOME=3D"`cd "${SCRIPT_HOME}" >/dev/null && pwd`" SCRIPT_FOLDER=3D"`basename $(dirname "$SCRIPT_HOME")`" # ----- modify default settings ----- JS_RELEASE=3D"2.5.0" JS_REPOSITORY=3D"sosberlin/js7" JS_IMAGE=3D"$(basename "${SCRIPT_HOME}")-${JS_RELEASE//\./-}" JS_USER_ID=3D"$UID" JS_ID=3D"jobscheduler" JS_HTTP_PORT=3D"4444" JS_HTTPS_PORT=3D"4443" JS_JAVA_OPTIONS=3D"-Xmx500m" JS_BUILD_ARGS=3D"" # ----- modify default settings ----- for option in "$@" do case "$option" in --release=3D*) JS_RELEASE=3D`echo "$option" | sed 's/--releas= e=3D//'` ;; --repository=3D*) JS_REPOSITORY=3D`echo "$option" | sed 's/--rep= ository=3D//'` ;; --image=3D*) JS_IMAGE=3D`echo "$option" | sed 's/--image=3D= //'` ;; --user-id=3D*) JS_USER_ID=3D`echo "$option" | sed 's/--user-i= d=3D//'` ;; --id=3D*) JS_ID=3D`echo "$option" | sed 's/--id=3D//'` ;; --http-port=3D*) JS_HTTP_PORT=3D`echo "$option" | sed 's/--http= -port=3D//'` ;; --https-port=3D*) JS_HTTPS_PORT=3D`echo "$option" | sed 's/--htt= ps-port=3D//'` ;; --java-options=3D*) JS_JAVA_OPTIONS=3D`echo "$option" | sed 's/--j= ava-options=3D//'` ;; --build-args=3D*) JS_BUILD_ARGS=3D`echo "$option" | sed 's/--bui= ld-args=3D//'` ;; *) echo "unknown argument: $option" exit 1 ;; esac done set -x docker build --no-cache --rm \ --tag=3D$JS_REPOSITORY:$JS_IMAGE \ --file=3D$SCRIPT_HOME/build/Dockerfile \ --build-arg=3D"JS_RELEASE=3D$JS_RELEASE" \ --build-arg=3D"JS_RELEASE_MAJOR=3D$(echo $JS_RELEASE | cut -d . -f 1,= 2)" \ --build-arg=3D"JS_USER_ID=3D$JS_USER_ID" \ --build-arg=3D"JS_ID=3D$JS_ID" \ --build-arg=3D"JS_HTTP_PORT=3D$JS_HTTP_PORT" \ --build-arg=3D"JS_HTTPS_PORT=3D$JS_HTTPS_PORT" \ --build-arg=3D"JS_JAVA_OPTIONS=3D$JS_JAVA_OPTIONS" \ $JS_BUILD_ARGS $SCRIPT_HOME/build set +x
Explanation:
sosberlin:js7
../build.= sh --id=3Djs7-prod --http-port=3D14445 --https-port=3D14443 --java-options= =3D"-Xmx1G"
docker build
command is execut=
ed with arguments. The Dockerfile is assumed to be located with the b=
uild
sub-directory of the current directory.