From 623afdc87993679da424a299df49aa3b881de960 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Wed, 13 May 2026 13:45:24 -0700 Subject: [PATCH 1/7] feat: cluster image Signed-off-by: Hendrik Leidinger --- build/.docker/orchestrated.bake.Dockerfile | 245 +++++++++++++ ....Dockerfile => standalone.bake.Dockerfile} | 4 +- .../nginx/includes/http-common.conf | 33 ++ .../nginx/includes/http-upstream.conf | 11 + build/configs/orchestrated/nginx/nginx.conf | 36 ++ .../supervisor/ds-adminpanel.conf | 0 .../supervisor/ds-converter.conf | 0 .../supervisor/ds-docservice.conf | 0 .../supervisor/ds-example.conf | 0 .../supervisor/ds-metrics.conf | 0 .../supervisor/supervisord.conf | 0 build/docker-bake.hcl | 21 +- .../scripts/orchestrated/docker-entrypoint.sh | 329 ++++++++++++++++++ .../orchestrated/example-docker-entrypoint.sh | 14 + .../orchestrated/init-docker-entrypoint.sh | 99 ++++++ .../orchestrated/proxy-docker-entrypoint.sh | 158 +++++++++ build/scripts/{ => standalone}/entrypoint.sh | 0 17 files changed, 944 insertions(+), 6 deletions(-) create mode 100644 build/.docker/orchestrated.bake.Dockerfile rename build/.docker/{docker.bake.Dockerfile => standalone.bake.Dockerfile} (95%) create mode 100644 build/configs/orchestrated/nginx/includes/http-common.conf create mode 100644 build/configs/orchestrated/nginx/includes/http-upstream.conf create mode 100644 build/configs/orchestrated/nginx/nginx.conf rename build/configs/{ => standalone}/supervisor/ds-adminpanel.conf (100%) rename build/configs/{ => standalone}/supervisor/ds-converter.conf (100%) rename build/configs/{ => standalone}/supervisor/ds-docservice.conf (100%) rename build/configs/{ => standalone}/supervisor/ds-example.conf (100%) rename build/configs/{ => standalone}/supervisor/ds-metrics.conf (100%) rename build/configs/{ => standalone}/supervisor/supervisord.conf (100%) create mode 100755 build/scripts/orchestrated/docker-entrypoint.sh create mode 100755 build/scripts/orchestrated/example-docker-entrypoint.sh create mode 100755 build/scripts/orchestrated/init-docker-entrypoint.sh create mode 100755 build/scripts/orchestrated/proxy-docker-entrypoint.sh rename build/scripts/{ => standalone}/entrypoint.sh (100%) diff --git a/build/.docker/orchestrated.bake.Dockerfile b/build/.docker/orchestrated.bake.Dockerfile new file mode 100644 index 0000000000..01466709e4 --- /dev/null +++ b/build/.docker/orchestrated.bake.Dockerfile @@ -0,0 +1,245 @@ +ARG POSTGRES_VERSION="15" +ARG MYSQL_VERSION="latest" +ARG MARIADB_VERSION="latest" + +FROM fedora:43 AS ds-base + + LABEL maintainer Euro-Office + + ARG COMPANY_NAME=euro-office + ARG DS_VERSION_HASH + ENV COMPANY_NAME=$COMPANY_NAME \ + APPLICATION_NAME=$COMPANY_NAME \ + DS_VERSION_HASH=$DS_VERSION_HASH \ + NODE_ENV=production-linux \ + NODE_CONFIG_DIR=/etc/$COMPANY_NAME/documentserver \ + PKG_NATIVE_CACHE_PATH=/tmp/.cache + + RUN dnf -y updateinfo list --security && \ + dnf update --security -y && \ + dnf install sudo \ + python3-pip \ + findutils \ + shadow-utils \ + procps-ng \ + tar \ + unzip \ + libaio \ + libnsl \ + nano \ + gettext \ + nginx \ + httpd-tools \ + wget -y && \ + pip3 install --no-cache-dir redis && \ + wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_$(uname -m) && \ + chmod +x /usr/local/bin/dumb-init && \ + mkdir -p /oracle/instantclient /opt/oracle /home/ds /etc/nginx/includes && \ + wget -O /oracle/basic.zip https://download.oracle.com/otn_software/linux/instantclient/2370000/instantclient-basic-linux.x64-23.7.0.25.01.zip && \ + unzip /oracle/basic.zip -d /oracle/instantclient && \ + mv /oracle/instantclient/instantclient_23_7 /opt/oracle/instantclient_23_7 && \ + rm -rf /oracle && \ + groupadd --system --gid 101 ds && \ + useradd --system -g ds --no-create-home --shell /sbin/nologin --uid 101 ds && \ + chown -R ds:ds /home/ds && \ + dnf clean all && \ + rm -rf /var/cache/dnf && \ + rm -f /var/log/*log + +FROM ds-base AS ds-service + ARG TARGETARCH + ARG DS_VERSION_HASH + ARG PRODUCT_EDITION= + ARG RELEASE_VERSION + ARG PRODUCT_VERSION + ENV TARGETARCH=$TARGETARCH \ + DS_VERSION_HASH=$DS_VERSION_HASH + WORKDIR /ds + + COPY --from=packages / /tmp/ + + RUN dnf -y install cabextract xorg-x11-font-utils fontconfig && \ + rpm -ivh --nodigest \ + https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm && \ + TARGETARCH=$(echo $TARGETARCH | sed "s/"$TARGETARCH"/"$(uname -m)"/g") && \ + rpm -ivh /tmp/euro-office-documentserver-${PRODUCT_VERSION}-0.${TARGETARCH}.rpm --noscripts --nodeps && \ + mkdir -p /var/www/$COMPANY_NAME/documentserver/core-fonts/msttcore && \ + cp -vt \ + /var/www/$COMPANY_NAME/documentserver/core-fonts/msttcore \ + /usr/share/fonts/msttcore/*.ttf && \ + chmod a+r /etc/$COMPANY_NAME/documentserver*/*.json && \ + chmod a+r /etc/$COMPANY_NAME/documentserver/log4js/*.json + COPY --chown=ds:ds \ + build/configs/orchestrated/nginx/includes/http-common.conf \ + build/configs/orchestrated/nginx/includes/http-upstream.conf \ + /etc/$COMPANY_NAME/documentserver/nginx/includes/ + #COPY --chown=ds:ds \ + # fonts/ \ + # /var/www/$COMPANY_NAME/documentserver/core-fonts/custom/ + #COPY --chown=ds:ds \ + # plugins/ \ + # /var/www/$COMPANY_NAME/documentserver/sdkjs-plugins/ + #COPY --chown=ds:ds \ + # dictionaries/ \ + # /var/www/onlyoffice/documentserver/dictionaries/ + RUN documentserver-generate-allfonts.sh true && \ + #python3 /var/www/onlyoffice/documentserver/server/dictionaries/update.py && \ + documentserver-flush-cache.sh -h $DS_VERSION_HASH -r false + # documentserver-pluginsmanager.sh -r false \ + # --update=\"/var/www/$COMPANY_NAME/documentserver/sdkjs-plugins/plugin-list-default.json\" + +# -------------------------------------------------------------------------------- +# This image contains ALL runtime components (DocService, Converter, Adminpanel and +# Proxy) and is intended to be reused by +# multiple Kubernetes Deployments +# +# Model: +# - Select the Docs service via container args (docservice|converter|adminpanel) +# - For the Proxy Deployment, override ONLY `command` in the +# PodSpec to run proxy-docker-entrypoint.sh directly +# -------------------------------------------------------------------------------- + +FROM ds-base AS docs + ENV DOCSERVICE_HOST_PORT=localhost:8000 \ + ADMINPANEL_HOST_PORT=localhost:9000 \ + EXAMPLE_HOST_PORT=localhost:3000 \ + NGINX_ACCESS_LOG=off \ + NGINX_GZIP_PROXIED=off \ + NGINX_CLIENT_MAX_BODY_SIZE=100m \ + NGINX_WORKER_CONNECTIONS=4096 \ + NGINX_WORKER_PROCESSES=1 + COPY --chown=ds:ds build/configs/orchestrated/nginx/nginx.conf /etc/nginx/nginx.conf + COPY --chown=ds:ds --from=ds-service \ + /usr/bin/documentserver-generate-allfonts.sh \ + #/usr/bin/documentserver-pluginsmanager.sh \ + /usr/local/bin/ + #COPY --from=ds-service \ + # /var/www/$COMPANY_NAME/documentserver/server/dictionaries/update.py \ + # /var/www/$COMPANY_NAME/documentserver/server/dictionaries/update.py + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/tools/allfontsgen \ + /var/www/$COMPANY_NAME/documentserver/server/tools/allfontsgen + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/tools/allthemesgen \ + /var/www/$COMPANY_NAME/documentserver/server/tools/allthemesgen + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/tools/pluginsmanager \ + /var/www/$COMPANY_NAME/documentserver/server/tools/pluginsmanager + COPY --chown=ds:ds --chmod=644 --from=ds-service \ + /etc/$COMPANY_NAME/documentserver/nginx/ds.conf \ + /etc/nginx/conf.d/ + COPY --chown=ds:ds --chmod=644 --from=ds-service \ + /etc/$COMPANY_NAME/documentserver*/nginx/includes/*.conf \ + /etc/nginx/includes/ds-cache.conf \ + /etc/nginx/includes/ + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/dictionaries \ + /var/www/$COMPANY_NAME/documentserver/dictionaries + COPY --from=ds-service \ + /etc/$COMPANY_NAME/documentserver/default.json \ + /etc/$COMPANY_NAME/documentserver/production-linux.json \ + /etc/$COMPANY_NAME/documentserver/ + COPY --from=ds-service --chown=ds:ds \ + /etc/$COMPANY_NAME/documentserver/log4js/production.json \ + /etc/$COMPANY_NAME/documentserver/log4js/ + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/sdkjs-plugins \ + /var/www/$COMPANY_NAME/documentserver/sdkjs-plugins + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/core-fonts \ + /var/www/$COMPANY_NAME/documentserver/core-fonts + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/fonts \ + /var/www/$COMPANY_NAME/documentserver/fonts + COPY --from=ds-service \ + /usr/share/fonts \ + /usr/share/fonts + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/sdkjs \ + /var/www/$COMPANY_NAME/documentserver/sdkjs + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/DocService \ + /var/www/$COMPANY_NAME/documentserver/server/DocService + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/FileConverter \ + /var/www/$COMPANY_NAME/documentserver/server/FileConverter + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/AdminPanel/server \ + /var/www/$COMPANY_NAME/documentserver/server/AdminPanel/server + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/server/AdminPanel/client \ + /client + #COPY --from=ds-service \ + # /var/www/$COMPANY_NAME/documentserver/server/info \ + # /var/www/$COMPANY_NAME/documentserver/server/info + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/web-apps \ + /var/www/$COMPANY_NAME/documentserver/web-apps + COPY --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver/document-templates/new \ + /var/www/$COMPANY_NAME/documentserver/document-templates/new + #COPY --from=ds-service \ + # /var/www/$COMPANY_NAME/documentserver/document-formats \ + # /var/www/$COMPANY_NAME/documentserver/document-formats + COPY --chown=ds:ds --from=ds-service \ + /var/www/$COMPANY_NAME/documentserver-example/welcome \ + /var/www/$COMPANY_NAME/documentserver-example/welcome + COPY build/scripts/orchestrated/docker-entrypoint.sh build/scripts/orchestrated/proxy-docker-entrypoint.sh /usr/local/bin/ + COPY build/scripts/orchestrated/init-docker-entrypoint.sh /init/ + RUN sed 's|\(application\/zip.*\)|\1\n application\/wasm wasm;|' \ + -i /etc/nginx/mime.types && \ + sed 's,\(listen.\+:\)\([0-9]\+\)\(.*;\),'"\18888\3"',' \ + -i /etc/nginx/conf.d/ds.conf && \ + sed '/access_log.*/d' -i /etc/nginx/includes/ds-common.conf && \ + sed '/error_log.*/d' -i /etc/nginx/includes/ds-common.conf && \ + echo -e "\ngzip_proxied \$NGINX_GZIP_PROXIED;\n" >> /etc/nginx/includes/ds-common.conf && \ + sed 's/#*\s*\(gzip_static\).*/\1 on;/g' -i /etc/nginx/includes/ds-docservice.conf && \ + sed -i 's/etc\/nginx/tmp\/proxy_nginx/g' /etc/nginx/nginx.conf && \ + sed -i 's/etc\/nginx/tmp\/proxy_nginx/g' /etc/nginx/conf.d/ds.conf && \ + sed 's/\(X-Forwarded-For\).*/\1 example.com;/' -i /etc/nginx/includes/ds-example.conf && \ + sed 's/\(index\).*/\1 k8s.html;/' -i /etc/nginx/includes/ds-example.conf && \ + chmod 755 /var/log/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log && \ + mkdir -p \ + /var/lib/$COMPANY_NAME/documentserver/App_Data/cache/files \ + /var/www/$COMPANY_NAME/config \ + /var/lib/$COMPANY_NAME/documentserver/App_Data/docbuilder && \ + chown -R ds:ds /var/lib/$COMPANY_NAME/documentserver /var/www/$COMPANY_NAME/config && \ + find \ + /var/www/$COMPANY_NAME/documentserver/fonts \ + -type f ! \ + -name "*.*" \ + -exec sh -c 'gzip -cf9 $0 > $0.gz && chown ds:ds $0.gz' {} \; && \ + find \ + /var/www/$COMPANY_NAME/documentserver/sdkjs \ + /var/www/$COMPANY_NAME/documentserver/sdkjs-plugins \ + /var/www/$COMPANY_NAME/documentserver/web-apps \ + /var/www/$COMPANY_NAME/documentserver-example/welcome \ + -type f \ + \( -name *.js -o -name *.json -o -name *.htm -o -name *.html -o -name *.css \) \ + -exec sh -c 'gzip -cf9 $0 > $0.gz && chown ds:ds $0.gz' {} \; + VOLUME /var/lib/$COMPANY_NAME + USER ds + + # -------------------------------------------------------------------- + # Default entrypoint for Docs services + # Do NOT override this for DocService/Converter/Adminpanel; only provide `args` + # -------------------------------------------------------------------- + ENTRYPOINT ["dumb-init", "--", "docker-entrypoint.sh"] + + # -------------------------------------------------------------------- + # Default execution mode for the image. + # Kubernetes `args` override this value: + # - DocService Deployment: + # args: ["docservice", ...] + # - Converter Deployment: + # args: ["converter", ...] + # - Adminpanel Deployment: + # args: ["adminpanel"] + # + # Proxy Deployment should override `command` instead: + # command: ["proxy-docker-entrypoint.sh"] + # args: [...] + # -------------------------------------------------------------------- + CMD ["docservice"] \ No newline at end of file diff --git a/build/.docker/docker.bake.Dockerfile b/build/.docker/standalone.bake.Dockerfile similarity index 95% rename from build/.docker/docker.bake.Dockerfile rename to build/.docker/standalone.bake.Dockerfile index b54c14291b..94e1341edd 100644 --- a/build/.docker/docker.bake.Dockerfile +++ b/build/.docker/standalone.bake.Dockerfile @@ -48,8 +48,8 @@ RUN apt-get -y update && \ # --- Final setup --- -COPY build/configs/supervisor/ /etc/supervisor/conf.d/ -COPY --chmod=755 build/scripts/entrypoint.sh /entrypoint.sh +COPY build/standalone/configs/supervisor/ /etc/supervisor/conf.d/ +COPY --chmod=755 build/standalone/scripts/entrypoint.sh /entrypoint.sh #RUN mkdir -p ${EO_LOG}/docservice ${EO_LOG}/converter \ # ${EO_LOG}/adminpanel ${EO_LOG}/metrics diff --git a/build/configs/orchestrated/nginx/includes/http-common.conf b/build/configs/orchestrated/nginx/includes/http-common.conf new file mode 100644 index 0000000000..612d2927fe --- /dev/null +++ b/build/configs/orchestrated/nginx/includes/http-common.conf @@ -0,0 +1,33 @@ +include /tmp/http-upstream.conf; +map $http_host $this_host { + "" $host; + default $http_host; +} + +map $http_cloudfront_forwarded_proto:$http_x_forwarded_proto $the_scheme { + "~^(https?)(?:,.*)?:.*" $1; + "~^:(https?)(?:,.*)?$" $1; + default $scheme; +} + +map $http_x_forwarded_host $the_host { + "~^([^,]+)" $1; + default $http_x_forwarded_host; + "" $this_host; +} + +map $http_x_forwarded_prefix $the_prefix { + default $http_x_forwarded_prefix; +} + +map $http_upgrade $proxy_connection { + default upgrade; + "" close; +} + +proxy_set_header Host $http_host; +proxy_set_header Upgrade $http_upgrade; +proxy_set_header Connection $proxy_connection; +proxy_set_header X-Forwarded-Host $the_host; +proxy_set_header X-Forwarded-Proto $the_scheme; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/build/configs/orchestrated/nginx/includes/http-upstream.conf b/build/configs/orchestrated/nginx/includes/http-upstream.conf new file mode 100644 index 0000000000..07d2cb254d --- /dev/null +++ b/build/configs/orchestrated/nginx/includes/http-upstream.conf @@ -0,0 +1,11 @@ +upstream docservice { + server $DOCSERVICE_HOST_PORT max_fails=0 fail_timeout=0s; +} + +upstream adminpanel { + server $ADMINPANEL_HOST_PORT max_fails=0 fail_timeout=0s; +} + +upstream example { + server $EXAMPLE_HOST_PORT; +} diff --git a/build/configs/orchestrated/nginx/nginx.conf b/build/configs/orchestrated/nginx/nginx.conf new file mode 100644 index 0000000000..76b20716c0 --- /dev/null +++ b/build/configs/orchestrated/nginx/nginx.conf @@ -0,0 +1,36 @@ +worker_processes 1; +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; + +# Load dynamic modules. See /usr/share/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log off; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 4096; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; +} diff --git a/build/configs/supervisor/ds-adminpanel.conf b/build/configs/standalone/supervisor/ds-adminpanel.conf similarity index 100% rename from build/configs/supervisor/ds-adminpanel.conf rename to build/configs/standalone/supervisor/ds-adminpanel.conf diff --git a/build/configs/supervisor/ds-converter.conf b/build/configs/standalone/supervisor/ds-converter.conf similarity index 100% rename from build/configs/supervisor/ds-converter.conf rename to build/configs/standalone/supervisor/ds-converter.conf diff --git a/build/configs/supervisor/ds-docservice.conf b/build/configs/standalone/supervisor/ds-docservice.conf similarity index 100% rename from build/configs/supervisor/ds-docservice.conf rename to build/configs/standalone/supervisor/ds-docservice.conf diff --git a/build/configs/supervisor/ds-example.conf b/build/configs/standalone/supervisor/ds-example.conf similarity index 100% rename from build/configs/supervisor/ds-example.conf rename to build/configs/standalone/supervisor/ds-example.conf diff --git a/build/configs/supervisor/ds-metrics.conf b/build/configs/standalone/supervisor/ds-metrics.conf similarity index 100% rename from build/configs/supervisor/ds-metrics.conf rename to build/configs/standalone/supervisor/ds-metrics.conf diff --git a/build/configs/supervisor/supervisord.conf b/build/configs/standalone/supervisor/supervisord.conf similarity index 100% rename from build/configs/supervisor/supervisord.conf rename to build/configs/standalone/supervisor/supervisord.conf diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index 4f0fd67c4e..d75c976d6a 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -41,7 +41,7 @@ variable "CACHE_BUST" { # ────────────────────────────────────────────── group "default" { - targets = ["docker"] + targets = ["standalone"] } group "develop" { @@ -166,10 +166,23 @@ target "packages" { # BUILD TARGETS # ────────────────────────────────────────────── -target "docker" { +target "orchestrated" { inherits = ["_common"] context = ".." - dockerfile = "./build/.docker/docker.bake.Dockerfile" + dockerfile = "./build/.docker/orchestrated.bake.Dockerfile" + target = "docs" + tags = ["${REGISTRY}/docs:${TAG}"] + contexts = { + packages = "target:packages" + } + cache-from = ["type=local,src=/tmp/${REGISTRY}/docs"] + cache-to = ["type=local,dest=/tmp/${REGISTRY}/docs,mode=max"] +} + +target "standalone" { + inherits = ["_common"] + context = ".." + dockerfile = "./build/.docker/standalone.bake.Dockerfile" target = "finalubuntu" tags = ["${REGISTRY}/documentserver:${TAG}"] contexts = { @@ -186,7 +199,7 @@ target "develop" { target = "develop" tags = ["${REGISTRY}/documentserver:${TAG}-dev"] contexts = { - finalubuntu = "target:docker" + finalubuntu = "target:standalone" } cache-from = ["type=local,src=/tmp/${REGISTRY}/develop"] cache-to = ["type=local,dest=/tmp/${REGISTRY}/develop,mode=max"] diff --git a/build/scripts/orchestrated/docker-entrypoint.sh b/build/scripts/orchestrated/docker-entrypoint.sh new file mode 100755 index 0000000000..2be78aad84 --- /dev/null +++ b/build/scripts/orchestrated/docker-entrypoint.sh @@ -0,0 +1,329 @@ +#!/usr/bin/env bash +set -e + +# -------------------------------------------------------------------- +# Service mode (first positional argument) +# Supported modes: +# - docservice +# - converter +# - adminpanel +# -------------------------------------------------------------------- +MODE="${1:-docservice}" +shift || true + +case "$MODE" in + docservice|converter|adminpanel) + ;; + *) + echo "Unknown mode: $MODE (use: docservice|converter|adminpanel)" >&2 + exit 2 + ;; +esac + +if [[ -n ${LOG_LEVEL} ]]; then + sed 's/\(^.\+"level":\s*"\).\+\(".*$\)/\1'$LOG_LEVEL'\2/g' -i /etc/$COMPANY_NAME/documentserver/log4js/production.json +fi + +if [[ -n ${LOG_TYPE} ]]; then + sed 's/\("type"\:\) "pattern"/\1 "'$LOG_TYPE'"/' -i /etc/$COMPANY_NAME/documentserver/log4js/production.json +fi + +if [[ -n ${LOG_PATTERN} ]]; then + sed "s/\(\"pattern\"\:\).*/\1 \"$LOG_PATTERN\"/" -i /etc/$COMPANY_NAME/documentserver/log4js/production.json +fi + +ACTIVEMQ_TRANSPORT="" +case $AMQP_PROTO in + amqps | amqp+ssl) + ACTIVEMQ_TRANSPORT="tls" + ;; + *) + ACTIVEMQ_TRANSPORT="tcp" + ;; +esac + +if [[ -n "$REDIS_SENTINEL_NODES" ]]; then + declare -a REDIS_SENTINEL_NODES_ALL=($REDIS_SENTINEL_NODES) + REDIS_SENTINEL_NODES_ARRAY=() + for node in "${REDIS_SENTINEL_NODES_ALL[@]}"; do + host="${node%%:*}" + port="${node##*:}" + REDIS_SENTINEL_NODES_ARRAY+=('{ "host": "'$host'", "port": '$port' }') + done + OLD_IFS="$IFS" + IFS="," + NODES=$(echo "${REDIS_SENTINEL_NODES_ARRAY[*]}") + IFS="$OLD_IFS" + REDIS_SENTINEL='[ '$NODES' ],' +else + REDIS_SENTINEL='[ { "host": "'${REDIS_SERVER_HOST:-localhost}'", "port": '${REDIS_SERVER_PORT:-6379}' } ],' +fi + +if [[ -n "$REDIS_CLUSTER_NODES" ]]; then + declare -a REDIS_CLUSTER_NODES_ALL=($REDIS_CLUSTER_NODES) + REDIS_CLUSTER_NODES_ARRAY=() + for node in "${REDIS_CLUSTER_NODES_ALL[@]}"; do + REDIS_CLUSTER_NODES_ARRAY+=('{ "url": "redis://'$node'" }') + done + OLD_IFS="$IFS" + IFS="," + NODES=$(echo "${REDIS_CLUSTER_NODES_ARRAY[*]}") + IFS="$OLD_IFS" + REDIS_CLUSTER='"rootNodes": [ '$NODES' ], "defaults": { "username": "'${REDIS_SERVER_USER:-default}'", "password": "'$REDIS_SERVER_PWD'" }' +else + REDIS_CLUSTER='' +fi + +# -------------------------------------------------------------------- +# NODE_CONFIG (exported for Docs services) +# -------------------------------------------------------------------- +export NODE_CONFIG='{ + "statsd": { + "useMetrics": '${METRICS_ENABLED:-false}', + "host": "'${METRICS_HOST:-localhost}'", + "port": '${METRICS_PORT:-8125}', + "prefix": "'${METRICS_PREFIX:-ds.}'" + }, + "runtimeConfig": { + "filePath": "/var/www/'${COMPANY_NAME}'/config/runtime.json" + }, + "services": { + "CoAuthoring": { + "sql": { + "type": "'${DB_TYPE:-postgres}'", + "dbHost": "'${DB_HOST:-localhost}'", + "dbPort": '${DB_PORT:-5432}', + "dbUser": "'${DB_USER:=onlyoffice}'", + "dbName": "'${DB_NAME:-${DB_USER}}'", + "dbPass": "'${DB_PWD:-onlyoffice}'" + }, + "redis": { + "name": "'${REDIS_CONNECTOR_NAME:-redis}'", + "host": "'${REDIS_SERVER_HOST:-${REDIST_SERVER_HOST:-localhost}}'", + "port": '${REDIS_SERVER_PORT:-${REDIST_SERVER_PORT:-6379}}', + "options": { + "user": "'${REDIS_SERVER_USER:-default}'", + "password": "'${REDIS_SERVER_PWD}'", + "db": "'${REDIS_SERVER_DB_NUM:-0}'" + }, + "optionsCluster": { '${REDIS_CLUSTER}' }, + "iooptions": { + "sentinels": '${REDIS_SENTINEL}' + "name": "'${REDIS_SENTINEL_GROUP_NAME:-mymaster}'", + "sentinelPassword": "'${REDIS_SENTINEL_PWD}'", + "username": "'${REDIS_SERVER_USER:-default}'", + "password": "'${REDIS_SERVER_PWD}'", + "db": "'${REDIS_SERVER_DB_NUM:-0}'" + } + }, + "token": { + "enable": { + "browser": '${JWT_ENABLED:=true}', + "request": { + "inbox": '${JWT_ENABLED_INBOX:-${JWT_ENABLED}}', + "outbox": '${JWT_ENABLED_OUTBOX:-${JWT_ENABLED}}' + } + }, + "inbox": { + "header": "'${JWT_HEADER_INBOX:-${JWT_HEADER:=Authorization}}'", + "inBody": '${JWT_IN_BODY:=false}' + }, + "outbox": { + "header": "'${JWT_HEADER_OUTBOX:-${JWT_HEADER}}'", + "inBody": '${JWT_IN_BODY}' + } + }, + "secret": { + "inbox": { + "string": "'${JWT_SECRET_INBOX:-${JWT_SECRET:=secret}}'" + }, + "outbox": { + "string": "'${JWT_SECRET_OUTBOX:-${JWT_SECRET}}'" + }, + "browser": { + "string": "'${JWT_SECRET}'" + }, + "session": { + "string": "'${JWT_SECRET}'" + } + }, + "request-filtering-agent" : { + "allowPrivateIPAddress": '${ALLOW_PRIVATE_IP_ADDRESS:-false}', + "allowMetaIPAddress": '${ALLOW_META_IP_ADDRESS:-false}', + "allowIPAddressList": '${ALLOW_IP_ADDRESS_LIST:-[]}', + "denyIPAddressList": '${DENY_IP_ADDRESS_LIST:-[]}' + } + } + }, + "queue": { + "type": "'${AMQP_TYPE:=rabbitmq}'" + }, + "activemq": { + "connectOptions": { + "port": "'${AMQP_PORT:=5672}'", + "host": "'${AMQP_HOST:=localhost}'", + "username": "'${AMQP_USER:=guest}'", + "password": "'${AMQP_PWD:=guest}'", + "transport": "'${ACTIVEMQ_TRANSPORT}'" + } + }, + "rabbitmq": { + "url": "'${AMQP_URI:-${AMQP_PROTO:-amqp}://${AMQP_USER}:${AMQP_PWD}@${AMQP_HOST}:${AMQP_PORT}${AMQP_VHOST:-/}}'" + }, + "wopi": { + "enable": '${WOPI_ENABLED:-false}', + "privateKey": "'${WOPI_PRIVATE_KEY}'", + "privateKeyOld": "'${WOPI_PRIVATE_KEY_OLD}'", + "publicKey": "'${WOPI_PUBLIC_KEY}'", + "publicKeyOld": "'${WOPI_PUBLIC_KEY_OLD}'", + "modulus": "'${WOPI_MODULUS_KEY}'", + "modulusOld": "'${WOPI_MODULUS_KEY_OLD}'", + "exponent": '${WOPI_EXPONENT_KEY:=65537}', + "exponentOld": '${WOPI_EXPONENT_KEY_OLD:-${WOPI_EXPONENT_KEY}}' + }, + "FileConverter": { + "converter": { + "maxprocesscount": 0.001, + "signingKeyStorePath": "/var/www/'${COMPANY_NAME}'/config/signing-keystore.p12" + } + }, + "storage": { + "fs": { + "folderPath": "/var/lib/'${COMPANY_NAME}'/documentserver/App_Data/cache/files/'${STORAGE_SUBDIRECTORY_NAME:-latest}'", + "secretString": "'${SECURE_LINK_SECRET:-verysecretstring}'" + }, + "storageFolderName": "files/'${STORAGE_SUBDIRECTORY_NAME:-latest}'" + }, + "persistentStorage": { + "fs": { + "folderPath": "/var/lib/'${COMPANY_NAME}'/documentserver/App_Data/cache/files", + "secretString": "'${SECURE_LINK_SECRET:-verysecretstring}'" + }, + "storageFolderName": "files" + } +}' + +WORK_DIR="/var/www/$COMPANY_NAME/documentserver" +BUILD_FONTS=false +BUILD_PLUGINS=false +BUILD_DICTIONARIES=false + +OPTIND=1 +while getopts ":fpd" opt; do + case "$opt" in + f) BUILD_FONTS=true ;; + p) BUILD_PLUGINS=true ;; + d) BUILD_DICTIONARIES=true ;; + \?) + echo "Unknown option: -$OPTARG" >&2 + exit 2 + ;; + esac +done + +shift $((OPTIND - 1)) + +if [[ "${BUILD_FONTS}" == "true" ]]; then + if [[ "$MODE" == "converter" ]]; then + if [ "$(find "$WORK_DIR/fonts" -mindepth 1 -maxdepth 1 -print -quit)" ]; then + echo -e "\e[0;32m Fonts have already been added, preparatory steps, please wait... \e[0m" + if [[ -n "$DOCS_SHARDS" ]]; then + until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8888/index.html || true)" = "200" ] + do + sleep 5 + done + fi + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/AllFonts.js $WORK_DIR/sdkjs/common/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/bin/* $WORK_DIR/server/FileConverter/bin/ + echo -e "\e[0;32m Completed \e[0m" + else + if [[ -n "$DOCS_SHARDS" ]]; then + echo -e "\e[0;32m Waiting for Fonts to be added, please wait... \e[0m" + until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8888/index.html || true)" = "200" ] + do + sleep 5 + done + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/AllFonts.js $WORK_DIR/sdkjs/common/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/bin/* $WORK_DIR/server/FileConverter/bin/ + else + echo -e "\e[0;32m Run Fonts adding, please wait... \e[0m" + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/Images/* $WORK_DIR/sdkjs/common/Images/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/themes/* $WORK_DIR/sdkjs/slide/themes/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/fonts/* $WORK_DIR/fonts/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/custom-k8s/* $WORK_DIR/core-fonts/custom-k8s/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/AllFonts.js $WORK_DIR/sdkjs/common/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/bin/* $WORK_DIR/server/FileConverter/bin/ + fi + echo -e "\e[0;32m Fonts have been added successfully \e[0m" + fi + fi +fi + +if [[ "${BUILD_PLUGINS}" == "true" ]]; then + if [[ "$MODE" != "converter" ]]; then + echo -e "\e[0;32m Waiting for Plugins to be added, please wait... \e[0m" + until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8888/ 2>/dev/null || true)" != "000" ] + do + sleep 5 + done + if [ "$(find "$WORK_DIR/sdkjs-plugins" -mindepth 1 -maxdepth 1 -print -quit)" ]; then + echo -e "\e[0;32m Plugins have been added successfully \e[0m" + else + echo -e "\e[0;31m No plugins added \e[0m" + fi + fi +fi + +if [[ "${BUILD_DICTIONARIES}" == "true" ]]; then + if [[ "$MODE" == "converter" ]]; then + echo -e "\e[0;32m Run Dictionaries adding, please wait... \e[0m" + ( find $WORK_DIR/sdkjs/cell $WORK_DIR/sdkjs/word $WORK_DIR/sdkjs/slide $WORK_DIR/sdkjs/visio -maxdepth 1 -type f \( -name '*.js' -o -name '*.bin' \) + echo "$WORK_DIR/sdkjs/common/spell/spell/spell.js" ) | while read -r file; do + chmod 740 "$file" + dir=$(basename "$(dirname "$file")") + base_file=$(basename "$file") + if [[ "${base_file}" == "spell.js" ]]; then + target_dir="$WORK_DIR/sdkjs/common/spell/$dir" + else + target_dir="$WORK_DIR/sdkjs/$dir" + fi + cp -a "/var/lib/$COMPANY_NAME/documentserver/buffer/dictionaries/$dir/$base_file" "$target_dir/" + chmod 440 "$target_dir/$base_file" + done + if [ "$(find "$WORK_DIR/dictionaries" -mindepth 1 -maxdepth 1 -print -quit)" ]; then + if [[ -n "$DOCS_SHARDS" ]]; then + until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8888/index.html || true)" = "200" ] + do + sleep 5 + done + fi + echo -e "\e[0;32m Completed \e[0m" + else + if [[ -n "$DOCS_SHARDS" ]]; then + echo -e "\e[0;32m Waiting for Dictionaries to be added, please wait... \e[0m" + until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8888/index.html || true)" = "200" ] + do + sleep 5 + done + else + cp -ra /var/lib/$COMPANY_NAME/documentserver/buffer/dictionaries/dictionaries/* $WORK_DIR/dictionaries/ + fi + echo -e "\e[0;32m Dictionaries have been added successfully \e[0m" + fi + fi +fi + +# -------------------------------------------------------------------- +# Exec docs service +# -------------------------------------------------------------------- +case "$MODE" in + docservice) + exec "/var/www/${COMPANY_NAME}/documentserver/server/DocService/docservice" "$@" + ;; + converter) + exec "/var/www/${COMPANY_NAME}/documentserver/server/FileConverter/converter" "$@" + ;; + adminpanel) + exec "/var/www/${COMPANY_NAME}/documentserver/server/AdminPanel/server/adminpanel" "$@" + ;; +esac diff --git a/build/scripts/orchestrated/example-docker-entrypoint.sh b/build/scripts/orchestrated/example-docker-entrypoint.sh new file mode 100755 index 0000000000..e124442f87 --- /dev/null +++ b/build/scripts/orchestrated/example-docker-entrypoint.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -e +export NODE_CONFIG='{ + "server": { + "siteUrl": "'${DS_URL:-"/"}'", + "token": { + "enable": '${JWT_ENABLED:-false}', + "secret": "'${JWT_SECRET:-secret}'", + "authorizationHeader": "'${JWT_HEADER:-Authorization}'" + } + } + }' + +exec "$@" \ No newline at end of file diff --git a/build/scripts/orchestrated/init-docker-entrypoint.sh b/build/scripts/orchestrated/init-docker-entrypoint.sh new file mode 100755 index 0000000000..6048d1290a --- /dev/null +++ b/build/scripts/orchestrated/init-docker-entrypoint.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +set -e + +WORK_DIR="/var/www/$COMPANY_NAME/documentserver" +BUILD_FONTS=false +BUILD_PLUGINS=false +BUILD_DICTIONARIES=false + +OPTIND=1 +while getopts ":fpd" opt; do + case "$opt" in + f) BUILD_FONTS=true ;; + p) BUILD_PLUGINS=true ;; + d) BUILD_DICTIONARIES=true ;; + \?) + echo "Unknown option: -$OPTARG" >&2 + exit 2 + ;; + esac +done +shift $((OPTIND-1)) + +cleanup_dir() { + local dir="$1" + if [[ -d "$dir" ]]; then + chmod 755 -R "$dir" + rm -rf "$dir" + fi +} + +build_fonts() { + [[ "$BUILD_FONTS" != "true" ]] && return + echo -e "\e[0;32m The build of new Fonts is running, please wait... \e[0m" + local buffer_dir="/var/lib/$COMPANY_NAME/documentserver/buffer/fonts" + cleanup_dir "$buffer_dir" + chmod 755 "$WORK_DIR/sdkjs/common" + chmod 755 "$WORK_DIR/sdkjs/common/Images" + chmod 755 "$WORK_DIR/sdkjs/slide/themes" + chmod 755 "$WORK_DIR/server/FileConverter/bin" + /usr/local/bin/documentserver-generate-allfonts.sh true true + mkdir -p "$buffer_dir/bin" + cp -ra "$WORK_DIR/sdkjs/common/Images/" "$buffer_dir/" + cp -ra "$WORK_DIR/sdkjs/slide/themes/" "$buffer_dir/" + cp -ra "$WORK_DIR/fonts" "$buffer_dir/" + cp -ra "$WORK_DIR/core-fonts/custom-k8s" "$buffer_dir/" + cp -a "$WORK_DIR/sdkjs/common/AllFonts.js" "$buffer_dir/" + cp -a \ + "$WORK_DIR/server/FileConverter/bin/AllFonts.js" \ + "$WORK_DIR/server/FileConverter/bin/font_selection.bin" \ + "$WORK_DIR/server/FileConverter/bin/fonts.log" \ + "$buffer_dir/bin/" + echo -e "\e[0;32m Changed files have been added successfully \e[0m" +} + +build_plugins() { + [[ "$BUILD_PLUGINS" != "true" ]] && return + echo -e "\e[0;32m The build of new Plugins is running, please wait... \e[0m" + local buffer_dir="/var/lib/$COMPANY_NAME/documentserver/buffer/plugins" + cleanup_dir "$buffer_dir" + chmod 755 "$WORK_DIR/sdkjs-plugins" + if [[ -n "$PLUGINS_LIST_DEFAULT" ]]; then + find "$WORK_DIR/sdkjs-plugins" -mindepth 1 -maxdepth 1 -name '{*' -exec rm -rf -- {} + + fi + if [[ "${PLUGINS_MARKET_DISABLED}" == "true" ]]; then + chmod 755 -R "$WORK_DIR/sdkjs-plugins/marketplace" + rm -rf "$WORK_DIR/sdkjs-plugins/marketplace" + fi + /usr/local/bin/documentserver-pluginsmanager.sh -r false -k true --update=\"/var/www/$COMPANY_NAME/documentserver/sdkjs-plugins/plugin-list-default.json\" + mkdir -p "$buffer_dir" + cp -ra "$WORK_DIR/sdkjs-plugins" "$buffer_dir/" + echo -e "\e[0;32m Changed files have been added successfully \e[0m" +} + +build_dictionaries() { + [[ "$BUILD_DICTIONARIES" != "true" ]] && return + echo -e "\e[0;32m The build of new Dictionaries is running, please wait... \e[0m" + local buffer_dir="/var/lib/$COMPANY_NAME/documentserver/buffer/dictionaries" + cleanup_dir "$buffer_dir" + ( find "$WORK_DIR/sdkjs/cell" "$WORK_DIR/sdkjs/word" "$WORK_DIR/sdkjs/slide" "$WORK_DIR/sdkjs/visio" -maxdepth 1 -type f \( -name '*.js' -o -name '*.bin' \) + echo "$WORK_DIR/sdkjs/common/spell/spell/spell.js" ) | while read -r file; do + chmod 755 "$(dirname "$file")" + chmod 740 "$file" + done + chmod 755 "$WORK_DIR/dictionaries" + python3 "$WORK_DIR/server/dictionaries/update.py" + mkdir -p "$buffer_dir/spell" + ( find "$WORK_DIR/sdkjs/cell" "$WORK_DIR/sdkjs/word" "$WORK_DIR/sdkjs/slide" "$WORK_DIR/sdkjs/visio" -maxdepth 1 -type f \( -name '*.js' -o -name '*.bin' \) + echo "$WORK_DIR/sdkjs/common/spell/spell/spell.js" ) | while read -r file; do + dir=$(basename "$(dirname "$file")") + mkdir -p "$buffer_dir/$dir" + cp -a "$file" "$buffer_dir/$dir/" + done + cp -ra "$WORK_DIR/dictionaries" "$buffer_dir/" + echo -e "\e[0;32m Changed files have been added successfully \e[0m" +} + +build_fonts +build_plugins +build_dictionaries diff --git a/build/scripts/orchestrated/proxy-docker-entrypoint.sh b/build/scripts/orchestrated/proxy-docker-entrypoint.sh new file mode 100755 index 0000000000..0f9dbab2ec --- /dev/null +++ b/build/scripts/orchestrated/proxy-docker-entrypoint.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +set -e + +if ! [ -d /tmp/proxy_nginx ]; then + mkdir /tmp/proxy_nginx +fi + +cp -r /etc/nginx/* /tmp/proxy_nginx/ +sed 's|\(worker_connections\) [[:digit:]]*;|\1 '$NGINX_WORKER_CONNECTIONS';|g' -i /tmp/proxy_nginx/nginx.conf +sed "s/\(worker_processes\).*/\1 $NGINX_WORKER_PROCESSES;/" -i /tmp/proxy_nginx/nginx.conf + +if [[ -n "$NGINX_LOG_FORMAT" ]]; then + sed "s/\(log_format main\).*/\1 '$NGINX_LOG_FORMAT';/" -i /tmp/proxy_nginx/nginx.conf +fi + +if [[ "$NGINX_ACCESS_LOG" != "off" ]]; then + sed 's|#*\(\s*access_log\).*;|\1 /var/log/nginx/access.log '$NGINX_ACCESS_LOG';|g' -i /tmp/proxy_nginx/nginx.conf +fi + +envsubst < /tmp/proxy_nginx/includes/http-upstream.conf > /tmp/http-upstream.conf +envsubst < /etc/nginx/includes/ds-common.conf | tee /tmp/proxy_nginx/includes/ds-common.conf > /dev/null +sed "s,\(set \+\$secure_link_secret\).*,\1 "${SECURE_LINK_SECRET:-verysecretstring}";," -i /tmp/proxy_nginx/conf.d/ds.conf +sed "s/\(client_max_body_size\).*/\1 $NGINX_CLIENT_MAX_BODY_SIZE;/" -i /tmp/proxy_nginx/includes/ds-common.conf + +if [[ ! -f "/proc/net/if_inet6" ]]; then + sed '/listen\s\+\[::[0-9]*\].\+/d' -i /tmp/proxy_nginx/conf.d/ds.conf +fi + +WELCOME_PATH="/var/www/$COMPANY_NAME/documentserver-example/welcome" +WELCOME_PAGE="$WELCOME_PATH/k8s.html" +ADMIN_PANEL_DISABLED_PAGE="$WELCOME_PATH/admin-disabled.html" +EXAMPLE_DISABLED_PAGE="$WELCOME_PATH/example-disabled.html" +if [[ -n "$DOCS_SHARDS" ]]; then + sed -i 's/\(Kubernetes-Docs\)\(-Shards\)\?/\1-Shards/g' "$WELCOME_PAGE" + sed -Ei 's|
sudo systemctl start ds-(adminpanel\|example).*
|
\helm upgrade documentserver onlyoffice/docs-shards --set \1.enabled=true
|g' "$ADMIN_PANEL_DISABLED_PAGE" "$EXAMPLE_DISABLED_PAGE" +else + sed -Ei 's|
sudo systemctl start ds-(adminpanel\|example).*
|
\helm upgrade documentserver onlyoffice/docs --set \1.enabled=true
|g' "$ADMIN_PANEL_DISABLED_PAGE" "$EXAMPLE_DISABLED_PAGE" +fi + +for page in \ + "$WELCOME_PAGE" \ + "$ADMIN_PANEL_DISABLED_PAGE" \ + "$EXAMPLE_DISABLED_PAGE" +do + gzip -cf9 "$page" > "$page.gz" +done + +if [[ -n "$INFO_ALLOWED_IP" ]]; then + declare -a IP_ALL=($INFO_ALLOWED_IP) + for ip in "${IP_ALL[@]}"; do + sed -i '/(info)/a\ allow '$ip'\;' /tmp/proxy_nginx/includes/ds-docservice.conf + done +fi + +if [[ -n "$INFO_ALLOWED_USER" ]]; then + htpasswd -c -b /tmp/auth "${INFO_ALLOWED_USER}" "${INFO_ALLOWED_PASSWORD:-password}" + sed -i '/(info)/a\ auth_basic \"Authentication Required\"\;' /tmp/proxy_nginx/includes/ds-docservice.conf + sed -i '/auth_basic/a\ auth_basic_user_file \/tmp\/auth\;' /tmp/proxy_nginx/includes/ds-docservice.conf +fi + +WORK_DIR="/var/www/$COMPANY_NAME/documentserver" +BUILD_FONTS=false +BUILD_PLUGINS=false +BUILD_DICTIONARIES=false + +OPTIND=1 +while getopts ":fpd" opt; do + case "$opt" in + f) BUILD_FONTS=true ;; + p) BUILD_PLUGINS=true ;; + d) BUILD_DICTIONARIES=true ;; + \?) + echo "Unknown option: -$OPTARG" >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +if [[ "${BUILD_FONTS}" == "true" ]]; then + if [ "$(find "$WORK_DIR/fonts" -mindepth 1 -maxdepth 1 -print -quit)" ]; then + echo -e "\e[0;32m Fonts have already been added, preparatory steps, please wait... \e[0m" + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/AllFonts.js $WORK_DIR/sdkjs/common/ + gzip -cf9 "$WORK_DIR/sdkjs/common/AllFonts.js" > "$WORK_DIR/sdkjs/common/AllFonts.js.gz" && chown ds:ds "$WORK_DIR/sdkjs/common/AllFonts.js.gz" + echo -e "\e[0;32m Completed \e[0m" + else + echo -e "\e[0;32m Run Fonts adding, please wait... \e[0m" + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/Images/* $WORK_DIR/sdkjs/common/Images/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/themes/* $WORK_DIR/sdkjs/slide/themes/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/fonts/* $WORK_DIR/fonts/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/custom-k8s/* $WORK_DIR/core-fonts/custom-k8s/ + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/fonts/AllFonts.js $WORK_DIR/sdkjs/common/ + find $WORK_DIR/fonts \ + -type f ! \ + -name "*.*" \ + -exec sh -c 'gzip -cf9 $0 > $0.gz && chown ds:ds $0.gz' {} \; + chmod 755 $WORK_DIR/sdkjs/common/Images/cursors/ + find $WORK_DIR/sdkjs/common \ + $WORK_DIR/sdkjs/slide/themes \ + -type f \ + \( -name '*.js' -o -name '*.json' -o -name '*.htm' -o -name '*.html' -o -name '*.css' \) \ + -exec sh -c 'gzip -cf9 $0 > $0.gz && chown ds:ds $0.gz' {} \; + chmod 555 $WORK_DIR/sdkjs/common/Images/cursors/ + echo -e "\e[0;32m Fonts have been added successfully \e[0m" + fi +fi + +if [[ "${BUILD_PLUGINS}" == "true" ]]; then + if [ "$(find "$WORK_DIR/sdkjs-plugins" -mindepth 1 -maxdepth 1 -print -quit)" ]; then + echo -e "\e[0;32m Plugins have already been added... \e[0m" + else + echo -e "\e[0;32m Run Plugins adding, please wait... \e[0m" + cp -a /var/lib/$COMPANY_NAME/documentserver/buffer/plugins/sdkjs-plugins/* $WORK_DIR/sdkjs-plugins/ + find $WORK_DIR/sdkjs-plugins/* -type d -exec chmod u+w {} \; + find $WORK_DIR/sdkjs-plugins \ + -type f \ + \( -name '*.js' -o -name '*.json' -o -name '*.htm' -o -name '*.html' -o -name '*.css' \) \ + -exec sh -c 'gzip -cf9 $0 > $0.gz && chown ds:ds $0.gz' {} \; + echo -e "\e[0;32m Plugins have been added successfully \e[0m" + fi +fi + +if [[ "${BUILD_DICTIONARIES}" == "true" ]]; then + echo -e "\e[0;32m Run Dictionaries adding, please wait... \e[0m" + ( find $WORK_DIR/sdkjs/cell $WORK_DIR/sdkjs/word $WORK_DIR/sdkjs/slide $WORK_DIR/sdkjs/visio -maxdepth 1 -type f -name '*.js' + echo "$WORK_DIR/sdkjs/common/spell/spell/spell.js" ) | while read -r file; do + chmod 740 "$file" + dir=$(basename "$(dirname "$file")") + base_file=$(basename "$file") + if [[ "${base_file}" == "spell.js" ]]; then + target_dir="$WORK_DIR/sdkjs/common/spell/$dir" + else + target_dir="$WORK_DIR/sdkjs/$dir" + fi + cp -a "/var/lib/$COMPANY_NAME/documentserver/buffer/dictionaries/$dir/$base_file" "$target_dir/" + gzip -cf9 "$target_dir/$base_file" > "$target_dir/$base_file.gz" + chmod 440 "$target_dir/$base_file" + done + if [ "$(find "$WORK_DIR/dictionaries" -mindepth 1 -maxdepth 1 -print -quit)" ]; then + echo -e "\e[0;32m Completed \e[0m" + else + cp -ra /var/lib/$COMPANY_NAME/documentserver/buffer/dictionaries/dictionaries/* $WORK_DIR/dictionaries/ + echo -e "\e[0;32m Dictionaries have been added successfully \e[0m" + fi +fi + +if [[ "$BUILD_FONTS" == "true" || "$BUILD_PLUGINS" == "true" || "$BUILD_DICTIONARIES" == "true" ]]; then + echo "set \$cache_tag \"$DS_VERSION_HASH\";" > /tmp/proxy_nginx/includes/ds-cache.conf + API_PATH="$WORK_DIR/web-apps/apps/api/documents/api.js" + chmod 755 $(dirname "$API_PATH") + cp -f ${API_PATH}.tpl ${API_PATH} + sed -i "s/{{HASH_POSTFIX}}/${DS_VERSION_HASH}/g" ${API_PATH} + rm -f ${API_PATH}.gz + gzip -cf9 "$API_PATH" > "$API_PATH.gz" + chmod 555 $(dirname "$API_PATH") +fi + +exec nginx -c /tmp/proxy_nginx/nginx.conf -g 'daemon off;' diff --git a/build/scripts/entrypoint.sh b/build/scripts/standalone/entrypoint.sh similarity index 100% rename from build/scripts/entrypoint.sh rename to build/scripts/standalone/entrypoint.sh From da5aa285d40443f8bcd943ae38db906bcf83b37f Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Wed, 13 May 2026 16:28:12 -0700 Subject: [PATCH 2/7] feat: add more needed cluster images Signed-off-by: Hendrik Leidinger --- build/.docker/orchestrated.bake.Dockerfile | 102 ++++++++++++++++++++- build/docker-bake.hcl | 33 ++++++- build/scripts/orchestrated/disql | 3 + build/scripts/orchestrated/sqlplus | 3 + 4 files changed, 138 insertions(+), 3 deletions(-) create mode 100755 build/scripts/orchestrated/disql create mode 100755 build/scripts/orchestrated/sqlplus diff --git a/build/.docker/orchestrated.bake.Dockerfile b/build/.docker/orchestrated.bake.Dockerfile index 01466709e4..c740b53a49 100644 --- a/build/.docker/orchestrated.bake.Dockerfile +++ b/build/.docker/orchestrated.bake.Dockerfile @@ -242,4 +242,104 @@ FROM ds-base AS docs # command: ["proxy-docker-entrypoint.sh"] # args: [...] # -------------------------------------------------------------------- - CMD ["docservice"] \ No newline at end of file + CMD ["docservice"] + + +FROM node:20-alpine3.19 AS example + LABEL maintainer Euro-Office + + ENV LANG=en_US.UTF-8 \ + LANGUAGE=en_US:en \ + LC_ALL=en_US.UTF-8 \ + NODE_ENV=production-linux \ + NODE_CONFIG_DIR=/etc/euro-office/documentserver-example/ + + WORKDIR /var/www/euro-office/documentserver-example/ + + RUN apk update && \ + apk add git && \ + git clone \ + --depth 1 \ + --recurse-submodules \ + https://github.com/Euro-Office/document-server-integration.git && \ + mkdir -p /var/www/euro-office/documentserver-example && \ + cp -r ./document-server-integration/web/documentserver-example/nodejs/. \ + /var/www/euro-office/documentserver-example/ && \ + rm -rf ./document-server-integration && \ + addgroup -S -g 1001 ds && \ + adduser \ + -S \ + -G ds \ + -D \ + -h /var/www/euro-office/documentserver-example \ + -s /sbin/nologin \ + -u 1001 ds && \ + chown -R ds:ds /var/www/euro-office/documentserver-example/ && \ + mkdir -p /var/lib/euro-office/documentserver-example/ && \ + chown -R ds:ds /var/lib/euro-office/ && \ + mv files /var/lib/euro-office/documentserver-example/ && \ + mkdir -p /etc/euro-office/documentserver-example/ && \ + chown -R ds:ds /etc/euro-office/ && \ + mv config/* /etc/euro-office/documentserver-example/ && \ + npm install + + EXPOSE 3000 + + USER ds + + ENTRYPOINT ["/var/www/euro-office/documentserver-example/docker-entrypoint.sh", "npm", "start"] + +FROM python:3.11-bookworm AS builder + RUN pip install redis psycopg2 PyMySQL pika python-qpid-proton func_timeout requests kubernetes flask + + +FROM python:3.11-slim-bookworm AS utils + ARG TARGETARCH + ARG DS_VERSION_HASH + ENV DS_VERSION_HASH=$DS_VERSION_HASH + COPY --from=ds-base /usr/local/bin/dumb-init /usr/local/bin/dumb-init + COPY --from=ds-base /opt/oracle/instantclient_23_7 /oracle/instantclient + COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages + RUN apt update && \ + apt-get install -y curl wget gnupg2 lsb-release jq xxd procps libaio1 unzip && \ + echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \ + wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \ + curl -sSL https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc && \ + echo "deb [arch=${TARGETARCH}] https://packages.microsoft.com/debian/$(lsb_release -rs)/prod $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/mssql.list && \ + apt-get update && \ + ACCEPT_EULA=Y apt install -y postgresql-client-17 default-mysql-client mssql-tools18 unixodbc-dev && \ + curl -LO \ + https://dl.k8s.io/release/`curl \ + -L -s https://dl.k8s.io/release/stable.txt`/bin/linux/${TARGETARCH}/kubectl && \ + chmod +x ./kubectl && \ + mv ./kubectl /usr/local/bin/kubectl && \ + mkdir /oracle/sqlplus /dameng /scripts && \ + wget -O /oracle/sqlplus/sqlplus.zip https://download.oracle.com/otn_software/linux/instantclient/2370000/instantclient-sqlplus-linux.x64-23.7.0.25.01.zip && \ + unzip -o /oracle/sqlplus/sqlplus.zip -d /oracle/sqlplus && \ + mv /oracle/sqlplus/instantclient_23_7/* /oracle/instantclient/ && \ + rm -rf /oracle/sqlplus && \ + groupadd --system -g 1006 ds && \ + useradd --system -g ds -d /home/ds -s /bin/bash -u 101 ds && \ + chown -R ds:ds /scripts && \ + chmod +x /usr/local/bin/dumb-init && \ + rm -rf /var/lib/apt/lists/* + COPY build/scripts/orchestrated/sqlplus /usr/bin/sqlplus + COPY build/scripts/orchestrated/disql /usr/bin/disql + COPY --from=onlyoffice/damengdb:8.1.2 /opt/dmdbms/bin /dameng + USER ds + +FROM statsd/statsd AS metrics + ARG COMPANY_NAME=onlyoffice + COPY --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/Metrics/config/config.js /usr/src/app/config.js + +FROM postgres:$POSTGRES_VERSION AS db + ARG COMPANY_NAME=onlyoffice + COPY --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/schema/postgresql/createdb.sql /docker-entrypoint-initdb.d/ + +FROM mysql:$MYSQL_VERSION AS mysqldb + ARG COMPANY_NAME=onlyoffice + COPY --chmod=777 --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/schema/mysql/createdb.sql /docker-entrypoint-initdb.d/ + +FROM mariadb:$MARIADB_VERSION AS db-mariadb + ARG COMPANY_NAME=onlyoffice + COPY --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/schema/mysql/createdb.sql /docker-entrypoint-initdb.d/ \ No newline at end of file diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index d75c976d6a..da092ce56b 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -44,6 +44,10 @@ group "default" { targets = ["standalone"] } +group "cluster" { + targets = ["cluster-utils", "cluster-example", "cluster-docs"] +} + group "develop" { targets = ["develop"] } @@ -166,12 +170,14 @@ target "packages" { # BUILD TARGETS # ────────────────────────────────────────────── -target "orchestrated" { +### Orchestrated images + +target "cluster-docs" { inherits = ["_common"] context = ".." dockerfile = "./build/.docker/orchestrated.bake.Dockerfile" target = "docs" - tags = ["${REGISTRY}/docs:${TAG}"] + tags = ["${REGISTRY}/cluster-docs:${TAG}"] contexts = { packages = "target:packages" } @@ -179,6 +185,29 @@ target "orchestrated" { cache-to = ["type=local,dest=/tmp/${REGISTRY}/docs,mode=max"] } +target "cluster-example" { + inherits = ["_common"] + context = ".." + dockerfile = "./build/.docker/orchestrated.bake.Dockerfile" + target = "example" + tags = ["${REGISTRY}/cluster-example:${TAG}"] + cache-from = ["type=local,src=/tmp/${REGISTRY}/example"] + cache-to = ["type=local,dest=/tmp/${REGISTRY}/example,mode=max"] +} + +target "cluster-utils" { + inherits = ["_common"] + context = ".." + dockerfile = "./build/.docker/orchestrated.bake.Dockerfile" + target = "utils" + tags = ["${REGISTRY}/cluster-utils:${TAG}"] + cache-from = ["type=local,src=/tmp/${REGISTRY}/utils"] + cache-to = ["type=local,dest=/tmp/${REGISTRY}/utils,mode=max"] +} + + +### Standalone image + target "standalone" { inherits = ["_common"] context = ".." diff --git a/build/scripts/orchestrated/disql b/build/scripts/orchestrated/disql new file mode 100755 index 0000000000..a7eabc2cb5 --- /dev/null +++ b/build/scripts/orchestrated/disql @@ -0,0 +1,3 @@ +#!/bin/bash +export LD_LIBRARY_PATH=/dameng +/dameng/disql "$@" diff --git a/build/scripts/orchestrated/sqlplus b/build/scripts/orchestrated/sqlplus new file mode 100755 index 0000000000..3433564633 --- /dev/null +++ b/build/scripts/orchestrated/sqlplus @@ -0,0 +1,3 @@ +#!/bin/bash +export LD_LIBRARY_PATH=/oracle/instantclient +/oracle/instantclient/sqlplus "$@" From bb56b636db2a8d55a7166d1072ae87a729035169 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Fri, 15 May 2026 10:03:39 -0700 Subject: [PATCH 3/7] fix: some cluster image bugs Signed-off-by: Hendrik Leidinger --- build/.docker/orchestrated.bake.Dockerfile | 21 +++++++++++++-------- build/docker-bake.hcl | 5 +++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/build/.docker/orchestrated.bake.Dockerfile b/build/.docker/orchestrated.bake.Dockerfile index c740b53a49..b0813d74ef 100644 --- a/build/.docker/orchestrated.bake.Dockerfile +++ b/build/.docker/orchestrated.bake.Dockerfile @@ -256,12 +256,14 @@ FROM node:20-alpine3.19 AS example WORKDIR /var/www/euro-office/documentserver-example/ + COPY document-server-integration ./document-server-integration + RUN apk update && \ apk add git && \ - git clone \ - --depth 1 \ - --recurse-submodules \ - https://github.com/Euro-Office/document-server-integration.git && \ + #git clone \ + #--depth 1 \ + #--recurse-submodules \ + #https://github.com/Euro-Office/document-server-integration.git && \ mkdir -p /var/www/euro-office/documentserver-example && \ cp -r ./document-server-integration/web/documentserver-example/nodejs/. \ /var/www/euro-office/documentserver-example/ && \ @@ -281,6 +283,9 @@ FROM node:20-alpine3.19 AS example mkdir -p /etc/euro-office/documentserver-example/ && \ chown -R ds:ds /etc/euro-office/ && \ mv config/* /etc/euro-office/documentserver-example/ && \ + rmdir config && \ + ln -sf /etc/euro-office/documentserver-example \ + /var/www/euro-office/documentserver-example/config && \ npm install EXPOSE 3000 @@ -329,17 +334,17 @@ FROM python:3.11-slim-bookworm AS utils USER ds FROM statsd/statsd AS metrics - ARG COMPANY_NAME=onlyoffice + ARG COMPANY_NAME=euro-office COPY --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/Metrics/config/config.js /usr/src/app/config.js FROM postgres:$POSTGRES_VERSION AS db - ARG COMPANY_NAME=onlyoffice + ARG COMPANY_NAME=euro-office COPY --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/schema/postgresql/createdb.sql /docker-entrypoint-initdb.d/ FROM mysql:$MYSQL_VERSION AS mysqldb - ARG COMPANY_NAME=onlyoffice + ARG COMPANY_NAME=euro-office COPY --chmod=777 --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/schema/mysql/createdb.sql /docker-entrypoint-initdb.d/ FROM mariadb:$MARIADB_VERSION AS db-mariadb - ARG COMPANY_NAME=onlyoffice + ARG COMPANY_NAME=euro-office COPY --from=ds-service /var/www/$COMPANY_NAME/documentserver/server/schema/mysql/createdb.sql /docker-entrypoint-initdb.d/ \ No newline at end of file diff --git a/build/docker-bake.hcl b/build/docker-bake.hcl index da092ce56b..2b694ffc8d 100644 --- a/build/docker-bake.hcl +++ b/build/docker-bake.hcl @@ -12,6 +12,10 @@ variable "PRODUCT_VERSION" { default = "9.3.1" } +variable "DS_VERSION_HASH" { + default = "dev001" +} + variable "BUILD_ROOT" { default = "/package" } @@ -59,6 +63,7 @@ group "develop" { target "_common" { args = { PRODUCT_VERSION = "${PRODUCT_VERSION}" + DS_VERSION_HASH = "${DS_VERSION_HASH}" BUILD_ROOT = "${BUILD_ROOT}" NUGET_CACHE = "${NUGET_CACHE}" CACHE_BUST = "${CACHE_BUST}" From 2efd74aef083b7cdbd397e109ed4e5356add03e5 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Fri, 15 May 2026 11:14:54 -0700 Subject: [PATCH 4/7] fix: adapted github workflow Signed-off-by: Hendrik Leidinger --- .github/workflows/build.yml | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b704485d5b..98f874d251 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,14 +134,14 @@ jobs: # docker target: push on default branch and git tags if [[ "$IS_DEFAULT" == "true" ]]; then - echo "docker_tag=nightly-${{ matrix.arch }}" >> $GITHUB_OUTPUT - echo "docker_push=true" >> $GITHUB_OUTPUT + echo "images_tag=nightly-${{ matrix.arch }}" >> $GITHUB_OUTPUT + echo "images_push=true" >> $GITHUB_OUTPUT elif [[ "$IS_TAG" == "true" ]]; then - echo "docker_tag=latest-${{ matrix.arch }}" >> $GITHUB_OUTPUT - echo "docker_push=true" >> $GITHUB_OUTPUT + echo "images_tag=latest-${{ matrix.arch }}" >> $GITHUB_OUTPUT + echo "images_push=true" >> $GITHUB_OUTPUT else - echo "docker_tag=${REF_NAME}-${{ matrix.arch }}" >> $GITHUB_OUTPUT - echo "docker_push=false" >> $GITHUB_OUTPUT + echo "images_tag=${REF_NAME}-${{ matrix.arch }}" >> $GITHUB_OUTPUT + echo "images_push=false" >> $GITHUB_OUTPUT fi # develop target: push on default branch only @@ -188,17 +188,29 @@ jobs: packages.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-packages-buildcache-${{ matrix.arch }} packages.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-packages-buildcache-${{ matrix.arch }},mode=max packages.tags= - docker.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-docker-buildcache-${{ matrix.arch }} - docker.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-docker-buildcache-${{ matrix.arch }},mode=max - docker.tags=${{ steps.meta.outputs.docker_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.docker_tag) || '' }} - docker.output=${{ steps.meta.outputs.docker_push == 'true' && format('type=registry') || 'type=cacheonly' }} + cluster-docs.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-docs-buildcache-${{ matrix.arch }} + cluster-docs.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-docs-buildcache-${{ matrix.arch }},mode=max + cluster-docs.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + cluster-docs.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} + cluster-example.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-example-buildcache-${{ matrix.arch }} + cluster-example.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-example-buildcache-${{ matrix.arch }},mode=max + cluster-example.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + cluster-example.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} + cluster-utils.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-utils-buildcache-${{ matrix.arch }} + cluster-utils.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-utils-buildcache-${{ matrix.arch }},mode=max + cluster-utils.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + cluster-utils.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} + standalone.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-standalone-buildcache-${{ matrix.arch }} + standalone.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-standalone-buildcache-${{ matrix.arch }},mode=max + standalone.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + standalone.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} develop.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-develop-buildcache-${{ matrix.arch }} develop.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-develop-buildcache-${{ matrix.arch }},mode=max develop.tags=${{ steps.meta.outputs.develop_push == 'true' && format('{0}/{1}:latest-dev-{2}', env.REGISTRY, env.IMAGE_NAME, matrix.arch) || '' }} develop.output=${{ steps.meta.outputs.develop_push == 'true' && 'type=registry' || 'type=cacheonly' }} env: REGISTRY: ${{ env.REGISTRY }} - TAG: ${{ steps.meta.outputs.docker_tag }} + TAG: ${{ steps.meta.outputs.images_tag }} PRODUCT_VERSION: ${{ env.PRODUCT_VERSION }} BUILD_ROOT: ${{ env.BUILD_ROOT }} NUGET_CACHE: local From a8110e39c7f94df18078586ee4559d06ad3355f2 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Fri, 15 May 2026 11:19:23 -0700 Subject: [PATCH 5/7] fix: bug in standalone build Signed-off-by: Hendrik Leidinger --- build/.docker/standalone.bake.Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/.docker/standalone.bake.Dockerfile b/build/.docker/standalone.bake.Dockerfile index 94e1341edd..b64cc9a886 100644 --- a/build/.docker/standalone.bake.Dockerfile +++ b/build/.docker/standalone.bake.Dockerfile @@ -48,8 +48,8 @@ RUN apt-get -y update && \ # --- Final setup --- -COPY build/standalone/configs/supervisor/ /etc/supervisor/conf.d/ -COPY --chmod=755 build/standalone/scripts/entrypoint.sh /entrypoint.sh +COPY build/configs/standalone/supervisor/ /etc/supervisor/conf.d/ +COPY --chmod=755 build/scripts/standalone/entrypoint.sh /entrypoint.sh #RUN mkdir -p ${EO_LOG}/docservice ${EO_LOG}/converter \ # ${EO_LOG}/adminpanel ${EO_LOG}/metrics From 0f79c6db57aabbcfbb692384875dd22fb54771a0 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Fri, 15 May 2026 12:21:45 -0700 Subject: [PATCH 6/7] fix: more bugs in github workflow Signed-off-by: Hendrik Leidinger --- .github/workflows/build.yml | 44 +++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 98f874d251..e096fbd7fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,9 @@ on: env: REGISTRY: ghcr.io/euro-office IMAGE_NAME: documentserver + CLUSTER_IMG_DOCS: cluster-docs + CLUSTER_IMG_EXAMPLE: cluster-example + CLUSTER_IMG_UTILS: cluster-utils CACHE_IMAGE_NAME: documentserver-build-cache PRODUCT_VERSION: 9.2.1 BUILD_ROOT: /package @@ -190,15 +193,15 @@ jobs: packages.tags= cluster-docs.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-docs-buildcache-${{ matrix.arch }} cluster-docs.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-docs-buildcache-${{ matrix.arch }},mode=max - cluster-docs.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + cluster-docs.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.CLUSTER_IMG_DOCS, steps.meta.outputs.images_tag) || '' }} cluster-docs.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} cluster-example.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-example-buildcache-${{ matrix.arch }} cluster-example.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-example-buildcache-${{ matrix.arch }},mode=max - cluster-example.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + cluster-example.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.CLUSTER_IMG_EXAMPLE, steps.meta.outputs.images_tag) || '' }} cluster-example.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} cluster-utils.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-utils-buildcache-${{ matrix.arch }} cluster-utils.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-cluster-utils-buildcache-${{ matrix.arch }},mode=max - cluster-utils.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.images_tag) || '' }} + cluster-utils.tags=${{ steps.meta.outputs.images_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.CLUSTER_IMG_UTILS, steps.meta.outputs.images_tag) || '' }} cluster-utils.output=${{ steps.meta.outputs.images_push == 'true' && format('type=registry') || 'type=cacheonly' }} standalone.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-standalone-buildcache-${{ matrix.arch }} standalone.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-standalone-buildcache-${{ matrix.arch }},mode=max @@ -256,22 +259,39 @@ jobs: - name: Create and push multi-arch manifests run: | REF="${{ steps.ref.outputs.name }}" - REPO="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + REGISTRY="${{ env.REGISTRY }}" create_manifest() { - local tag="$1" + local repo="$1" + local target_tag="$2" + local source_tag="${3:-$target_tag}" docker buildx imagetools create \ - -t "${REPO}:${tag}" \ - "${REPO}:${tag}-amd64" \ - "${REPO}:${tag}-arm64" + -t "${repo}:${target_tag}" \ + "${repo}:${source_tag}-amd64" \ + "${repo}:${source_tag}-arm64" } + # Repos that follow the standard tagging scheme + # (nightly on default branch, latest + ref on git tags). + # documentserver additionally gets :latest-dev on the default branch + # via the develop target; the cluster images do not. + REPOS=( + "${REGISTRY}/${{ env.IMAGE_NAME }}" + "${REGISTRY}/${{ env.CLUSTER_IMG_DOCS }}" + "${REGISTRY}/${{ env.CLUSTER_IMG_EXAMPLE }}" + "${REGISTRY}/${{ env.CLUSTER_IMG_UTILS }}" + ) + if [[ "${{ github.ref_name }}" == "${{ github.event.repository.default_branch }}" ]]; then - create_manifest "nightly" - create_manifest "latest-dev" + for repo in "${REPOS[@]}"; do + create_manifest "$repo" "nightly" + done + create_manifest "${REGISTRY}/${{ env.IMAGE_NAME }}" "latest-dev" fi if [[ "${{ github.ref }}" == refs/tags/* ]]; then - create_manifest "latest" - create_manifest "${REF}" + for repo in "${REPOS[@]}"; do + create_manifest "$repo" "latest" + create_manifest "$repo" "${REF}" "latest" + done fi From d29c8bf13aefc8bd76ceb9564024071d6fe4abc8 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Fri, 15 May 2026 13:36:21 -0700 Subject: [PATCH 7/7] fix: build also cluster images in workflow Signed-off-by: Hendrik Leidinger --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e096fbd7fd..ca915fe4a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -162,7 +162,7 @@ jobs: # Build the full graph; bake deduplicates shared layers automatically. # packages is included so its local filesystem export always runs, # enabling the release upload step below. - targets: develop,packages + targets: develop,packages,cluster-utils,cluster-example,cluster-docs # push=false here; per-target pushing is controlled via tags below. # Targets with empty tags= are not pushed regardless of this flag. push: false