diff --git a/.github/workflows/4testing-build.yml b/.github/workflows/4testing-build.yml index ab6a01c..dc88712 100644 --- a/.github/workflows/4testing-build.yml +++ b/.github/workflows/4testing-build.yml @@ -77,31 +77,36 @@ jobs: exit 1 fi echo "editions=$(jq -n -c --arg s "${EDITIONS[*]}" '($s|split(" "))')" >> $GITHUB_OUTPUT + echo "platforms=$(jq -c -n '$ARGS.positional' --args "${PLATFORMS[@]}")" >> $GITHUB_OUTPUT outputs: editions: ${{ steps.matrix.outputs.editions }} + platforms: ${{ steps.matrix.outputs.platforms }} build: - name: "Build ${{ matrix.image }}-${{ matrix.edition }}" - runs-on: ubuntu-latest + name: "Build ${{ matrix.image }}-${{ matrix.edition }}:${{ matrix.platform }}" + runs-on: ${{ matrix.runner }} needs: prepare strategy: fail-fast: false matrix: image: ["documentserver"] edition: ${{ fromJSON(needs.prepare.outputs.editions) }} + platform: ${{ fromJSON(needs.prepare.outputs.platforms) }} + include: + - platform: amd64 + runner: ubuntu-latest + - platform: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: actions/checkout@v4 - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} @@ -126,8 +131,7 @@ jobs: id: build-ds env: BRANCH_NAME: ${{ github.ref_name }} - AMD64: ${{ github.event.inputs.amd64 }} - ARM64: ${{ github.event.inputs.arm64 }} + PLATFORM: linux/${{ matrix.platform }} BUILD_NUMBER: ${{ github.event.inputs.build }} EDITION: ${{ matrix.edition }} IMAGE: ${{ matrix.image }} @@ -149,10 +153,6 @@ jobs: ;; esac - [ "${AMD64}" = true ] && PLATFORMS+=("amd64") - [ "${ARM64}" = true ] && PLATFORMS+=("arm64") - PLATFORM=$(echo ${PLATFORMS[*]/#/linux/} | tr ' ' ',') - if [ "$BRANCH_NAME" = develop ]; then BUILD_CHANNEL=nightly PRODUCT_VERSION=99.99.99 @@ -164,10 +164,9 @@ jobs: export PRODUCT_EDITION export PACKAGE_VERSION=${PRODUCT_VERSION}-${BUILD_NUMBER} export BUILD_CHANNEL - export PLATFORM export DOCKERFILE=Dockerfile export PREFIX_NAME=4testing- - export TAG=${PRODUCT_VERSION}.${BUILD_NUMBER} + export TAG=${PRODUCT_VERSION}.${BUILD_NUMBER}-${{ matrix.platform }} ### ==>> Build and push images at this step ### @@ -186,6 +185,7 @@ jobs: - name: Trigger zap manualy if: >- matrix.edition == 'community' && + matrix.platform == 'amd64' && (startsWith(steps.build-ds.outputs.branch, 'release/') || startsWith(steps.build-ds.outputs.branch, 'hotfix/')) env: @@ -200,3 +200,120 @@ jobs: -f version="${VERSION}" shell: bash + - name: Save build result to file + if: always() + run: | + mkdir -p build-result + + cat > build-result/info.json < /dev/null 2>&1; then + echo "Found image: $img" + FROM_TAGS+=( "$img" ) + return 0 + fi + + echo "Image not found yet, retrying in ${interval}s..." + sleep $interval + elapsed=$(( elapsed + interval )) + done + + echo "ERROR: Image not found after ${timeout}s: $img" + return 1 + } + + if [[ "${AMD64_STATUS}" == "success" ]]; then + check_image "${COMPANY_NAME}/4testing-${PRODUCT_NAME}${PRODUCT_EDITION}:${TAG}-amd64" + fi + + if [[ "${ARM64_STATUS}" == "success" ]]; then + check_image "${COMPANY_NAME}/4testing-${PRODUCT_NAME}${PRODUCT_EDITION}:${TAG}-arm64" + fi + + PUSH_TAGS=( + -t "${COMPANY_NAME}/4testing-${PRODUCT_NAME}${PRODUCT_EDITION}:${TAG}" + ) + + if [[ "${BUILD_CHANNEL}" == "nightly" ]]; then + PUSH_TAGS+=( -t "${COMPANY_NAME}/4testing-${PRODUCT_NAME}${PRODUCT_EDITION}:latest" ) + fi + + docker buildx imagetools create "${PUSH_TAGS[@]}" "${FROM_TAGS[@]}" diff --git a/Dockerfile b/Dockerfile index d7bdb34..6c59736 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG BASE_VERSION=24.04 ARG BASE_IMAGE=ubuntu:$BASE_VERSION FROM ${BASE_IMAGE} AS documentserver -LABEL maintainer Ascensio System SIA +LABEL maintainer="Ascensio System SIA " ARG BASE_VERSION ARG PG_VERSION=16 @@ -122,6 +122,7 @@ RUN PACKAGE_FILE="${COMPANY_NAME}-${PRODUCT_NAME}${PRODUCT_EDITION}${PACKAGE_VER apt-get -y update && \ service postgresql start && \ apt-get -yq install /tmp/$PACKAGE_FILE && \ + if [ "${PRODUCT_EDITION}" != "-ee" ] && [ "${PRODUCT_EDITION}" != "-de" ]; then rm -f /etc/supervisor/conf.d/ds-adminpanel.conf && sed -i 's/,adminpanel//' /etc/supervisor/conf.d/ds.conf; fi && \ PGPASSWORD=$ONLYOFFICE_VALUE dropdb -h localhost -p 5432 -U $ONLYOFFICE_VALUE $ONLYOFFICE_VALUE && \ sudo -u postgres psql -c "DROP ROLE onlyoffice;" && \ service postgresql stop && \ diff --git a/README.md b/README.md index e99b7a0..f268ce3 100644 --- a/README.md +++ b/README.md @@ -198,13 +198,14 @@ Below is the complete list of parameters that can be set using environment varia - **MSSQL** — schema to set as [DEFAULT_SCHEMA](https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-user-transact-sql?view=sql-server-ver17#default_schema---schema_name--null-), default `dbo`. - **AMQP_URI**: The [AMQP URI](https://www.rabbitmq.com/uri-spec.html "RabbitMQ URI Specification") to connect to message broker server. - **AMQP_TYPE**: The message broker type. Supported values are `rabbitmq` or `activemq`. Defaults to `rabbitmq`. +- **RABBIT_CONNECTIONS**: Sets the maximum number of simultaneous connections that can be opened to the RabbitMQ message broker. Defaults to the soft limit from `ulimit -n`. - **REDIS_SERVER_HOST**: The IP address or the name of the host where the Redis server is running. - **REDIS_SERVER_PORT**: The Redis server port number. - **REDIS_SERVER_USER**: The Redis server username. The username is not set by default. - **REDIS_SERVER_PASS**: The Redis server password. The password is not set by default. - **REDIS_SERVER_DB**: The Redis database index number to select. Defaults to `0`. - **NGINX_WORKER_PROCESSES**: Defines the number of nginx worker processes. -- **NGINX_WORKER_CONNECTIONS**: Sets the maximum number of simultaneous connections that can be opened by a nginx worker process. +- **NGINX_WORKER_CONNECTIONS**: Sets the maximum number of simultaneous connections that can be opened by a nginx worker process. Defaults to the soft limit from `ulimit -n`. - **NGINX_ACCESS_LOG**: Defines whether access logging is enabled. Defaults to `false`. - **SECURE_LINK_SECRET**: Defines secret for the nginx config directive [secure_link_md5](https://nginx.org/en/docs/http/ngx_http_secure_link_module.html#secure_link_md5). Defaults to `random string`. - **JWT_ENABLED**: Specifies the enabling the JSON Web Token validation by the ONLYOFFICE Document Server. Defaults to `true`. @@ -216,6 +217,8 @@ Below is the complete list of parameters that can be set using environment varia - **ALLOW_PRIVATE_IP_ADDRESS**: Defines if it is allowed to connect private IP address or not. Defaults to `false`. - **USE_UNAUTHORIZED_STORAGE**: Set to `true` if using self-signed certificates for your storage server e.g. Nextcloud. Defaults to `false` - **GENERATE_FONTS**: When 'true' regenerates fonts list and the fonts thumbnails etc. at each start. Defaults to `true` +- **ADMINPANEL_ENABLED**: Enables admin panel service autostart. Defaults to `false`. +- **EXAMPLE_ENABLED**: Enables example service autostart. Defaults to `false`. - **METRICS_ENABLED**: Specifies the enabling StatsD for ONLYOFFICE Document Server. Defaults to `false`. - **METRICS_HOST**: Defines StatsD listening host. Defaults to `localhost`. - **METRICS_PORT**: Defines StatsD listening port. Defaults to `8125`. diff --git a/config/supervisor/ds/ds-docservice.conf b/config/supervisor/ds/ds-docservice.conf index 7cb28f7..51c81ce 100644 --- a/config/supervisor/ds/ds-docservice.conf +++ b/config/supervisor/ds/ds-docservice.conf @@ -2,7 +2,7 @@ command=/var/www/COMPANY_NAME/documentserver/server/DocService/docservice directory=/var/www/COMPANY_NAME/documentserver/server/DocService user=ds -environment=NODE_ENV=production-linux,NODE_CONFIG_DIR=/etc/COMPANY_NAME/documentserver,NODE_DISABLE_COLORS=1,APPLICATION_NAME=COMPANY_NAME +environment=NODE_ENV=production-linux,NODE_CONFIG_DIR=/etc/COMPANY_NAME/documentserver,NODE_DISABLE_COLORS=1,PKG_NATIVE_CACHE_PATH=/tmp/.cache,APPLICATION_NAME=COMPANY_NAME stdout_logfile=/var/log/COMPANY_NAME/documentserver/docservice/out.log stdout_logfile_backups=0 stdout_logfile_maxbytes=0 diff --git a/docker-bake.hcl b/docker-bake.hcl index 7fe3843..30c8b70 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -90,8 +90,7 @@ target "documentserver" { target = "documentserver" dockerfile = "${DOCKERFILE}" tags = [ - "docker.io/${COMPANY_NAME}/${PREFIX_NAME}${PRODUCT_NAME}${PRODUCT_EDITION}:${TAG}", - equal("nightly",BUILD_CHANNEL) ? "docker.io/${COMPANY_NAME}/${PREFIX_NAME}${PRODUCT_NAME}${PRODUCT_EDITION}:latest": "", + "docker.io/${COMPANY_NAME}/${PREFIX_NAME}${PRODUCT_NAME}${PRODUCT_EDITION}:${TAG}" ] platforms = ["${PLATFORM}"] args = { diff --git a/run-document-server.sh b/run-document-server.sh index c373640..0169318 100644 --- a/run-document-server.sh +++ b/run-document-server.sh @@ -84,7 +84,7 @@ elif [[ -f ${SSL_CERTIFICATE_PATH} ]]; then fi if [[ -n $NODE_EXTRA_ENVIRONMENT ]]; then - sed -i "s|^environment=.*$|&,NODE_EXTRA_CA_CERTS=${NODE_EXTRA_ENVIRONMENT}|" /etc/supervisor/conf.d/*.conf + sed -i "s|^environment=.*$|&,NODE_EXTRA_CA_CERTS=${NODE_EXTRA_ENVIRONMENT}|" ${SUPERVISOR_CONF_DIR}/*.conf fi CA_CERTIFICATES_PATH=${CA_CERTIFICATES_PATH:-${SSL_CERTIFICATES_DIR}/ca-certificates.pem} @@ -105,13 +105,13 @@ NGINX_CONFIG_PATH="/etc/nginx/nginx.conf" NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-1} NGINX_ACCESS_LOG=${NGINX_ACCESS_LOG:-false} # Limiting the maximum number of simultaneous connections due to possible memory shortage -LIMIT=$(ulimit -n); [ $LIMIT -gt 1048576 ] && LIMIT=1048576 +LIMIT=$(ulimit -n); [ "$LIMIT" = "unlimited" ] || [ "$LIMIT" -gt 1048576 ] && LIMIT=1048576 NGINX_WORKER_CONNECTIONS=${NGINX_WORKER_CONNECTIONS:-$LIMIT} RABBIT_CONNECTIONS=${RABBIT_CONNECTIONS:-$LIMIT} JWT_ENABLED=${JWT_ENABLED:-true} -# validate user's vars before usinig in json +# validate user's vars before using in json if [ "${JWT_ENABLED}" == "true" ]; then JWT_ENABLED="true" else @@ -136,6 +136,8 @@ else REDIS_ENABLED=true fi +[[ "${PRODUCT_EDITION}" =~ ^-(ee|de)$ ]] && ADMINPANEL_AVAILABLE=true || ADMINPANEL_AVAILABLE=false + ONLYOFFICE_DEFAULT_CONFIG=${CONF_DIR}/local.json ONLYOFFICE_LOG4JS_CONFIG=${CONF_DIR}/log4js/production.json ONLYOFFICE_EXAMPLE_CONFIG=${CONF_DIR}-example/local.json @@ -585,16 +587,25 @@ create_oracle_tbl() { update_welcome_page() { WELCOME_PAGE="${APP_DIR}-example/welcome/docker.html" + EXAMPLE_DISABLED_PAGE="${APP_DIR}-example/welcome/example-disabled.html" + if ${ADMINPANEL_AVAILABLE}; then + ADMIN_DISABLED_PAGE="${APP_DIR}-example/welcome/admin-disabled.html" + sed -Ei 's#sudo systemctl start ds-(adminpanel|example)#sudo docker exec $(sudo docker ps -q) supervisorctl start ds:\1#g' "$ADMIN_DISABLED_PAGE" "$EXAMPLE_DISABLED_PAGE" + else + sed -Ei 's#sudo systemctl start ds-example#sudo docker exec $(sudo docker ps -q) supervisorctl start ds:example#g' "$EXAMPLE_DISABLED_PAGE" + fi + + TARGET_PAGES="$WELCOME_PAGE $EXAMPLE_DISABLED_PAGE${ADMIN_DISABLED_PAGE:+ $ADMIN_DISABLED_PAGE}" if [[ -e $WELCOME_PAGE ]]; then DOCKER_CONTAINER_ID=$(basename $(cat /proc/1/cpuset)) (( ${#DOCKER_CONTAINER_ID} < 12 )) && DOCKER_CONTAINER_ID=$(hostname) if (( ${#DOCKER_CONTAINER_ID} >= 12 )); then if [[ -x $(command -v docker) ]]; then DOCKER_CONTAINER_NAME=$(docker inspect --format="{{.Name}}" $DOCKER_CONTAINER_ID) - sed 's/$(sudo docker ps -q)/'"${DOCKER_CONTAINER_NAME#/}"'/' -i $WELCOME_PAGE + sed 's/$(sudo docker ps -q)/'"${DOCKER_CONTAINER_NAME#/}"'/' -i ${TARGET_PAGES} JWT_MESSAGE=$(echo $JWT_MESSAGE | sed 's/$(sudo docker ps -q)/'"${DOCKER_CONTAINER_NAME#/}"'/') else - sed 's/$(sudo docker ps -q)/'"${DOCKER_CONTAINER_ID::12}"'/' -i $WELCOME_PAGE + sed 's/$(sudo docker ps -q)/'"${DOCKER_CONTAINER_ID::12}"'/' -i ${TARGET_PAGES} JWT_MESSAGE=$(echo $JWT_MESSAGE | sed 's/$(sudo docker ps -q)/'"${DOCKER_CONTAINER_ID::12}"'/') fi fi @@ -672,10 +683,10 @@ update_release_date(){ } # create base folders -for i in converter docservice metrics adminpanel; do - mkdir -p "$DS_LOG_DIR/$i" && touch "$DS_LOG_DIR/$i"/{out,err}.log +for SUPERVISOR_CONF in "${SUPERVISOR_CONF_DIR}"/ds-*.conf; do + SERVICE_NAME=$(sed "s|^${SUPERVISOR_CONF_DIR}/ds-||; s|\.conf$||" <<<"$SUPERVISOR_CONF") + mkdir -p "$DS_LOG_DIR/$SERVICE_NAME" && touch "$DS_LOG_DIR/$SERVICE_NAME"/{out,err}.log done - mkdir -p "${DS_LOG_DIR}-example" && touch "${DS_LOG_DIR}-example"/{out,err}.log # create app folders @@ -736,7 +747,8 @@ if [ ${ONLYOFFICE_DATA_CONTAINER_HOST} = "localhost" ]; then chmod 400 ${RABBITMQ_DATA}/.erlang.cookie fi - echo "ulimit -n $RABBIT_CONNECTIONS" >> /etc/default/rabbitmq-server + sed -i '/^[[:space:]]*ulimit[[:space:]]\+-n[[:space:]]\+/d' /etc/default/rabbitmq-server + printf 'ulimit -n %s\n' "${RABBIT_CONNECTIONS}" >> /etc/default/rabbitmq-server LOCAL_SERVICES+=("rabbitmq-server") # allow Rabbitmq startup after container kill @@ -759,7 +771,7 @@ else waiting_for_datacontainer # read settings after the data container in ready state - # to prevent get unconfigureted data + # to prevent get unconfigured data read_setting update_welcome_page @@ -793,11 +805,11 @@ if [ ${ONLYOFFICE_DATA_CONTAINER} != "true" ]; then update_nginx_settings if [ "${PLUGINS_ENABLED}" = "true" ]; then - echo -n Installing plugins, please wait... - start_process documentserver-pluginsmanager.sh -r false --update=\"${APP_DIR}/sdkjs-plugins/plugin-list-default.json\" >/dev/null - echo Done + ( documentserver-pluginsmanager.sh -r false --update="${APP_DIR}/sdkjs-plugins/plugin-list-default.json" >/dev/null; echo "[pluginsmanager] Plugins initialization finished" >/proc/1/fd/1 ) & fi + ${ADMINPANEL_AVAILABLE} && [ "${ADMINPANEL_ENABLED:-false}" = "true" ] && sed -i 's,autostart=false,autostart=true,' ${SUPERVISOR_CONF_DIR}/ds-adminpanel.conf + [ "${EXAMPLE_ENABLED:-false}" = "true" ] && sed -i 's,autostart=false,autostart=true,' ${SUPERVISOR_CONF_DIR}/ds-example.conf service supervisor start # start cron to enable log rotating