Файл docker-compose для Nextcloud со всем необходимым

Обновлено и опубликовано Опубликовано:

Используемые термины: Nextcloud, Docker, Linux.

В инструкции будет приведен не только пример файла docker-compose, но и примеры команд для настройки и запуска приложения. В итоге, мы получим:

  • Облачное решение Nextcloud с базовыми функциями.
  • Возможность работы с документами при помощи Onlyoffice.
  • Платформу для проведения видеоконференций с большим числом участников.

Для работы будет использоваться система на базе Linux. Подразумевается, что Docker и docker-compose уже установлены в системе.

Nextcloud с базовыми функциями

Для начала поднимаем облачный сервис для хранения файлов. Создаем каталог, где разместим docker файлы и переходим в него:

mkdir -p /opt/nextcloud && cd /opt/nextcloud

Создаем файл docker-compose:

vi docker-compose.yml

  1. services:
  2.  
  3.   postgres:
  4.     image: postgres:${PG_VER}-alpine
  5.     container_name: postgres
  6.     hostname: postgres
  7.     restart: unless-stopped
  8.     volumes:
  9.       - ./postgresql/data:/var/lib/postgresql/data
  10.     environment:
  11.       TZ: Europe/Moscow
  12.       POSTGRES_DB: ${DB_NAME}
  13.       POSTGRES_USER: ${DB_USER}
  14.       POSTGRES_PASSWORD: ${DB_PASSWORD}
  15.  
  16.   redis:
  17.     image: redis:alpine
  18.     container_name: redis
  19.     hostname: redis
  20.     restart: unless-stopped
  21.     environment:
  22.       TZ: Europe/Moscow
  23.  
  24.   nextcloud:
  25.     image: nextcloud:${NC_VER}
  26.     container_name: nextcloud
  27.     hostname: nextcloud
  28.     restart: unless-stopped
  29.     extra_hosts:
  30.       - "${NC_DOMAIN}:host-gateway"
  31.     depends_on:
  32.       - postgres
  33.       - redis
  34.     volumes:
  35.       - ./nextcloud:/var/www/html
  36.     environment:
  37.       TZ: Europe/Moscow
  38.       VIRTUAL_HOST: ${NC_DOMAIN}
  39.       NEXTCLOUD_TRUSTED_DOMAINS: ${NC_DOMAIN} 127.0.0.1
  40.       NEXTCLOUD_OVERWRITEPROTOCOL: https
  41.       NEXTCLOUD_ADMIN_USER: ${NC_ADMIN_USER}
  42.       NEXTCLOUD_ADMIN_PASSWORD: ${NC_ADMIN_PASSWORD}
  43.       POSTGRES_HOST: postgres
  44.       POSTGRES_DB: ${DB_NAME}
  45.       POSTGRES_USER: ${DB_USER}
  46.       POSTGRES_PASSWORD: ${DB_PASSWORD}
  47.       REDIS_HOST: redis
  48.  
  49.   caddy:
  50.     image: caddy:${CD_VER}
  51.     hostname: caddy
  52.     container_name: caddy
  53.     restart: unless-stopped
  54.     environment:
  55.       TZ: "Europe/Moscow"
  56.       NC_DOMAIN: ${NC_DOMAIN}
  57.     ports:
  58.       - 80:80
  59.       - 443:443
  60.     volumes:
  61.       - ./caddy/Caddyfile:/etc/caddy/Caddyfile
  62.       - ./caddy/ssl:/etc/caddy/ssl
  63.  
  64.   cron:
  65.     image: nextcloud:${NC_VER}
  66.     hostname: cron
  67.     container_name: cron
  68.     restart: unless-stopped
  69.     volumes:
  70.       - ./nextcloud:/var/www/html
  71.     entrypoint: /cron.sh
  72.     depends_on:
  73.       - nextcloud
  74.     environment:
  75.       TZ: "Europe/Moscow"
  76.       POSTGRES_HOST: postgres
  77.       POSTGRES_DB: ${DB_NAME}
  78.       POSTGRES_USER: ${DB_USER}
  79.       POSTGRES_PASSWORD: ${DB_PASSWORD}
  80.       REDIS_HOST: redis

