===== OpenCloud + OpenOffice + NPM =====
Описан вариант реализации:
* На сервере запущен Proxmox 8.4.13
* На хосте Proxmox создан ZFS vdev и примонтирован в ''/Storage''
* OpenCloud запускается через Docker внутри [[https://community-scripts.github.io/ProxmoxVE/scripts?id=docker|LXC контейнера с Ubuntu]]
* Для работы с документами запущен OnlyOffice Document Server в отдельном LXC контейнере
* В качестве reverse proxy вместо Traefik используется [[https://nginxproxymanager.com/|Nginx Proxy Manager]], который идет в стандартной конфигурации ([[https://community-scripts.github.io/ProxmoxVE/scripts?id=nginxproxymanager|ссылка на LXC]])
* В качестве места хранения данных используется отдельный dataset на хосте PVE, который монтируется в контейнер с OpenCloud с помощью mount point
==== Установка OpenOffice ====
Для создания нового LXC контейнера с OnlyOffice Document Server нужно запустить на хосте PVE [[https://community-scripts.github.io/ProxmoxVE/scripts?id=onlyoffice|скрипт установки]]:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/onlyoffice.sh)"
Затем нужно [[https://api.onlyoffice.com/docs/docs-api/more-information/faq/using-wopi/|включить WOPI]] в конфигурационном файле через ''nano /etc/onlyoffice/documentserver/local.json'', для этого в разделе ''wopi'' изменить ''enable'' на true:
"wopi": {
"enable": true,
"privateKey": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwg>
"privateKeyOld": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBK>
"publicKey": "BgIAAACkAABSU0ExAAgAAAEAAQDZocibvNv/R5sjTZe0QWZ41k5gI/ZPzQFuYNu4Uo8>
"publicKeyOld": "BgIAAACkAABSU0ExAAgAAAEAAQDZocibvNv/R5sjTZe0QWZ41k5gI/ZPzQFuYNu4>
"modulus": "lTD2Ffrausy6KKVy7aiofW6rMw5I1z68LboVUIsF4b50Nj9YoEou4blmXfaX7MRgiU5ZT>
"modulusOld": "lTD2Ffrausy6KKVy7aiofW6rMw5I1z68LboVUIsF4b50Nj9YoEou4blmXfaX7MRgiU>
"exponent": 65537,
"exponentOld": 65537
},
После чего нужно перезапустить сервис:
systemctl restart ds-docservice.service
Необходимо присвоить статический IP-адрес, либо сделать DHCP reservation на роутере - этот адрес пригодится при настройке NPM в дальнейшем.
Примечание: возможен также запуск OO DS в отдельном контейнере без отдельного хоста, но такой вариант не проверялся.
==== OpenCloud в Docker ====
Для запуска OpenCloud через Docker нужно клонировать репозиторий https://github.com/opencloud-eu/opencloud-compose:
git clone https://github.com/opencloud-eu/opencloud-compose.git
cd opencloud-compose
Затем скопировать образец файла, содержащего значения переменных окружения:
cp .env.example .env
После чего внести изменения через ''nano .env'', указав значения переменных:
^ Переменная ^ Значение ^
| OC_DOMAIN | Домен, по которому осуществляется доступ к OpenCloud через reverse proxy (например, **oc.domain.ru**) |
| DEMO_USERS | Указать false, чтобы не создавать демонстрационных пользователей |
| INITIAL_ADMIN_PASSWORD | Длинный и сложный пароль, который будет создан для первого пользователя OpenCloud. Создать, например, можно через ''tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 32'' |
| LOG_PRETTY | ''true'', чтобы логи были более удобочитаемыми |
| COLLABORA_DOMAIN | Домен, по которому осуществляется доступ к OpenOffice через reverse proxy (например, **oo.oc.domain.ru**) |
| WOPISERVER_DOMAIN | Домен, по которому осуществляется доступ к WOPI server через reverse proxy (например, **wopi.oc.domain.ru**). В данном случае он будет запускаться в стеке opencloud на отдельном порту |
Далее нужно создать два дополнительных файла для OnlyOffice, по аналогии с имеющимися.
''nano weboffice/oo.yml''
---
services:
opencloud:
environment:
# this is needed for setting the correct CSP header
COLLABORA_DOMAIN: ${COLLABORA_DOMAIN:-collabora.opencloud.test}
# expose nats and the reva gateway for the collaboration service
NATS_NATS_HOST: 0.0.0.0
GATEWAY_GRPC_ADDR: 0.0.0.0:9142
# make collabora the secure view app
FRONTEND_APP_HANDLER_SECURE_VIEW_APP_ADDR: eu.opencloud.api.collaboration.CollaboraOnline
GRAPH_AVAILABLE_ROLES: "b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5,a8d5fe5e-96e3-418d-825b-534dbdf22b99,fb6c3e19-e378-47e5-b277-9732f9de6e21,58c63c02-1d89-4572-916a-870abc5a1b7d,2d00ce52-1fc2-4dbc-8b95-a73b73395f5a,1c996275-f1c9-4e71-abdf-a42f6495e960,312c0871-5ef7-4b3a-85b6-0e4074c64049,aa97fe03-7980-45ac-9e50-b325749fd7e6"
collaboration:
image: ${OC_DOCKER_IMAGE:-opencloudeu/opencloud-rolling}:${OC_DOCKER_TAG:-latest}
networks:
opencloud-net:
depends_on:
opencloud:
condition: service_started
entrypoint:
- /bin/sh
command: [ "-c", "opencloud collaboration server" ]
environment:
COLLABORATION_GRPC_ADDR: 0.0.0.0:9301
COLLABORATION_HTTP_ADDR: 0.0.0.0:9300
MICRO_REGISTRY: "nats-js-kv"
MICRO_REGISTRY_ADDRESS: "opencloud:9233"
COLLABORATION_WOPI_SRC: https://${WOPISERVER_DOMAIN:-wopiserver.opencloud.test}
COLLABORATION_APP_NAME: "OnlyOfficeName"
COLLABORATION_APP_PRODUCT: "OnlyOffice"
COLLABORATION_APP_ADDR: https://${COLLABORA_DOMAIN:-collabora.opencloud.test}
COLLABORATION_APP_ICON: https://${COLLABORA_DOMAIN:-collabora.opencloud.test}/favicon.ico
COLLABORATION_APP_INSECURE: "${INSECURE:-true}"
COLLABORATION_CS3API_DATAGATEWAY_INSECURE: "${INSECURE:-true}"
COLLABORATION_LOG_LEVEL: ${LOG_LEVEL:-info}
OC_URL: https://${OC_DOMAIN:-cloud.opencloud.test}
volumes:
# configure the .env file to use own paths instead of docker internal volumes
- ${OC_CONFIG_DIR:-opencloud-config}:/etc/opencloud
logging:
driver: ${LOG_DRIVER:-local}
restart: always
''nano external-proxy/oo.yml''
---
services:
collaboration:
ports:
# expose the wopi server
- "9300:9300"
После чего нужно запустить стек командой:
docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml up -d
Результат команды должен быть примерно таким:
root@docker:~/opencloud-compose# docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml up -d
[+] Running 8/8
✔ collaboration Pulled 6.7s
✔ 0368fd46e3c6 Already exists 0.0s
✔ 5fc4e13002df Pull complete 3.0s
✔ b6f4dd128c04 Pull complete 3.0s
✔ f97f18512833 Pull complete 3.0s
✔ 4f4fb700ef54 Pull complete 3.0s
✔ 689386fb247f Pull complete 3.9s
✔ opencloud Pulled 6.7s
[+] Running 5/5
✔ Network opencloud-compose_opencloud-net Created 0.0s
✔ Volume "opencloud-compose_opencloud-config" Created 0.0s
✔ Volume "opencloud-compose_opencloud-data" Created 0.0s
✔ Container opencloud-compose-opencloud-1 Started 4.0s
✔ Container opencloud-compose-collaboration-1 Started 0.6s
На данном этапе первичная настройка завершена.
==== Настройка Nginx Proxy Manager ====
Предварительно необходимо:
* внести A-записи **oc.domain.ru**, **oo.oc.domain.ru**, **wopi.oc.domain.ru** у хостера DNS, которые указывают на публичный статичный IP провайдера
* реализовать форвардинг на роутере в сторону IP адреса Nginx Proxy Manager
* создать отдельный Access List
=== Внесение A-записей ===
Отличается в зависимости от хостера, для примера [[https://beget.com/ru/kb/manual/dns#redaktirovanie-zony|инструкция Beget]]
=== Форвардинг на NPM ===
Зависит от роутера, для примера [[https://www.omadanetworks.com/tr/support/faq/1917/|TP-Link Omada]]
=== Access List ===
В данном примере веб-интерфейс NPM находится по адресу http://proxy.home.lan, публичный IP ''1.2.3.4''.
Перейти по http://proxy.home.lan/nginx/access.
Справа сверху нажать кнопку **Add Access List**.
На вкладке **Detail** в поле **Name** задать имя, например 'Local plus static ext IP'.
На вкладке **Access** с помощью кнопки **Add** добавить записи:
allow 192.168.0.1/16
allow 1.2.3.4/32
deny all (добавляется автоматически по умолчанию)
Нужно добавить хосты и получить валидные SSL-сертификаты (**domain.ru** заменить на свой):
^ Хост ^ Протокол ^ Адрес ^ Порт ^ Cache assets ^ Websockets support ^ Block common exploits ^ Access list ^ SSL/Force SSL ^ SSL/HTTP/2 Support ^
| oc.domain.ru | http | | 9200 | On | On | Off | Publicly Accessible | On | On |
| oo.oc.domain.ru | http | | 80 | On | On | Off | Local plus static ext IP | On | On |
| wopi.oc.domain.ru | http | | 9300 | On | On | Off | Local plus static ext IP | On | On |
'''' - хост, на котором запущен Docker с OpenCloud
'''' - хост, на котором запущен OnlyOffice Document Server в LXC
После этих настроек должно быть следующее:
* должен быть доступен OpenCloud по адресу **oc.domain.ru**
* по адресам **oo.oc.domain.ru** & **wopi.oc.domain.ru** должно отдаваться 403 Forbidden
* работает OnlyOffice Document Server, т.е. имеется возмжность создавать и редактировать документы в браузере
Если не отображаются PDF файлы, то стоит попробовать изменить настройки расширения uBlock Origin для сайта, если таковой имеется.
==== Подготовка хранилища ====
На данном этапе все данные хранятся в docker volumes, что не очень удобно.
В данном примере рассмотрена настройка на ZFS на хосте.
Создаем отдельный вложенный датасет OpenCloud в датасете Storage, присваиваем нужные права на хосте PVE и пробрасываем в контейнер с docker (в данном случае он имеет ID 103):
zfs create Storage/OpenCloud
chown -R 101000:110000 /Storage/OpenCloud
pct set 103 -mp0 /Storage/OpenCloud/,mp=/mnt/opencloud
После чего в контейнере 103 вносим изменения в файл .env (необходимо раскомментировать эти переменные и задать им значения):
OC_CONFIG_DIR=/mnt/opencloud/config/
OC_DATA_DIR=/mnt/opencloud/data/
Перезапустить контейнеры той же командой, которой запускали в первый раз:
docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml up -d
После первого запуска будут созданы директории config & data, но будет ошибка полномочий:
root@docker:~/opencloud-compose# docker compose logs -f
opencloud-1 exited with code 1
opencloud-1 | 2025/09/16 09:16:44 Could not create config: open /etc/opencloud/opencloud.yaml: permission denied
opencloud-1 | The jwt_secret has not been set properly in your config for opencloud. Make sure your /etc/opencloud config contains the proper values (e.g. by using 'opencloud init --diff' and applying the patch or setting a value manually in the config/corresponding environment variable).
Нужно остановить контейнеры:
docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml down
На хосте PVE еще раз присвоить владельца и группу (это id root внутри docker):
chown -R 101000:110000 /Storage/OpenCloud
Повторно запустить контейнеры и проверить логи:
docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml up -d
docker compose logs -f
Далее нужно зайти на **oc.domain.ru**, загрузить файл 'file-sample_150kB.pdf' для теста и проверить на хосте, что он появился:
root@pve:/# find /Storage/OpenCloud/data/ -name "file-sample_150kB.pdf"
/Storage/OpenCloud/data/storage/users/users/47a79e02-f54d-495f-9b8b-cd122717eace/file-sample_150kB.pdf
Далее можно удалить теперь уже ненужные docker volumes:
root@docker:~/opencloud-compose# docker volume rm opencloud-compose_opencloud-config opencloud-compose_opencloud-data
opencloud-compose_opencloud-config
opencloud-compose_opencloud-data
Наверняка есть более правильный и удобный способ добиться желаемого меньшим количеством приседаний, если кто-то знает - просьба сообщить :)
==== Установка расширений ====
Расширения находятся в [[https://github.com/opencloud-eu/web-extensions|отдельном репозитории]].
Заходим в Releases https://github.com/opencloud-eu/web-extensions/releases и находим нужное расширение.
Для примера возьмем https://github.com/opencloud-eu/web-extensions/releases/tag/unzip-v1.0.2
Копируем ссылку https://github.com/opencloud-eu/web-extensions/releases/download/unzip-v1.0.2/unzip-1.0.2.zip на unzip-1.0.2.zip
На хосте docker в директории ''opencloud-compose'' скачиваем и распаковываем в соответствующую директорию расширение и перезапускаем контейнеры:
wget -q -O tmp.zip https://github.com/opencloud-eu/web-extensions/releases/download/unzip-v1.0.2/unzip-1.0.2.zip && unzip tmp.zip -d config/opencloud/apps && rm tmp.zip
docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml down
docker compose -f docker-compose.yml -f weboffice/oo.yml -f external-proxy/opencloud.yml -f external-proxy/oo.yml up -d
Для теста в OpenCloud загружаем этот же архив ''unzip-1.0.2.zip'' и проверяем, что при нажатии правой кнопки мыши появился пункт меню **Extract here**.
По аналогии устанавливаем другие расширения, изменяя адрес в команде ''wget''.
Некоторые расширения (например, ''external-sites'') требуют конфигурации после установки.
После распаковки архива нужно изменить файл настроек с помощью ''nano config/opencloud/apps/external-sites/manifest.json'', пользуясь [[https://github.com/opencloud-eu/web-extensions/tree/main/packages/web-app-external-sites|документацией]] к расширению