From 5b96a674e0c60cc13c2adc54b835cdba88cb8882 Mon Sep 17 00:00:00 2001 From: Daniel Berteaud Date: Sat, 11 Nov 2023 00:13:30 +0100 Subject: [PATCH] More work on OnlyOffice --- ...nlyoffice-docserver.hcl => onlyoffice.hcl} | 0 ...nlyoffice-docserver.hcl => onlyoffice.hcl} | 6 + images/onlyoffice-docserver/Dockerfile | 33 ++++- .../root/entrypoint.d/10-conf.sh | 6 + .../root/entrypoint.d/10-mkdir.sh | 5 - .../root/entrypoint.d/20-sql.sh | 33 ++--- .../root/etc/nginx/nginx.conf | 69 +++++++---- .../custom-environment-variables.json | 48 ++++++++ .../local-production-linux.json | 9 ++ .../documentserver/production-linux.json | 74 ----------- .../root/etc/supervisord.d/ds-converter.ini | 2 - .../root/etc/supervisord.d/ds-docserver.ini | 2 - .../root/etc/supervisord.d/ds-metrics.ini | 2 - .../root/etc/supervisord.d/ds-nginx.ini | 3 +- onlyoffice-docserver.nomad.hcl | 115 +++++++++--------- prep.d/10-mv_conf.sh | 2 +- prep.d/20-rand-keys.sh | 6 +- templates/local.json.tpl | 48 ++++++++ templates/nginx.conf.tpl | 9 +- templates/production-linux.json.tpl | 107 ---------------- variables.yml | 49 +++++--- ...nlyoffice-docserver.hcl => onlyoffice.hcl} | 0 22 files changed, 293 insertions(+), 335 deletions(-) rename consul/config/service-defaults/{onlyoffice-docserver.hcl => onlyoffice.hcl} (100%) rename consul/config/service-intentions/{onlyoffice-docserver.hcl => onlyoffice.hcl} (61%) create mode 100755 images/onlyoffice-docserver/root/entrypoint.d/10-conf.sh delete mode 100755 images/onlyoffice-docserver/root/entrypoint.d/10-mkdir.sh create mode 100644 images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/custom-environment-variables.json create mode 100644 images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/local-production-linux.json delete mode 100644 images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/production-linux.json create mode 100644 templates/local.json.tpl delete mode 100644 templates/production-linux.json.tpl rename vault/policies/{onlyoffice-docserver.hcl => onlyoffice.hcl} (100%) diff --git a/consul/config/service-defaults/onlyoffice-docserver.hcl b/consul/config/service-defaults/onlyoffice.hcl similarity index 100% rename from consul/config/service-defaults/onlyoffice-docserver.hcl rename to consul/config/service-defaults/onlyoffice.hcl diff --git a/consul/config/service-intentions/onlyoffice-docserver.hcl b/consul/config/service-intentions/onlyoffice.hcl similarity index 61% rename from consul/config/service-intentions/onlyoffice-docserver.hcl rename to consul/config/service-intentions/onlyoffice.hcl index c43f5b1..a7bb8e7 100644 --- a/consul/config/service-intentions/onlyoffice-docserver.hcl +++ b/consul/config/service-intentions/onlyoffice.hcl @@ -4,6 +4,12 @@ Sources = [ { Name = "[[ .traefik.instance ]]" Permissions = [ + { + Action = "deny" + HTTP { + PathRegex = "^(\\/[\\d]+\\.[\\d]+\\.[\\d]+[\\.|-][\\d]+)?\\/(internal|info)(\\/.*)$" + } + }, { Action = "allow" HTTP { diff --git a/images/onlyoffice-docserver/Dockerfile b/images/onlyoffice-docserver/Dockerfile index 08d1822..da2a0b9 100644 --- a/images/onlyoffice-docserver/Dockerfile +++ b/images/onlyoffice-docserver/Dockerfile @@ -1,8 +1,27 @@ FROM [[ .docker.repo ]][[ .docker.base_images.alma9.image ]] MAINTAINER [[ .docker.maintainer ]] +ARG OO_VERSION=7.5.1 + ENV LANG=[[ .locale.lang ]] \ - TZ=[[ .locale.tz ]] + TZ=[[ .locale.tz ]] \ + NGINX_LISTEN_IP=0.0.0.0 \ + NODE_ENV=production-linux \ + NODE_CONFIG_DIR=/etc/onlyoffice/documentserver \ + NODE_DISABLE_COLORS=1 \ + APPLICATION_NAME=onlyoffice \ + OO_STORAGE_SECRET=changeme \ + OO_JWT_TOKEN=changeme \ + OO_USE_TOKEN=true \ + OO_AUTOSAVE=true \ + OO_AUTOSAVE_INTERVAL=5m \ + OO_VERIFY_CERT=true \ + OO_LOG4JS_CONFIG=/etc/onlyoffice/documentserver/log4js/production.json \ + OO_DB_HOST=localhost \ + OO_DB_PORT=5432 \ + OO_DB_NAME=onlyoffice \ + OO_DB_USER=onlyoffice \ + OO_DB_PASS=onlyoffice USER root COPY root/etc/yum.repos.d/ /etc/yum.repos.d/ @@ -10,19 +29,21 @@ RUN set -euxo pipefail &&\ dnf -y update &&\ rpm -i https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm &&\ dnf -y module disable postgresql &&\ + addgroup -g 819 ds &&\ + adduser --system --ingroup ds --disabled-password --uid 819 --home /var/www/onlyoffice/documentserver/ --shell /sbin/nologin ds &&\ dnf -y install \ + dnf \ postgresql16 \ onlyoffice-documentserver \ supervisor \ nginx \ - jq \ &&\ - chown :ds /etc/onlyoffice/documentserver/* &&\ - mkdir -p /data &&\ - chown ds:ds /data + dnf clean all &&\ + rm -rf /var/cache/dnf/* /var/cache/yum/* /var/log/dnf* /var/log/yum/* /var/lib/dnf/history* + COPY root/ / -EXPOSE 8084 +EXPOSE 8819 USER ds diff --git a/images/onlyoffice-docserver/root/entrypoint.d/10-conf.sh b/images/onlyoffice-docserver/root/entrypoint.d/10-conf.sh new file mode 100755 index 0000000..7fa60a7 --- /dev/null +++ b/images/onlyoffice-docserver/root/entrypoint.d/10-conf.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -euo pipefail + +echo "Replacing env variable in nginx config" +busybox awk -f /usr/local/bin/envsubst < /etc/nginx/nginx.conf > /tmp/nginx.conf diff --git a/images/onlyoffice-docserver/root/entrypoint.d/10-mkdir.sh b/images/onlyoffice-docserver/root/entrypoint.d/10-mkdir.sh deleted file mode 100755 index ba0bff1..0000000 --- a/images/onlyoffice-docserver/root/entrypoint.d/10-mkdir.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -set -euo pipefail - -mkdir -p /data/files /data/wopi /data/templates diff --git a/images/onlyoffice-docserver/root/entrypoint.d/20-sql.sh b/images/onlyoffice-docserver/root/entrypoint.d/20-sql.sh index 9b0bb52..39dd927 100755 --- a/images/onlyoffice-docserver/root/entrypoint.d/20-sql.sh +++ b/images/onlyoffice-docserver/root/entrypoint.d/20-sql.sh @@ -2,20 +2,11 @@ set -euo pipefail -function get_value(){ - local KEY=$1 - local VALUE=$(jq -r -s \ - " .[0].services.CoAuthoring.sql * .[1].services.CoAuthoring.sql | .${KEY}" \ - /etc/onlyoffice/documentserver/default.json \ - /etc/onlyoffice/documentserver/production-linux.json) - echo ${VALUE} -} - -export PGHOST=$(get_value "dbHost") -export DGPORT=$(get_value "dbport") -export PGDATABASE=$(get_value "dbName") -export PGUSER=$(get_value "dbUser") -export PGPASSWORD=$(get_value "dbPass") +export PGHOST=${OO_DB_HOST} +export DGPORT=${OO_DB_PORT} +export PGDATABASE=${OO_DB_NAME} +export PGUSER=${OO_DB_USER} +export PGPASSWORD=${OO_DB_PASS} function init_db(){ psql -f /var/www/onlyoffice/documentserver/server/schema/postgresql/createdb.sql @@ -26,21 +17,15 @@ function reset_db(){ } function write_version(){ - echo $(rpm -q onlyoffice-documentserver --qf "%{VERSION}-%{RELEASE}") > /data/onlyoffice.version + echo $(rpm -q onlyoffice-documentserver --qf "%{VERSION}-%{RELEASE}") > /var/lib/onlyoffice/documentserver/App_Data/onlyoffice.version } -export PGHOST=$(get_value "dbHost") -export DGPORT=$(get_value "dbport") -export PGDATABASE=$(get_value "dbName") -export PGUSER=$(get_value "dbUser") -export PGPASSWORD=$(get_value "dbPass") - -if [ ! -e "/data/onlyoffice.version" ]; then - echo "File /data/onlyoffice.version doesn't exist, initializing database" +if [ ! -e "/var/lib/onlyoffice/documentserver/App_Data/onlyoffice.version" ]; then + echo "File /var/lib/onlyoffice/documentserver/App_Data/onlyoffice.version doesn't exist, initializing database" init_db write_version else - PREVIOUS_VERSION=$(head -n 1 /data/onlyoffice.version) + PREVIOUS_VERSION=$(head -n 1 /var/lib/onlyoffice/documentserver/App_Data/onlyoffice.version) CURRENT_VERSION=$(rpm -q onlyoffice-documentserver --qf "%{VERSION}-%{RELEASE}") if [ "${CURRENT_VERSION}" != "${PREVIOUS_VERSION}" ]; then echo "Running ${CURRENT_VERSION} while previous version was ${PREVIOUS_VERSION}. Reinitializing database" diff --git a/images/onlyoffice-docserver/root/etc/nginx/nginx.conf b/images/onlyoffice-docserver/root/etc/nginx/nginx.conf index b042753..a4514c0 100644 --- a/images/onlyoffice-docserver/root/etc/nginx/nginx.conf +++ b/images/onlyoffice-docserver/root/etc/nginx/nginx.conf @@ -1,6 +1,7 @@ worker_processes auto; error_log /dev/stderr warn; pid /tmp/nginx.pid; +daemon off; events { worker_connections 1024; } @@ -19,30 +20,52 @@ http { sendfile on; keepalive_timeout 65; - include /etc/onlyoffice/documentserver/nginx/includes/http-common.conf; - + upstream docservice { + server unix:/tmp/oods.sock max_fails=0 fail_timeout=0s; + } + + map $http_host $this_host { + "" $host; + default $http_host; + } + + map $http_x_forwarded_proto $the_scheme { + default $http_x_forwarded_proto; + "" $scheme; + } + + map $http_x_forwarded_host $the_host { + default $http_x_forwarded_host; + "" $this_host; + } + + map $http_upgrade $proxy_connection { + default upgrade; + "" close; + } + + map $http_x_forwarded_prefix $the_prefix { + default $http_x_forwarded_prefix; + } + + 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; + + client_max_body_size 100m; + + set_real_ip_from 127.0.0.1; + real_ip_header X-Forwarded-For; + real_ip_recursive on; + server { - listen 0.0.0.0:8084; - server_name _; + listen ${NGINX_LISTEN_IP}:8819 default_server; + server_tokens off; - client_max_body_size 100m; - - set_real_ip_from 127.0.0.1; - real_ip_header X-Forwarded-For; - real_ip_recursive on; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - - # Override the fonts endpoint to add a Content-Type so reverse proxies can handle caching corectly - location ~ ^(\/[\d]+\.[\d]+\.[\d]+[\.|-][\d]+)?\/fonts(\/.*)$ { - add_header Content-Type font/opentype; - expires 365d; - alias /var/www/onlyoffice/documentserver/fonts$2; - } - set $secure_link_secret verysecretstring; - include /etc/onlyoffice/documentserver/nginx/includes/ds-docservice.conf; + set $secure_link_secret ${OO_STORAGE_SECRET}; + include /etc/nginx/includes/ds-docservice.conf; + include /etc/nginx/includes/ds-mime.types.conf; } } diff --git a/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/custom-environment-variables.json b/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/custom-environment-variables.json new file mode 100644 index 0000000..d7fe125 --- /dev/null +++ b/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/custom-environment-variables.json @@ -0,0 +1,48 @@ +{ + "log": { + "filePath": "OO_LOG4JS_CONFIG" + }, + "storage": { + "fs": { + "secretString": "OO_STORAGE_SECRET" + } + }, + "services": { + "CoAuthoring": { + "secret": { + "inbox": { + "string": "OO_JWT_TOKEN" + }, + "outbox": { + "string": "OO_JWT_TOKEN" + }, + "session": { + "string": "OO_JWT_TOKEN" + } + }, + "token": { + "browser": "OO_USE_TOKEN", + "request": { + "inbox": "OO_USE_TOKEN", + "outbox": "OO_USE_TOKEN" + } + }, + "requestDefaults": { + "rejectUnauthorized": "OO_VERIFY_CERT" + }, + "sql": { + "type": "OO_DB_TYPE", + "dbHost": "OO_DB_HOST", + "dbPort": "OO_DB_PORT", + "dbName": "OO_DB_NAME", + "dbUser": "OO_DB_USER", + "dbPass": "OO_DB_PASS" + }, + "autoAssembly": { + "enable": "OO_AUTOSAVE", + "interval": "OO_AUTOSAVE_INTERVAL" + } + } + } +} + diff --git a/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/local-production-linux.json b/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/local-production-linux.json new file mode 100644 index 0000000..46aa403 --- /dev/null +++ b/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/local-production-linux.json @@ -0,0 +1,9 @@ +{ + "services": { + "CoAuthoring": { + "server": { + "port": "/tmp/oods.sock" + } + } + } +} diff --git a/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/production-linux.json b/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/production-linux.json deleted file mode 100644 index c6ee6b0..0000000 --- a/images/onlyoffice-docserver/root/etc/onlyoffice/documentserver/production-linux.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "log": { - "filePath": "/etc/onlyoffice/documentserver/log4js/production.json" - }, - "storage": { - "fs": { - "folderPath": "/data/files" - } - }, - "wopi": { - "htmlTemplate" : "/data/wopi" - }, - "services": { - "CoAuthoring": { - "server": { - "newFileTemplate" : "/data/templates", - "static_content": { - "/fonts": { - "path": "/var/www/onlyoffice/documentserver/fonts", - "options": {"maxAge": "7d"} - }, - "/sdkjs": { - "path": "/var/www/onlyoffice/documentserver/sdkjs", - "options": {"maxAge": "7d"} - }, - "/web-apps": { - "path": "/var/www/onlyoffice/documentserver/web-apps", - "options": {"maxAge": "7d"} - }, - "/welcome": { - "path": "/var/www/onlyoffice/documentserver/server/welcome", - "options": {"maxAge": "7d"} - }, - "/info": { - "path": "/var/www/onlyoffice/documentserver/server/info", - "options": {"maxAge": "7d"} - }, - "/sdkjs-plugins": { - "path": "/var/www/onlyoffice/documentserver/sdkjs-plugins", - "options": {"maxAge": "7d"} - }, - "/dictionaries": { - "path": "/var/www/onlyoffice/documentserver/dictionaries", - "options": {"maxAge": "7d"} - } - } - }, - "utils": { - "utils_common_fontdir": "/usr/share/fonts" - }, - "sockjs": { - "sockjs_url": "/web-apps/vendor/sockjs/sockjs.min.js" - } - } - }, - "license": { - "license_file": "/var/www/onlyoffice/documentserver/../Data/license.lic", - "warning_limit_percents": 70, - "packageType": 0 - }, - "FileConverter": { - "converter": { - "fontDir": "/usr/share/fonts", - "presentationThemesDir": "/var/www/onlyoffice/documentserver/sdkjs/slide/themes", - "x2tPath": "/var/www/onlyoffice/documentserver/server/FileConverter/bin/x2t", - "docbuilderPath": "/var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder" - } - }, - "SpellChecker": { - "server": { - "dictDir": "/var/www/onlyoffice/documentserver/dictionaries" - } - } -} diff --git a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-converter.ini b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-converter.ini index ffae110..d4f611d 100644 --- a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-converter.ini +++ b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-converter.ini @@ -1,8 +1,6 @@ [program:converter] command=/var/www/onlyoffice/documentserver/server/FileConverter/converter directory=/var/www/onlyoffice/documentserver/server/FileConverter -;user=ds -environment=NODE_ENV=production-linux,NODE_CONFIG_DIR=/etc/onlyoffice/documentserver,NODE_DISABLE_COLORS=1,APPLICATION_NAME=onlyoffice stdout_logfile=/proc/self/fd/1 stdout_logfile_backups=0 stdout_logfile_maxbytes=0 diff --git a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-docserver.ini b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-docserver.ini index 03447f2..5512c81 100644 --- a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-docserver.ini +++ b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-docserver.ini @@ -1,8 +1,6 @@ [program:docservice] command=/var/www/onlyoffice/documentserver/server/DocService/docservice directory=/var/www/onlyoffice/documentserver/server/DocService -;user=ds -environment=NODE_ENV=production-linux,NODE_CONFIG_DIR=/etc/onlyoffice/documentserver,NODE_DISABLE_COLORS=1 stdout_logfile=/proc/self/fd/1 stdout_logfile_backups=0 stdout_logfile_maxbytes=0 diff --git a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-metrics.ini b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-metrics.ini index 746a11e..1605fa5 100644 --- a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-metrics.ini +++ b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-metrics.ini @@ -1,8 +1,6 @@ [program:metrics] command=/var/www/onlyoffice/documentserver/server/Metrics/metrics ./config/config.js directory=/var/www/onlyoffice/documentserver/server/Metrics -;user=ds -environment=NODE_DISABLE_COLORS=1 stdout_logfile=/proc/self/fd/1 stdout_logfile_backups=0 stdout_logfile_maxbytes=0 diff --git a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-nginx.ini b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-nginx.ini index 9ad24cd..dbcc80b 100644 --- a/images/onlyoffice-docserver/root/etc/supervisord.d/ds-nginx.ini +++ b/images/onlyoffice-docserver/root/etc/supervisord.d/ds-nginx.ini @@ -1,7 +1,6 @@ [program:nginx] -command=/usr/sbin/nginx -g "daemon off;" +command=/usr/sbin/nginx -c /tmp/nginx.conf directory=/ -;user=nginx stdout_logfile=/proc/self/fd/1 stdout_logfile_backups=0 stdout_logfile_maxbytes=0 diff --git a/onlyoffice-docserver.nomad.hcl b/onlyoffice-docserver.nomad.hcl index 6ad84d2..ebb2543 100644 --- a/onlyoffice-docserver.nomad.hcl +++ b/onlyoffice-docserver.nomad.hcl @@ -12,26 +12,33 @@ job [[ .oo.instance | toJSON ]] { hostname = "[[ .oo.instance ]][[ $c.consul.suffix ]]" } - volume "ds" { - type = [[ .oo.volumes.ds.type | toJSON ]] - source = [[ .oo.volumes.ds.source | toJSON ]] - access_mode = "single-node-writer" + volume "data" { + type = [[ .oo.volumes.data.type | toJSON ]] + source = [[ .oo.volumes.data.source | toJSON ]] + access_mode = "single-node-writer" + attachment_mode = "file-system" + } + + volume "rabbitmq" { + type = [[ .oo.volumes.rabbitmq.type | toJSON ]] + source = [[ .oo.volumes.rabbitmq.source | toJSON ]] + access_mode = "single-node-writer" attachment_mode = "file-system" } service { name = "[[ .oo.instance ]][[ $c.consul.suffix ]]" - port = 8084 + port = 8819 [[ template "common/connect.tpl" $c ]] check { - name = "health" - type = "http" - path = "/healthcheck" - expose = true + name = "health" + type = "http" + path = "/healthcheck" + expose = true interval = "10s" - timeout = "5s" + timeout = "8s" check_restart { limit = 90 @@ -45,40 +52,43 @@ job [[ .oo.instance | toJSON ]] { "[[ $c.traefik.instance ]].http.routers.[[ .oo.instance ]][[ $c.consul.suffix ]].rule=Host(`[[ (urlParse .oo.ds.public_url).Hostname ]]`) [[- if not (regexp.Match "^/?$" (urlParse .oo.ds.public_url).Path) ]] && PathPrefix(`[[ (urlParse .oo.ds.public_url).Path ]]`)[[ end ]]", "[[ $c.traefik.instance ]].http.routers.[[ .oo.instance ]][[ $c.consul.suffix ]].entrypoints=[[ join $c.traefik.entrypoints "," ]]", + "[[ $c.traefik.instance ]].http.middlewares.[[ .oo.instance ]]-headers[[ $c.consul.suffix ]].headers.contentsecuritypolicy=[[ range $k, $v := $c.traefik.csp ]][[ $k ]] [[ $v ]];[[ end ]]", + "[[ $c.traefik.instance ]].http.middlewares.[[ .oo.instance ]]-headers[[ $c.consul.suffix ]].headers.customrequestheaders.X-Forwarded-Proto=https", [[- if not (regexp.Match "^/?$" (urlParse .oo.ds.public_url).Path) ]] "[[ $c.traefik.instance ]].http.middlewares.[[ .oo.instance ]][[ $c.consul.suffix ]]-prefix.stripprefix.prefixes=[[ (urlParse .oo.ds.public_url).Path ]]", - "[[ $c.traefik.instance ]].http.routers.[[ .oo.instance ]][[ $c.consul.suffix ]].middlewares=[[ .oo.instance ]][[ $c.consul.suffix ]]-prefix,[[ template "common/traefik_middlewares.tpl" $c.traefik ]]", + "[[ $c.traefik.instance ]].http.routers.[[ .oo.instance ]][[ $c.consul.suffix ]].middlewares=[[ .oo.instance ]]-headers[[ $c.consul.suffix ]],[[ .oo.instance ]][[ $c.consul.suffix ]]-prefix,[[ template "common/traefik_middlewares.tpl" $c.traefik ]]", [[- else ]] - "[[ $c.traefik.instance ]].http.routers.[[ .oo.instance ]][[ $c.consul.suffix ]].middlewares=[[ template "common/traefik_middlewares.tpl" $c.traefik ]]", + "[[ $c.traefik.instance ]].http.routers.[[ .oo.instance ]][[ $c.consul.suffix ]].middlewares=[[ .oo.instance ]]-headers[[ $c.consul.suffix ]],[[ template "common/traefik_middlewares.tpl" $c.traefik ]]", [[- end ]] [[- end ]] ] } - task "documentserver" { + task "docserver" { driver = [[ $c.nomad.driver | toJSON ]] leader = true config { - image = [[ .oo.ds.image | toJSON ]] - pids_limit = 100 + image = [[ .oo.ds.image | toJSON ]] + pids_limit = 200 readonly_rootfs = true - volumes = [ - "secrets/production-linux.json:/etc/onlyoffice/documentserver/production-linux.json:ro", - "local/metrics.js:/var/www/onlyoffice/documentserver/server/Metrics/config/config.js:ro", - "secrets/nginx.conf:/etc/nginx/nginx.conf:ro" + volumes = [ + "local/metrics.js:/var/www/onlyoffice/documentserver/server/Metrics/config/config.js:ro" ] -[[ template "common/tmpfs.tpl" "/tmp" ]] +[[ template "common/tmpfs.tpl" dict "target" "/tmp" "size" 3000000 ]] + } vault { - policies = ["[[ .oo.instance ]][[ $c.consul.suffix ]]"] + policies = ["[[ .oo.instance ]][[ $c.consul.suffix ]]"] disable_file = true - env = false + env = false } env { + NGINX_LISTEN_IP = "127.0.0.1" + APPLICATION_NAME = "[[ .oo.instance ]][[ .consul.suffix ]]" [[ template "common/proxy_env.tpl" $c ]] } @@ -86,34 +96,14 @@ job [[ .oo.instance | toJSON ]] { template { data =<<_EOT -[[ template "onlyoffice-documentserver/production-linux.json.tpl" . ]] -_EOT - destination = "secrets/production-linux.json" - uid = 100000 - gid = 100990 - perms = 640 - } - - template { - data =<<_EOT -[[ template "onlyoffice-documentserver/metrics.js.tpl" . ]] +[[ template "onlyoffice-docserver/metrics.js.tpl" . ]] _EOT destination = "local/metrics.js" } - template { - data =<<_EOT -[[ template "onlyoffice-documentserver/nginx.conf.tpl" . ]] -_EOT - destination = "secrets/nginx.conf" - uid = 100000 - gid = 100990 - perms = 640 - } - volume_mount { - volume = "ds" - destination = "/data" + volume = "data" + destination = "/var/lib/onlyoffice/documentserver/App_Data/" } [[ template "common/resources.tpl" $c.resources ]] @@ -124,18 +114,18 @@ _EOT task "redis" { driver = [[ $c.nomad.driver | toJSON ]] - user = 2967 + user = 2967 lifecycle { - hook = "prestart" + hook = "prestart" sidecar = true } config { - image = "redis:alpine" - pids_limit = 20 + image = "redis:alpine" + pids_limit = 20 readonly_rootfs = true - args = ["/local/redis.conf"] + args = ["/local/redis.conf"] } template { @@ -150,7 +140,7 @@ _EOT } resources { - cpu = 10 + cpu = 10 memory = 20 } } @@ -159,33 +149,38 @@ _EOT task "rabbitmq" { driver = [[ $c.nomad.driver | toJSON ]] - user = 100 + #user = 100 lifecycle { - hook = "prestart" + hook = "prestart" sidecar = true } config { - image = [[ $c.image | toJSON ]] - pids_limit = 100 + image = [[ $c.image | toJSON ]] + pids_limit = 100 readonly_rootfs = true - volumes = [ + volumes = [ "local/rabbitmq.conf:/etc/rabbitmq/conf.d/30-oods.conf" ] -[[ template "common/tmpfs.tpl" dict "target" "/var/lib/rabbitmq" "size" 20000000]] } +[[ template "common/file_env.tpl" $c.env ]] + template { data = <<_EOT listeners.tcp.1 = 127.0.0.1:5672 -# Set watermark to 70% of the mem allocated to the container -vm_memory_high_watermark.absolute = [[ mul .oo.rabbitmq.resources.memory 734003 ]] +# Set watermark to 95% of the mem allocated to the container +#vm_memory_high_watermark.absolute = [[ mul .oo.rabbitmq.resources.memory 996147 ]] +vm_memory_high_watermark.relative = 0.999 _EOT destination = "local/rabbitmq.conf" } -[[ template "common/file_env.tpl" $c.env ]] + volume_mount { + volume = "rabbitmq" + destination = "/var/lib/rabbitmq" + } [[ template "common/resources.tpl" $c.resources ]] } diff --git a/prep.d/10-mv_conf.sh b/prep.d/10-mv_conf.sh index b01df2b..4a39091 100755 --- a/prep.d/10-mv_conf.sh +++ b/prep.d/10-mv_conf.sh @@ -1 +1 @@ -[[ template "common/mv_conf.sh.tpl" dict "ctx" . "services" (dict "onlyoffice-docserver" .oo.instance) ]] +[[ template "common/mv_conf.sh.tpl" dict "ctx" . "services" (dict "onlyoffice" .oo.instance) ]] diff --git a/prep.d/20-rand-keys.sh b/prep.d/20-rand-keys.sh index 8150819..f01ddcc 100755 --- a/prep.d/20-rand-keys.sh +++ b/prep.d/20-rand-keys.sh @@ -6,11 +6,11 @@ set -euo pipefail if ! vault kv list [[ .vault.prefix ]]kv/service 2>/dev/null | grep -q -E '^[[ .oo.instance ]]$'; then vault kv put [[ .vault.prefix ]]kv/service/[[ .oo.instance ]] \ - secret_key=$(pwgen -s -n 50 1) \ - link_secret=$(pwgen -s -n 50 1) + jwt_token=$(pwgen -s -n 50 1) \ + storage_secret=$(pwgen -s -n 50 1) fi -for PWD in secret_key link_secret; do +for PWD in jwt_token storage_secret; do if ! vault kv get -field ${PWD} [[ .vault.prefix ]]kv/service/[[ .oo.instance ]] >/dev/null 2>&1; then vault kv patch [[ .vault.prefix ]]kv/service/[[ .oo.instance ]] \ ${PWD}=$(pwgen -s -n 50 1) diff --git a/templates/local.json.tpl b/templates/local.json.tpl new file mode 100644 index 0000000..efd6a26 --- /dev/null +++ b/templates/local.json.tpl @@ -0,0 +1,48 @@ +{ + "log": { + "filePath": "/etc/onlyoffice/documentserver/log4js/development.json" + }, + "storage": { + "fs": { + "secretString": "[[ .oo.ds.link_secret ]]" + } + }, + "services": { + "CoAuthoring": { +[[- if and (has .oo.ds "secret_key") (ne .oo.ds.secret_key "") ]] + "secret": { + "inbox": { + "string": "[[ .oo.ds.secret_key ]]" + }, + "outbox": { + "string": "[[ .oo.ds.secret_key ]]" + } + }, + "token": { + "enable": { + "browser": true, + "request": { + "inbox": true, + "outbox": true + } + } + }, +[[- end ]] + "sql": { + "type": "[[ .oo.ds.database.type ]]", + "dbHost": "[[ .oo.ds.database.host ]]", + "dbPort": [[ .oo.ds.database.port ]], + "dbName": "[[ .oo.ds.database.name ]]", + "dbUser": "[[ .oo.ds.database.user ]]", + "dbPass": "[[ .oo.ds.database.password ]]" + }, + "autoAssembly": { + "enable": true, + "interval": "5m" + }, + "server": { + "port": "/tmp/oods.sock" + } + } + } +} diff --git a/templates/nginx.conf.tpl b/templates/nginx.conf.tpl index d70d205..bbb6b5f 100644 --- a/templates/nginx.conf.tpl +++ b/templates/nginx.conf.tpl @@ -1,6 +1,7 @@ worker_processes auto; error_log /dev/stderr info; pid /tmp/nginx.pid; +daemon off; events { worker_connections 1024; } @@ -20,7 +21,7 @@ http { keepalive_timeout 65; upstream docservice { - server unix:/tmp/oods.sock; + server unix:/tmp/oods.sock max_fails=0 fail_timeout=0s; } map $http_host $this_host { @@ -53,7 +54,7 @@ http { proxy_set_header X-Forwarded-Proto $the_scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_socket_keepalive on; + #proxy_socket_keepalive on; client_max_body_size 100m; @@ -64,8 +65,8 @@ http { server { listen 127.0.0.1:8084 default_server; server_tokens off; - - set $secure_link_secret [[ .oo.ds.link_secret ]]; + + set $secure_link_secret [[ .oo.ds.env.OO_STORAGE_SECRET ]]; include /etc/nginx/includes/ds-docservice.conf; include /etc/nginx/includes/ds-mime.types.conf; } diff --git a/templates/production-linux.json.tpl b/templates/production-linux.json.tpl deleted file mode 100644 index 3290e3c..0000000 --- a/templates/production-linux.json.tpl +++ /dev/null @@ -1,107 +0,0 @@ -{ - "log": { - "filePath": "/etc/onlyoffice/documentserver/log4js/development.json" - }, - "storage": { - "fs": { - "folderPath": "/data/files", - "secretString": "[[ .oo.ds.link_secret ]]" - } - }, - "wopi": { - "htmlTemplate" : "/data/wopi" - }, - "services": { - "CoAuthoring": { -[[- if and (has .oo.ds "secret_key") (ne .oo.ds.secret_key "") ]] - "secret": { - "inbox": { - "string": "[[ .oo.ds.secret_key ]]" - }, - "outbox": { - "string": "[[ .oo.ds.secret_key ]]" - } - }, - "token": { - "enable": { - "browser": true, - "request": { - "inbox": true, - "outbox": true - } - } - }, -[[- end ]] - "sql": { - "type": "[[ .oo.ds.database.type ]]", - "dbHost": "[[ .oo.ds.database.host ]]", - "dbPort": [[ .oo.ds.database.port ]], - "dbName": "[[ .oo.ds.database.name ]]", - "dbUser": "[[ .oo.ds.database.user ]]", - "dbPass": "[[ .oo.ds.database.password ]]" - }, - "autoAssembly": { - "enable": true, - "interval": "5m" - }, - "server": { - "port": "/tmp/oods.sock", - "newFileTemplate" : "/data/templates", - "static_content": { - "/fonts": { - "path": "/var/www/onlyoffice/documentserver/fonts", - "options": {"maxAge": "7d"} - }, - "/sdkjs": { - "path": "/var/www/onlyoffice/documentserver/sdkjs", - "options": {"maxAge": "7d"} - }, - "/web-apps": { - "path": "/var/www/onlyoffice/documentserver/web-apps", - "options": {"maxAge": "7d"} - }, - "/welcome": { - "path": "/var/www/onlyoffice/documentserver/server/welcome", - "options": {"maxAge": "7d"} - }, - "/info": { - "path": "/var/www/onlyoffice/documentserver/server/info", - "options": {"maxAge": "7d"} - }, - "/sdkjs-plugins": { - "path": "/var/www/onlyoffice/documentserver/sdkjs-plugins", - "options": {"maxAge": "7d"} - }, - "/dictionaries": { - "path": "/var/www/onlyoffice/documentserver/dictionaries", - "options": {"maxAge": "7d"} - } - } - }, - "utils": { - "utils_common_fontdir": "/usr/share/fonts" - }, - "sockjs": { - "sockjs_url": "/web-apps/vendor/sockjs/sockjs.min.js" - } - } - }, - "license": { - "license_file": "/var/www/onlyoffice/documentserver/../Data/license.lic", - "warning_limit_percents": 70, - "packageType": 0 - }, - "FileConverter": { - "converter": { - "fontDir": "/usr/share/fonts", - "presentationThemesDir": "/var/www/onlyoffice/documentserver/sdkjs/slide/themes", - "x2tPath": "/var/www/onlyoffice/documentserver/server/FileConverter/bin/x2t", - "docbuilderPath": "/var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder" - } - }, - "SpellChecker": { - "server": { - "dictDir": "/var/www/onlyoffice/documentserver/dictionaries" - } - } -} diff --git a/variables.yml b/variables.yml index 7e9cb76..4ac289a 100644 --- a/variables.yml +++ b/variables.yml @@ -1,33 +1,39 @@ --- oo: - instance: onlyoffice-docserver + instance: onlyoffice ds: image: danielberteaud/onlyoffice-docserver:latest - env: {} resources: cpu: 200 memory: 512 public_url: https://oods.example.org - secret_key: '{{ with secret "[[ .vault.prefix ]]kv/service/[[ .oo.instance ]]" }}{{ .Data.data.secret_key }}{{ end }}' - link_secret: '{{ with secret "[[ .vault.prefix ]]kv/service/[[ .oo.instance ]]" }}{{ .Data.data.link_secret }}{{ end }}' - database: - type: postgres - host: localhost - port: 5432 - name: '[[ .oo.instance ]]' - user: '{{- with secret "[[ .vault.prefix ]]database/creds/[[ .oo.instance ]]" }}{{ .Data.username }}{{ end }}' - password: '{{- with secret "[[ .vault.prefix ]]database/creds/[[ .oo.instance ]]" }}{{ .Data.password }}{{ end }}' + env: + OO_STORAGE_SECRET: '{{ with secret "[[ .vault.prefix ]]kv/service/[[ .oo.instance ]]" }}{{ .Data.data.storage_secret }}{{ end }}' + OO_JWT_TOKEN: '{{ with secret "[[ .vault.prefix ]]kv/service/[[ .oo.instance ]]" }}{{ .Data.data.jwt_token }}{{ end }}' + OO_DB_HOST: 127.0.0.1 + OO_DB_PORT: 5432 + OO_DB_NAME: '[[ .oo.instance ]]' + OO_DB_USER: '{{ with secret "[[ .vault.prefix ]]database/creds/[[ .oo.instance ]]" }}{{ .Data.username }}{{ end }}' + OO_DB_PASS: '{{ with secret "[[ .vault.prefix ]]database/creds/[[ .oo.instance ]]" }}{{ .Data.password }}{{ end }}' traefik: enabled: true - base_middlewares: [] - #- rate-limit-std@file - #- inflight-std@file - #- security-headers@file - #- forward-headers@file - #- hsts@file - #- compression@file + csp: + default-src: "'self'" + img-src: "'self' data: https://*" + script-src: "'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: https://ajax.googleapis.com https://www.youtube.com/ https://*.cloudfront.net https://cdn.rawgit.com https://code.jquery.com https://translate.googleapis.com https://code.responsivevoice.org https://cdn.jsdelivr.net" + style-src: "'self' 'unsafe-inline' data: https://fonts.googleapis.com https://translate.googleapis.com" + font-src: "'self' data: https://fonts.googleapis.com https://fonts.gstatic.com" + connect-src: "'self' https://www.zotero.org https://cdn.jsdelivr.net https://cdn.rawgit.com https://translate.googleapis.com https://code.responsivevoice.org https://onlyoffice.github.io" + media-src: "'self' https://code.responsivevoice.org" + frame-src: "'self' https://www.youtube.com https://onlyoffice.github.io" + base_middlewares: + - rate-limit-std@file + - inflight-std@file + - security-headers@file + - hsts@file + - compression@file wait_for: - service: 'master.postgres[[ .consul.suffix ]]' consul: @@ -41,9 +47,12 @@ oo: env: {} resources: cpu: 80 - memory: 128 + memory: 156 volumes: - ds: + data: type: csi source: '[[ .oo.instance ]]-data' + rabbitmq: + type: csi + source: '[[ .oo.instance ]]-rabbitmq' diff --git a/vault/policies/onlyoffice-docserver.hcl b/vault/policies/onlyoffice.hcl similarity index 100% rename from vault/policies/onlyoffice-docserver.hcl rename to vault/policies/onlyoffice.hcl