Описание сценария

Кратко опишем, что выполнит наш сценарий. Подробнее про работу с docker-compose можно прочитать в инструкции Шпаргалка по работе с docker-compose.

Строки Описание
3 - 14 Поднимаем контейнер с базой данных PostgreSQL. При инициализации мы создаем пользователя и базу. Значения передаем в виде переменных, значения которых мы потом укажем в файле .env.
16 - 22 Для кэширования данных используем Redis.
24 - 47 Описываем контейнер для запуска Nextcloud. Обратите внимание, что также как для PostgreSQL, часть параметров передаем переменными из .env файла.
49 - 62 Для проксирования http запросов мы будем использовать caddy. Данный контейнер будет слушать на портах 80 и 443.
64 - 80 Данный контейнер будет использоваться для запуска заданий Nextcloud по расписанию.

Настройка и запуск

Для корректной работы сервиса нам нужно создать несколько конфигурационных файлов.

Сначала создадим файл .env:

vi .env

PG_VER=16
NC_VER=32
CD_VER=2.10

DB_USER=nextcloud
DB_PASSWORD=nextcloud123
DB_NAME=nextcloud

NC_DOMAIN=cloud.dmosk.local
NC_ADMIN_USER=admin
NC_ADMIN_PASSWORD=password123

* обратите внимание, что между знаком = не должно быть пробелов.
** вам необходимо указать свои значения:

  • PG_VER / NC_VER / CD_VER — версии PostgreSQL, Nextcloud и Caddy соответственно. Лучше изучить документацию чтобы определиться с более правильными значениями или попробовать указать последние версии, посмотрев их на Docker Hub.
  • DB_USER / DB_PASSWORD / DB_NAME — значения для первичной настройки базы данных. Имя пользователя, пароль и имя базы. Особое внимание стоит уделить паролю.
  • NC_DOMAIN / NC_ADMIN_USER / NC_ADMIN_PASSWORD — данные для инициализации Nextcloud. Укажите ваш домен, на котором должен работать сервис, а также логин с паролем для входа в облако.

Создадим каталог для файлов веб-сервера caddy:

mkdir -p caddy

Если у нас используется внутренний домен и мы не можем из вне попасть на сервер, то необходимо сгенерировать самоподписанный сертификат. Данный вариант не самый лучший и некоторые службы могут работать некорректно, но для тестирования он подойдет.

Создадим каталог для хранения сертификатов:

mkdir -p caddy/ssl

И сгенерируем сертификат:

openssl req -new -x509 -days 1461 -nodes -out caddy/ssl/cert.pem -keyout caddy/ssl/cert.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=cloud.dmosk.local" -addext "subjectAltName=DNS:cloud.dmosk.local,IP:127.0.0.1"

* в данном примере будут созданы 2 файла caddy/ssl/cert.key и caddy/ssl/cert.pem для домена cloud.dmosk.local.

Создаем конфигурационный файл для caddy:

vi caddy/Caddyfile

{$NC_DOMAIN} {
    tls /etc/caddy/ssl/cert.pem /etc/caddy/ssl/cert.key

    redir /.well-known/carddav* /remote.php/dav 301
    redir /.well-known/caldav* /remote.php/dav 301

    header {
        Strict-Transport-Security "max-age=15552000; includeSubDomains; preload"
    }

    handle {
        reverse_proxy nextcloud:80
    }
}

* обратите внимание на строку, где мы указываем путь до сертификатов. Если у вас внешний домен, доступный из вне, то кадди сам получит сертификаты от Let's Encrypt. Данную строку нужно удалить.

Запускаем контейнеры:

docker-compose up -d

Из состояние теперь можно посмотреть командой:

docker-compose ps

Для инициализации nextcloud понадобится какое-то время. Около минуты. Мы можем наблюдать за процессом, запустив непрерывное чтение логов:

docker logs nextcloud -f

