Ниже — полная инструкция по установке отдельного ONLYOFFICE Docs в контейнере Incus, с конфигом Nginx сразу на 443 (HTTPS).


📋 Часть 1: Подготовка контейнера Incus

1.1. Создание контейнера и выделение ресурсов

# На хосте
incus launch images:debian/12 ooffice-docs
incus config set ooffice-docs limits.memory 4GB
incus config set ooffice-docs limits.cpu 2

1.2. Починка Docker в Incus (обязательно)

Без этих шагов Docker внутри контейнера не заработает:

# Разрешаем вложенность
incus config set ooffice-docs security.nesting=true

# Пробрасываем FUSE
incus config set ooffice-docs linux.kernel_modules=fuse
incus config device add ooffice-docs fuse unix-char path=/dev/fuse

# Исправляем ошибку с ip_unprivileged_port_start
incus config set ooffice-docs linux.sysctl.net.ipv4.ip_unprivileged_port_start=0

# Перезапускаем
incus restart ooffice-docs

1.3. Увеличение лимитов keyring на хосте

Исправляет ошибку unable to join session keyring: disk quota exceeded:

# На хосте
sudo sysctl -w kernel.keys.maxkeys=20000
sudo sysctl -w kernel.keys.maxbytes=500000

sudo tee /etc/sysctl.d/99-docker-keyring.conf <<'EOF'
kernel.keys.maxkeys = 20000
kernel.keys.maxbytes = 500000
EOF
sudo sysctl -p /etc/sysctl.d/99-docker-keyring.conf

📦 Часть 2: Установка зависимостей внутри контейнера

incus exec ooffice-docs -- bash

apt update
apt install -y curl gnupg postgresql rabbitmq-server redis-server nginx-extras

🗄️ Часть 3: Настройка PostgreSQL

su - postgres -c "psql -c \"CREATE USER onlyoffice WITH PASSWORD 'onlyoffice';\""
su - postgres -c "psql -c \"CREATE DATABASE onlyoffice OWNER onlyoffice;\""
su - postgres -c "psql -c \"ALTER ROLE onlyoffice WITH LOGIN CREATEDB;\""

Если пользователь или база уже существуют — ошибки игнорируются.


⚙️ Часть 4: Настройка debconf

echo "onlyoffice-documentserver onlyoffice/ds-port select 8080" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/db-host string localhost" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/db-name string onlyoffice" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/db-user string onlyoffice" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/db-pwd password onlyoffice" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/rabbitmq-host string localhost" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/rabbitmq-user string guest" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/rabbitmq-pwd password guest" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/jwt-enabled boolean true" | debconf-set-selections
echo "onlyoffice-documentserver onlyoffice/jwt-secret password my_jwt_secret_here" | debconf-set-selections

# Проверка
debconf-show onlyoffice-documentserver | grep -E "port|db-|jwt"

🔑 Часть 5: GPG-ключ и репозиторий

mkdir -p -m 700 /root/.gnupg

gpg --no-default-keyring --keyring gnupg-ring:/tmp/onlyoffice.gpg \
  --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys CB2DE8E5

chmod 644 /tmp/onlyoffice.gpg
chown root:root /tmp/onlyoffice.gpg
mv /tmp/onlyoffice.gpg /usr/share/keyrings/onlyoffice.gpg

echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] https://download.onlyoffice.com/repo/debian squeeze main" \
  | tee /etc/apt/sources.list.d/onlyoffice.list

apt update

📥 Часть 6: Установка ONLYOFFICE Docs

apt install -y onlyoffice-documentserver

Во время установки debconf не должен ничего спрашивать. Если спросит — введите: host=localhost, db=onlyoffice, user=onlyoffice, password=onlyoffice, port=8080.


✅ Часть 7: Проверка

systemctl status ds-docservice
ss -tlnp | grep 8080
curl -I http://localhost:8080/

ds-docservice при первом запуске может 30–60 секунд инициализировать БД. curl должен вернуть 200 или 302.


🌐 Часть 8: Nginx на хосте (HTTPS, порт 443)

8.1. Узнайте IP контейнера

incus list ooffice-docs

Допустим, IP = 10.214.97.8.

8.2. Получите SSL-сертификат (если ещё нет)

# На хосте
apt install -y certbot python3-certbot-nginx
mkdir -p /var/www/certbot
certbot --nginx -d docs.example.com

Certbot создаст сертификаты в /etc/letsencrypt/live/docs.example.com/. Если используете самоподписанный — пропустите этот шаг и укажите свои пути в конфиге.

8.3. Полный конфиг Nginx на хосте

Создайте /etc/nginx/sites-available/onlyoffice-docs:

# Редирект HTTP -> HTTPS + ACME для Let's Encrypt
server {
    listen 80;
    listen [::]:80;
    server_name docs.example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

# WebSocket map для корректного апгрейда соединения
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# Основной HTTPS-сервер
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name docs.example.com;

    # --- SSL сертификаты ---
    ssl_certificate     /etc/letsencrypt/live/docs.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/docs.example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    add_header Strict-Transport-Security "max-age=31536000" always;

    client_max_body_size 512M;

    location / {
        # ЗАМЕНИТЕ на реальный IP контейнера ooffice-docs
        proxy_pass http://10.214.97.8:8080;

        proxy_http_version 1.1;

        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Port $server_port;

        # WebSocket — для совместного редактирования
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_connect_timeout 60s;
        proxy_send_timeout 600s;
        proxy_read_timeout 600s;

        # КРИТИЧНО: подмена внутренних адресов на внешний HTTPS
        # Docs генерирует ссылки с localhost:8080 — их нужно заменить
        proxy_set_header Accept-Encoding "";
        gzip off;

        sub_filter 'http://127.0.0.1:8080' 'https://docs.example.com';
        sub_filter 'http://localhost:8080' 'https://docs.example.com';
        sub_filter_once off;
        sub_filter_types text/html application/javascript application/json;
    }
}

8.4. Активация

ln -s /etc/nginx/sites-available/onlyoffice-docs /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

8.5. Проверка

curl -I https://docs.example.com/

Должен вернуть HTTP/2 200 или HTTP/2 302.


🔗 Часть 9: Интеграция с Nextcloud

  1. В Nextcloud: Приложения → Office & Text → ONLYOFFICE → Установить.
  2. В Настройки → ONLYOFFICE:
    • Document Editing Service address: https://docs.example.com/
    • Secret key (JWT): my_jwt_secret_here (тот же, что в debconf).
  3. Откройте любой документ в Nextcloud — он должен открыться в редакторе.

Если редактор не загружается — проверьте в браузере (F12 → Network), что запросы к docs.example.com возвращают 200, а не 404 или 502. Основные причины: неверный IP в proxy_pass, отсутствие sub_filter, несовпадение JWT-секрета.


📌 Ключевые нюансы

  • sub_filter обязателен — без него Docs будет ссылаться на localhost:8080, и редактор не загрузится через внешний домен.
  • sub_filter заменяет на https:// — если оставить http://, браузер заблокирует загрузку как mixed content.
  • WebSocket-заголовки (Upgrade, Connection) — без них не работает совместное редактирование.
  • JWT-секрет должен совпадать в debconf, в конфиге Docs и в настройках плагина Nextcloud.
  • Порт 8080 внутри контейнера — выбран, чтобы не конфликтовать с Nginx на хосте (порт 80/443).

Готово — Docs работает как отдельный сервис, и Nextcloud может его использовать.