После можно попробовать зайти в панель Nextcloud. Для этого в браузере вводим адрес, который указали в качестве имени. В моем примере https://cloud.dmosk.local

Мы должны увидеть окно ввода логин и пароля. Вводим данные, которые указали в файле .env.

Оптимизация

Сразу после развертывания, Nextcloud будет отображать ошибки и предупреждения, без решения которых работа облачного сервиса будет не полностью полноценной. Рассмотрим по шагам, как оптимизировать работу приложения.

1. Укажем, что nextcloud может доверять проксированию из сети docker:

docker exec --user www-data nextcloud php occ config:system:set trusted_proxies 0 --value=$(docker inspect nextcloud -f '{{range .NetworkSettings.Networks}}{{.IPPrefixLen}}{{end}}' | xargs -I {} docker inspect nextcloud -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}' | sed 's/\.[0-9]*$/\.0/')/$(docker inspect nextcloud -f '{{range .NetworkSettings.Networks}}{{.IPPrefixLen}}{{end}}')

2. Для запуска задач по расписанию используем cron, а также укажем окно обслуживания (тяжелые задания будут выполняться в данное время):

docker exec --user www-data nextcloud php occ config:app:set core backgroundjobs_mode --value="cron"

docker exec --user www-data nextcloud php occ config:system:set maintenance_window_start --type=integer --value=2

* в нашем примере наиболее долгие по времени операции будут запускаться после 02:00 ночи.

3. Выставляем телефонный регион по умолчанию:

docker exec --user www-data nextcloud php occ config:system:set default_phone_region --value="RU"

* в данном примере российский.

4. Сразу после развертывания Nextcloud, как правило, для оптимизации базы доступны миграции и команды для создания индексов. Выполняем команды:

docker exec --user www-data nextcloud php occ maintenance:repair --include-expensive

docker exec --user www-data nextcloud php occ db:add-missing-indices

5. Система будет выдавать предупреждение, если у нас не установлено приложение для обеспечения двухфакторной аутентификации. При этом, не обязательно его включать, но нужно, чтобы оно было. Выполняем команду:

docker exec --user www-data nextcloud php occ app:enable twofactor_totp

Готово. Можно пользоваться Nextcloud для работы с файлами.

Onlyoffice

Расширим функциональные возможности нашего сервиса, добавив возможность онлайн работы с документами. Для этого запустим контейнер onlyoffice.

Открываем на редактирование композ файл:

vi docker-compose.yml

Допишем в него:

 ...

  1.   onlyoffice:
  2.     image: onlyoffice/documentserver:${OO_VER}
  3.     hostname: onlyoffice
  4.     container_name: onlyoffice
  5.     restart: unless-stopped
  6.     extra_hosts:
  7.       - "${NC_DOMAIN}:host-gateway"
  8.     environment:
  9.       JWT_ENABLED: true
  10.       JWT_SECRET: ${OO_SECRET}
  11.       USE_UNAUTHORIZED_STORAGE: true
  12.     volumes:
  13.       - ./onlyoffice/data:/var/www/onlyoffice/Data

USE_UNAUTHORIZED_STORAGE — если вы используете не самоподписанный сертификат, то данная строка не нужна. Она позволяет делать запросы по https, если сертификат не может пройти валидацию.

Сгенерируем последовательность для токена:

openssl rand -hex 16

Фиксируем полученный результат. Он нам нужен для добавление системной переменной.

Откроем env файл:

vi .env

Допишем в него строку:

...
OO_VER=9.2
OO_SECRET=<Onfyoffice key>

* где Onfyoffice key — последовательность, которую мы получили командой openssl.

Запускаем новый контейнер:

docker-compose up -d

В нашем облачном приложении устанавливаем и включаем приложение onlyoffice:

docker exec --user www-data nextcloud php occ app:enable onlyoffice

Внесем изменение в конфигурацию веб-сервера кадди:

vi caddy/Caddyfile

Добавим внутрь нашей конфигурации для домена:

{$NC_DOMAIN} {
    ...

    handle_path /onlyoffice/* {
        reverse_proxy onlyoffice:80 {
            header_up X-Forwarded-Host {host}
            header_up X-Forwarded-Proto {scheme}
            header_up X-Forwarded-Prefix /onlyoffice
        }
    }


    handle {
        reverse_proxy nextcloud:80
    }
}

Перезапустим контейнер с caddy:

docker restart caddy

Осталось настроить привязку в самом Nextcloud. Это также делается из командной строки.

Прочитаем наши переменные из энвайромент файла:

source .env

Укажем URL для подключения к Onlyoffice:

docker exec --user www-data nextcloud php occ config:app:set onlyoffice DocumentServerUrl --value="https://${NC_DOMAIN}/onlyoffice/"

Зададим токен безопасности:

docker exec --user www-data nextcloud php occ config:app:set onlyoffice jwt_secret --value="${OO_SECRET}"

Если мы используем самоподписанный сертификат, то необходимо отключить его проверку:

docker exec --user www-data nextcloud php occ config:app:set onlyoffice verify_peer_off --value="true"

Переходим в веб-интерфейс, настройку Onlyoffice и кликаем Сохранить.

Talk

Приложение Talk для реализации системы видеоконференции набрало большую популярность. Добавим в наш сценарий развертывание необходимых компонентов для его корректной работы.

Talk + Coturn

Возможность выполнять видеозвонки для небольшого числа участников требует развертывания приложения Talk и Coturn.

Устанавливаем в nextcloud приложение talk:

docker exec --user www-data nextcloud php occ app:install spreed

* исторически, nextcloud совместно со Struktur AG работали над интеграцией Spreed.ME в коробку. Поэтому id приложения называется не talk.

Проинсталлируем приложение notify_push для отправки push уведомлений:

docker exec --user www-data nextcloud php occ app:install notify_push

Открываем файл docker-compose:

vi docker-compose.yml

Добавляем в него сервис coturn:

 ...

  1.   coturn:
  2.     image: coturn/coturn:latest
  3.     hostname: coturn
  4.     container_name: coturn
  5.     restart: unless-stopped
  6.     environment:
  7.       TZ: "Europe/Moscow"
  8.       DETECT_EXTERNAL_IP: yes
  9.       DETECT_RELAY_IP: yes
  10.     network_mode: host
  11.     command:
  12.       - -n
  13.       - --log-file=stdout
  14.       - --lt-cred-mech
  15.       - --fingerprint
  16.       - --static-auth-secret=${TURN_SECRET}
  17.       - --realm=${NC_DOMAIN}
  18.       - --external-ip=$$(detect-external-ip)
  19.       - --relay-ip=$$(detect-external-ip)
  20.       - --total-quota=100
  21.       - --bps-capacity=0
  22.       - --stale-nonce=600
  23.       - --no-multicast-peers

* обратите внимание на несколько моментов:

  • network_mode: host — необходимое решение для Coturn, так как TURN серверу нужен прямой доступ к реальным IP-адресам клиентов.
  • DETECT_EXTERNAL_IP — определение внешнего IP в облачных средах.

Сформируем секретный код для котурна:

openssl rand -hex 16

Открываем файл с системными переменными:

vi .env

Добавляем в него переменную со сформированным секретом:

...
TURN_SECRET=<TURN key>

Запускаем новый контейнер:

docker-compose up -d

Его состояние можно посмотреть командой:

docker-compose ps

Если на нашем хосте брандмауэр настроит на запрет, то открываем порт 3478 (tcp и udp). В зависимости от утилиты управления команды будут разные.

а) Для iptables (как правило, системы DEB):

iptables -I INPUT -p tcp --dport 3478 -j ACCEPT

iptables -I INPUT -p udp --dport 3478 -j ACCEPT

Для сохранения правил можно использовать 

apt install iptables-persistent

netfilter-persistent save

б) Для firewalld (как правило, системы RPM):

firewall-cmd --add-port=3478/{tcp,udp}

firewall-cmd --add-port=3478/{tcp,udp} --permanent

Сервис готов к использованию. Но нужно его указать в настройках Nextcloud.

Открываем веб интерфейс и переходим в раздел Конференции. Добавляем TURN сервер и указываем наш домен с портом 3478:

Прописываем turn сервер для корректной работы Talk в Nextcloud

Также необходимо прописать секретный ключ.

Проверяем подключение к сервису. Мы должны увидеть зеленую галочку:

Проверка работоспособности turn сервера

Можно устраивать конференции на небольшое число участников.

High-performance backend (signaling)

Для более серьезных нагрузок (от 5 человек) рекомендуется развернуть высокопроизводительный сервер.

Нам нужно 5 секретов для безопасного взаимодействия компонентов. Можно придумать их самостоятельно, или сгенерировать одной командой:

seq 5 | xargs -I {} openssl rand -hex 16

Команда выдаст 5 строк, каждая из которых состоит из 32 символов. Сразу скопируйте их и подпишите, например:

# Janus
c178fcea4d2c0e45194cccb245283cff

# Hash
07e164de3c2ff5656ef10f115b3d54e3

# Block
e4bef0271402c471ba45e3d97fb3c2ac

# Internal secret
5aa3203091196cfb909af062b2022aae

# Nextcloud secret
f9b088e2cc8e4e175092f8663da498d9

Данные последовательности мы будем использовать в ходе настройки компонентов.

Открываем docker композе:

vi docker-compose.yml

Допишем в него новые сервисы:

 ...

  1.   nats:
  2.     image: nats:alpine
  3.     hostname: nats
  4.     container_name: nats
  5.     restart: unless-stopped
  6.     environment:
  7.       TZ: "Europe/Moscow"
  8.  
  9.   janus:
  10.     image: canyan/janus-gateway:latest
  11.     hostname: janus
  12.     container_name: janus
  13.     restart: unless-stopped
  14.     environment:
  15.       TZ: "Europe/Moscow"
  16.     network_mode: host
  17.     volumes:
  18.       - ./janus/janus.jcfg:/usr/local/etc/janus/janus.jcfg
  19.       - ./janus/janus.transport.http.jcfg:/usr/local/etc/janus/janus.transport.http.jcfg
  20.  
  21.   signaling:
  22.     image: strukturag/nextcloud-spreed-signaling:latest
  23.     hostname: signaling
  24.     container_name: signaling
  25.     restart: unless-stopped
  26.     extra_hosts:
  27.       - "janus:host-gateway"
  28.       - "coturn:host-gateway"
  29.       - "${NC_DOMAIN}:host-gateway"
  30.     environment:
  31.       TZ: "Europe/Moscow"
  32.     depends_on:
  33.       - nats
  34.       - janus
  35.     volumes:
  36.       - ./signaling/server.conf:/config/server.conf

* где:

  • nats — обеспечиваем связь между компонентами. В нашем случае позволяет управлять комнатами и обмениваться служебными сообщениями между участниками.
  • janus — универсальный WebRTC-сервер, который выступает в роли медиа-шлюза.
  • signaling — для обмена управляющей информацией (установление, поддержание и завершение WebRTC-соединения).

Создадим каталог для хранения данных janus:

mkdir janus

Скачаем в него 2 оригинальных конфигурационных файла:

wget https://raw.githubusercontent.com/meetecho/janus-gateway/refs/heads/master/conf/janus.jcfg.sample.in -O janus/janus.jcfg

wget https://raw.githubusercontent.com/meetecho/janus-gateway/refs/heads/master/conf/janus.transport.http.jcfg.sample -O janus/janus.transport.http.jcfg

Откроем для редактирования основной конфигурационный файл:

vi janus/janus.jcfg

Приведем некоторые значения параметром к следующему виду:

        configs_folder = "/usr/local/etc/janus"
        plugins_folder = "/usr/local/lib/janus/plugins"
        transports_folder = "/usr/local/lib/janus/transports"
        events_folder = "/usr/local/lib/janus/events"
        loggers_folder = "/usr/local/lib/janus/loggers"

        full_trickle = true

        turn_rest_api_key = "c178fcea4d2c0e45194cccb245283cff"

* если опция закомментирована, то комментарий нужно снять.

Создаем каталог для хранения файлов signaling:

mkdir signaling

Скачиваем конфигурационный файл в созданный каталог:

wget https://raw.githubusercontent.com/strukturag/nextcloud-spreed-signaling/refs/heads/master/server.conf.in -O signaling/server.conf

Открываем скачанный файл на редактирование:

vi signaling/server.conf

Приводим его к виду:

[http]
listen = 0.0.0.0:8080

[sessions]
hashkey = <Hash Key>
blockkey = <Block Key>

[nats] 
url = nats://nats:4222

[clients]
internalsecret = <Internal Secret Key>

[backend]
backends = backend-1

[backend-1]
url = https://cloud.dmosk.local
secret = <Nextcloud Secret Key>


[mcu] 
type = janus
url = ws://janus:8188

[turn] 
apikey = <Janus Key>
secret = <Turn Server Key>
servers = turn:coturn:3478?transport=udp,turn:coturn:3478?transport=tcp

Можно запускать новые контейнеры:

docker-compose up -d

Делаем тестовый запрос:

curl -i http://$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' signaling):8080/api/v1/welcome

Мы должны увидеть, примерно, следующий ответ:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: nextcloud-spreed-signaling/2.1.0~docker
X-Spreed-Signaling-Features: audio-video-permissions, chat-relay, dialout, federation, hello-v2, incall-all, join-features, mcu, offer-codecs, recipient-call, serverinfo, simulcast, switchto, transient-data, transient-sessiondata, update-sdp, welcome
Date: Sat, 14 Feb 2026 20:55:19 GMT
Content-Length: 66

{"nextcloud-spreed-signaling":"Welcome","version":"2.1.0~docker"}

Открываем конфигурацию веб-сервера:

vi caddy/Caddyfile

Добавим внутри секции настройки домена:

{$NC_DOMAIN} {
    ...

    handle_path /standalone-signaling/* {
        reverse_proxy signaling:8080 {
            header_up X-Forwarded-Prefix /standalone-signaling
        }
    }


    handle {
        reverse_proxy nextcloud:80
    }
}

Перезапускаем caddy:

docker restart caddy

Попробуем сделать тестовый запрос. Для удобства ввода команды читаем системные переменные из .env файла:

source .env

И вводим:

curl -k --resolve ${NC_DOMAIN}:443:127.0.0.1 https://${NC_DOMAIN}/standalone-signaling/api/v1/welcome

Мы должны увидеть что-то на подобие:

{"nextcloud-spreed-signaling":"Welcome","version":"2.1.0~docker"}

Теперь необходимо привязать сервер к Nextcloud. В настройка последнего переходим в конференции:

Переходим к настройкам конференции Nextcloud

Добавляем новый высокопроизводительный сервер и секретный ключ (Nextcloud):

Добавляем новый высокопроизводительный сервер

Мы должны увидеть OK при проверке работоспособности:

Получаем статус проверки signaling сервиса

Теперь у нас нет программных ограничений для проведения более масштабных конференций.

# DevOps # Linux # Серверы # Контейнеризация
Дмитрий Моск — частный мастер
Был ли вам полезен этот скрипт?

Да            Нет

Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

Заказать настройку контейнеризации

Нужна бесплатная консультация?

Скрипты

Запуск Nextcloud с помощью docker-compose со всем необходимым

Пример скрипта на Python для копирования пакетов NPM с одного репозитория Nexus в другой

Развертывание caddy прокси в docker с помощью docker-compose

Файл docker-compose для развертывания Nginx Proxy Manager

Пример файла docker-compose для запуска контейнеров с сервером Grafana Loki

Пример файла docker-compose.yml для запуска и настройки Portainer

Пример файла docker-compose для развертывания чат-платформы Matrix Synapse на Linux

Другие скрипты

Все статьи

Нужен скрипт? Опишите его назначение:





Реклама