Это старая версия документа!


Дата написания: март 2023 г.
Автор: Graf

Сервер облачного хранилища на базе Nextcloud


Локальный IP-адрес сервера куда всё устанавливаем и где настраиваем - 192.168.10.217
IP-адрес шлюза - 192.168.10.1
Внешний IP-адрес - 77.77.77.77 (Вымышленный. Придуманный, только лишь, в качестве примера.)
Доменное имя - my-cloud.ru (Вымышленное. Придуманное, только лишь, в качестве примера.)
Nextcloud версии 25.0.4

Начало

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

  1. минимум 512 MB ОЗУ на процесс;
  2. дистрибутив на базе deb или rpm пакетов;
  3. MySQL/MariaDB или PostgreSQL;
  4. Apache 2.4 с php-fpm (можно и с mod_php) или Nginx с php-fpm;
  5. PHP 8.1.

п.1 - Испытывалось на 8 GB ОЗУ.
п.2 - У нас система будет круче! :) А именно - Slackware Linux 15.0 64-bit без DE и всем, что с ними связанно. После обновления всех доступных пакетов, посредством slackpkg, с ядром 5.15.94.
п.3 - MariaDB 10.5.18 в составе дистрибутива.
п.4 - Apache 2.4.55 с php-fpm в составе дистрибутива.
п.5 - В Slackware Linux 15.0 установлен PHP версии 7.4. Поэтому, первым делом, обновим версию PHP до 8.1.

Скачаем и установим sbopkg при помощи которого будем устанавливать недостающие программы и php-модули.

# wget https://github.com/sbopkg/sbopkg/releases/download/0.38.2/sbopkg-0.38.2-noarch-1_wsr.tgz
# upgradepkg --install-new ./sbopkg-0.38.2-noarch-1_wsr.tgz
# sbopkg -r

Для чистоты эксперимента удалим старую версию PHP и установим новую:

# slackpkg remove php
# slackpkg install php81
# php -v
PHP 8.1.16 (cli) (built: Feb 14 2023 15:50:34) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.1.16, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.16, Copyright (c), by Zend Technologies

Большинство необходимых php-модулей и программ уже установлено в системе. Установка того, чего нет в системе будет описана по мере необходимости.
В первую очередь, для управления кэшированием, установим сервер Redis. Его можно установить при помощи sbopkg, но мы соберём пакет самостоятельно при помощи сборочного скрипта (SlackBuild) от Eric Hameleers АКА Alien Bob. Он внёс кое-какие изменения для правильной работы сервера Redis через UXIX-сокет.
Скачиваем необходимые для сборки файлы, последнюю версию (на день написания статьи) Redis, исправляем версию в SlackBuild, собираем и устанавливаем.

# wget -r -nd -np -R index*,redis-6* -e robots=off http://www.slackware.com/~alien/slackbuilds/redis/build/
# wget https://download.redis.io/releases/redis-7.0.9.tar.gz
# sed -i "s/{VERSION:-6.2.6/{VERSION:-7.0.9/" ./redis.SlackBuild
# chmod +x ./redis.SlackBuild
# ./redis.SlackBuild
# upgradepkg --install-new /tmp/redis-7.0.9-x86_64-1alien.txz

Теперь установим сам Nextcloud. Так как в репозитории sbopkg находится не самая свежая версия сервера, поэтому смотрим, нам необходимую, версию ТУТ
и либо меняем вручную, либо как я, при помощи скрипта. Заодно установим php-модуль для сервера Redis и, для правильной работы просмотров pdf-файлов, php-модуль imagick.

#!/bin/bash
 
NC_PATH="/var/lib/sbopkg/SBo/15.0/network/nextcloud-server"
NC_SB="nextcloud-server.SlackBuild"
NC_SB_LOCAL=$NC_SB".sbopkg"
NC_INFO="nextcloud-server.info"
NC_INFO_LOCAL=$NC_INFO".sbopkg"
 
NC_SUM=$(cat $NC_PATH/$NC_INFO | grep MD5SUM | awk -F \" '{print $2}')
NC_VER=$(cat $NC_PATH/$NC_INFO | grep VERSION | awk -F \" '{print $2}')
NC_VER_NEW="25.0.4"
 
PHPEX_PATH="/etc/php.d"
 
# Копируем оригинальные файлы в *.sbopkg
cp $NC_PATH/$NC_SB $NC_PATH/$NC_SB_LOCAL
cp $NC_PATH/$NC_INFO $NC_PATH/$NC_INFO_LOCAL
 
# Меняем номер версии в *.SlackBuld.sbopkg
[ -f $NC_PATH/$NC_SB_LOCAL ] && sed -i "s/$NC_VER/$NC_VER_NEW/g" $NC_PATH/$NC_SB_LOCAL || { echo "Файл $NC_SB_LOCAL не найден." ; exit 1; }
 
# Меняем номер версии *.info.sbopkg
[ -f $NC_PATH/$NC_INFO_LOCAL ] && sed -i "s/$NC_VER/$NC_VER_NEW/g" $NC_PATH/$NC_INFO_LOCAL || { echo "Файл $NC_INFO_LOCAL не найден." ; exit 1; }
 
# Скачиваем файл с контрольной суммой для новой версии
wget https://download.nextcloud.com/server/releases/nextcloud-$NC_VER_NEW.tar.bz2.md5
 
# Считываем контрольную сумму для новой версии со скаченного файла в переменную
NC_SUM_NEW=$(cat ./nextcloud-$NC_VER_NEW.tar.bz2.md5 | awk '{print $1}')
 
# Меняем контрольные суммы старой версии на новую
[ -n "${NC_SUM_NEW}" ] && { sed -i "s/$NC_SUM/$NC_SUM_NEW/g" $NC_PATH/$NC_INFO_LOCAL ; rm  ./nextcloud-$NC_VER_NEW.tar.bz2.md5; } || { echo "Не найдена контрольная сумма для версии $NC_VER_NEW." ; exit 1; }
 
# Запускаем установку
# На запрос:
#
# A local info file for nextcloud-server was found in addition to the original
# info file.
#
# Use (O)riginal/(L)ocal, see (D)iff, or (C)ancel?: 
#
# и запрос:
#
# A local SlackBuild file for nextcloud-server was found in addition to the
# original SlackBuild file.
#
# Use (O)riginal/(L)ocal, see (D)iff, or (C)ancel?:
#
# отвечаем "L"
 
sbopkg -Bi "nextcloud-server php-redis php-imagick"
 
# Подключаем php-модуль redis, убрав знак комментария в redis.ini
[ -f $PHPEX_PATH/redis.ini ] && sed -i "s/\; extension=redis.so/extension=redis.so/g" $PHPEX_PATH/redis.ini || { echo "Файл $PHPEX_PATH/redis.ini не найден." ; exit 1; }
 
# Подключаем php-модуль imagick, убрав знак комментария в imagick.ini
[ -f $PHPEX_PATH/imagick.ini ] && sed -i "s/\; extension=imagick.so/extension=imagick.so/g" $PHPEX_PATH/imagick.ini || { echo "Файл $PHPEX_PATH/imagick.ini не найден." ; exit 1; }

Остальное в системе уже установлено. Перейдём к Настройке.

Настройка

MySQL

Инициализируем каталог данных MySQL, создадим системные таблицы и запустим MySQL.

# mkdir /var/lib/mysql/mysql
# mysql_install_db
# chown -R mysql.mysql /var/lib/mysql
# chmod +x /etc/rc.d/rc.mysqld
# /etc/rc.d/rc.mysqld start

Выполним первоначальную настройку запустив сценарий, который предложит установить пароль администратора (root) и даст возможность удалить тестовые базы данных и анонимного пользователя, которые создаются по умолчанию.

# mysql_secure_installation

Switch to unix_socket authentication [Y/n] n
Set root password? [Y/n] y
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

Внесём изменения в файл /etc/my.cnf.d/client.cnf

[client]
default-character-set = utf8mb4

в файл /etc/my.cnf.d/server.cnf

[server]
skip_name_resolve = 1
skip-external-locking
innodb_buffer_pool_size = 512M
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_log_buffer_size = 32M
innodb_max_dirty_pages_pct = 90
query_cache_type = 1
query_cache_limit = 2M
query_cache_min_res_unit = 2k
query_cache_size = 64M
table_open_cache = 2048
tmp_table_size= 256M
max_heap_table_size= 256M
thread_cache_size = 8
max_allowed_packet = 8M
#sql_mode = NO_ENGINE_SUBSTITUTION
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

[mysqld]
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
transaction_isolation = READ-COMMITTED
binlog_format = ROW
innodb_large_prefix=on
innodb_file_format=barracuda
innodb_file_per_table=1

и создадим файл /etc/php.d/nc.ini прописав следующее:

[mysql]
mysql.allow_local_infile=On
mysql.allow_persistent=On
mysql.cache_size=2000
mysql.max_persistent=-1
mysql.max_links=-1
mysql.default_socket=/var/run/mysql/mysql.sock
mysql.connect_timeout=60
mysql.trace_mode=Off

Apache & php-fpm

Внесём кое-какие правки в /etc/httpd/httpd.conf, а именно:

  • удалим знак комментария с модулей http2, cgi, cgid, rewrite, proxy, proxy_fcgi
  • в DirectoryIndex добавим index.php
  • в конец файла добавим строку о расположении файла nc-vhosts.conf, в котором будем настраивать необходимые директивы.
# sed -i'.org' \
-e '/mod_http2.so/s/#//' \
-e '/mod_cgi.so/s/#//' \
-e '/mod_cgid.so/s/#//' \
-e '/mod_rewrite.so/s/#//' \
-e '/mod_proxy.so/s/#//' \
-e '/mod_proxy_fcgi.so/s/#//' \
-e '/DirectoryIndex index.html/ s/$/ index.php/' \
-e '$a Include /etc/httpd/extra/nc-vhosts.conf' \
/etc/httpd/httpd.conf

Создадим файл /etc/httpd/extra/nc-vhosts.conf и добавим туда следующее:

# Nextcloud
<VirtualHost *:80>
 
    ServerAdmin it@my-cloud.ru
    ServerName 192.168.10.217
 
    DocumentRoot "/var/www/htdocs/nextcloud"
 
    <Directory "/var/www/htdocs/nextcloud">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    </Directory>
 
# Используем http2
    <IfModule http2_module>
        Protocols h2 h2c http/1.1
        H2Direct on
    </IfModule>
 
# Работаем через php-fpm
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
 
    ErrorLog "/var/log/httpd/my-cloud-error_log"
    CustomLog "/var/log/httpd/my-cloud-access_log" common
 
</VirtualHost>

Даём бит запуска и стартуем php-fpm с apache.

# chmod +x /etc/rc.d/rc.php-fpm
# chmod +x /etc/rc.d/rc.httpd

# /etc/rc.d/rc.php-fpm start
# /etc/rc.d/rc.httpd start

Если в /var/log/php-fpm.log появится ошибки,
server reached pm.max_children setting (5), consider raising it
seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers)

то нужно увеличить кол-во параллельных процессов php, в файле /etc/php-fpm.conf.
Эти процессы задаются переменными:

  • pm.max_children - максимальное количество дочерних процессов
  • pm.start_servers - количество процессов при старте
  • pm.min_spare_servers - минимальное количество процессов, ожидающих соединения
  • pm.max_spare_servers - максимальное количество процессов, ожидающих соединения

Для того, чтобы придать этим переменным правильное значение, сначала, выясним среднее значение памяти на один php-fpm процесс.

# ps -ylC php-fpm --sort:rss

S   UID   PID  PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
S     0 29742     1  0  80   0  16696  93823 -    ?        00:00:00 php-fpm
S    80 29779 29742  0  80   0 104656 103548 -    ?        00:00:32 php-fpm
S    80 29744 29742  0  80   0 129088 107368 -    ?        00:00:33 php-fpm
S    80 29743 29742  0  80   0 134612 145226 -    ?        00:00:33 php-fpm

Нас интересует столбец RSS, который показывает значения потребляемой памяти в Килобайтах. Возьмём среднее значение равное 130 Мб. Учитывая то, что из имеющихся 8 Гб ОЗУ, я готов отдать под процессы php-fpm 4 Гб, получим - 4096/130≈31 дочерних процессов я могу использовать. Округлим это число до 30 и присвоим его переменной pm.max_children.
Значение переменной min_spare_servers можно начать с расчёта из количества ядер процессора умноженное на 2. У меня 6-ядерный процессор, поэтому начнём со значения 12. Значение переменной max_spare_servers можно начать с расчёта из количества ядер процессора умноженное на 4. У меня 6-ядерный процессор, поэтому начнём со значения 24. Далее следим за потребляемой памятью и нагрузкой на процессор, в том же htop, например. И, в зависимости от результатов, уменьшаем или увеличиваем значения.
Значение переменной start_servers=(pm.min_spare_servers+pm.max_spare_servers)/2. В нашем случае получаем 18.
И добавим pm.max_requests = 1000 для ограничения максимального количества запросов, которое обработает дочерний процесс, прежде чем будет уничтожен. На всякий случай, для устранения утечек памяти.

pm.max_children = 30
pm.min_spare_servers = 12
pm.max_spare_servers = 24
pm.start_servers = 18
pm.max_requests = 1000

После любых изменений в файле /etc/php-fpm.conf не забываем рестарт php-fpm.

# /etc/rc.d/rc.php-fpm restart

На самом деле, всё настройки очень индивидуальны и подбираются, часто, методом сравнительного анализа. Меня эти устроили, так и оставил.

Переходим к завершению настройки Nextcloud в веб-интерфейсе.

Nextcloud

Продолжим настройку в веб-интерфейсе. Запустим наше облако локально, по адресу http://192.168.10.217 и введём необходимые данные.

«Имя пользователя» - пользователь с правами админа - например, admin :).
«Пароль» - пароль пользователя с правами админа.

Если вдруг забыли пароль или его нужно сменить какому-либо пользователю:
# chmod +x /var/www/htdocs/nextcloud/occ
# sudo -u apache /var/www/htdocs/nextcloud/occ user:resetpassword admin
Enter a new password: 
Confirm the new password: 
Successfully reset password for admin

Если свёрнуто, то раскрываем «Хранилище и база данных» и заполняем:
«Каталог с данными» - Здесь создастся каталог data, место, где будут храниться ВСЕ данные ВСЕХ пользователей, а так же логи Nextcloud. Лучше для этого выделить отдельный винчестер и в этом поле указать путь к его точке монтирования. Не забыв сделать её владельцем apache:apache. Либо сетевой ресурс.
Выбираем базу данных - MySQL/MariaDB и в поля ниже вводим соответствующие значения:
«Пользователь базы данных» - пользователь с правами администратора MySQL, у нас это - root;
«Пароль базы данных» - пароль пользователя с правами администратора MySQL;
«Название базы данных»- название создаваемой базы данных, у нас это - nextcloud;
«Хост базы данных»- путь к компьютеру, где установлена MySQL.

Правильнее было бы создать отдельного пользователя и БД вручную. Например:
# mysql -uroot -p
> CREATE USER 'nc_admin'@'localhost' IDENTIFIED BY 'ВашПароль';
> CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
> GRANT ALL PRIVILEGES ON nextcloud.* TO 'nc_admin'@'localhost';
> FLUSH PRIVILEGES;
> quit;

И ввести их в форму.

Нажимаем на Установить и, если всё прошло гладко, увидим предложение на установку рекомендованных приложений.
Соглашаемся или пропускаем и получаем веб-интерфейс Nextcloud.

Кэш

Для повышения производительности сервера настроим два вида кэша:

  1. кэш кода операций PHP, называемый opcache;
  2. кэширование данных веб-сервера при помощи Redis.

Добавим рекомендуемые параметры opcache в /etc/php.d/nc.ini и кое-какие параметры для приемлемой работы с файлами большого объёма:

; Размер POST-данных, которые будет принимать PHP
post_max_size = 16G

; Максимально допустимый размер загружаемых файлов (0 - без ограничений)
upload_max_filesize = 0

; Максимальный объем памяти, который может занимать сценарий
; 
; В /etc/php.ini этот параметр нужно закомментировать.
; В документации Nexctckoud предлагается установить этот параметр равный 512.
; Я увеличил в 2 раза.
memory_limit = 1G

; Часовой пояс по умолчанию, используемый функциями даты
date.timezone = Europe/Moscow
 
[opcache]
; Включаем Zend OPCache
opcache.enable = 1

; Включаем Zend OPCache для интерфейса командной строки PHP
opcache.enable_cli = 1

; Объем памяти для интернированных строк в Мбайт
opcache.interned_strings_buffer = 16

; Максимальное количество ключей (скриптов) в хэш-таблице OPcache.
; Допустимое значение, числа от 200 до 1000000.
opcache.max_accelerated_files = 10000

; Размер хранилища для OPcache
opcache.memory_consumption = 256

; Все комментарии PHPDoc храним в коде
opcache.save_comments = 1

; Всегда проверять временные метки файлов на предмет изменений в хранилище
opcache.revalidate_freq = 0

Настроим Redis на прослушивание UNIX-сокета. Для этого, в файле /etc/redis/redis.conf, уберём знаки комментария с нужных нам параметров и изменим их под наши нужды:

maxclients 3000
unixsocket /var/run/redis/redis.sock
unixsocketperm 770

для безошибочной работы Redis изменим параметры ядра:

# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
# sysctl -p

добавим пользователя apache в группу redis:

# gpasswd -a apache redis

Добавим в /var/www/htdocs/nextcloud/config/config.php:

//Меняем расположение кеша, по умолчанию это data/$user/cache, где $user - текущий пользователь.
  'cache_path' => '/tmp/nextcloud',
 
// Кэширование памяти для локально сохраненных данных.
// Если памяти достаточно много, то эффективнее использовать APCu, но его нужно установить.
  'memcache.local' => '\OC\Memcache\Redis',
 
// Если используется несколько веб-серверов включаем распределенный кэш   
//  'memcache.distributed' => '\OC\Memcache\Redis',
 
// Кэширование памяти для блокировки файлов
  'memcache.locking' => '\OC\Memcache\Redis',
 
// Разрешаем блокировку файлов к которым происходит одновременный доступ.
  'filelocking.enabled' => 'true',
 
// Настройка redis   
  'redis' =>
  array (
    'host' => '/var/run/redis/redis.sock',
    'port' => 0,
  ),

Даём бит запуска стартовому скрипту и запускаем сервер Redis.

# chmod +x /etc/rc.d/rc.redis
# /etc/rc.d/rc.redis start

Для автоматической загрузки, при запуске сервера, пропишем строчку /etc/rc.d/rc.redis start в файл /etc/rc.d/rc.local, если её там нет.

Перезапускаем php-fpm и Apache.

# /etc/rc.d/rc.php-fpm restart
# /etc/rc.d/rc.httpd restart

HTTPS

Сначала, необходимо прописать наш домен в DNS. Это делается у хостеров, провайдеров, регистраторов и т.д., там где у вас есть права на изменения записей в DNS.
(Кусок конфигурации зоны в bind для домена my-cloud.ru)

$TTL 86400
@       IN      SOA     my-cloud.ru.  it.my-cloud.ru. (
...
...
)
...
...
@       IN      A       77.77.77.77
www     IN      CNAME   @
...

На шлюзе пробросим порты 80 и 443 на наш сервер с nextcloud.

$IPTABLES -t nat -A PREROUTING -d $INET_IP -p tcp -m multiport --dport 80,443 -j DNAT --to-destination 192.168.10.217
$IPTABLES -I FORWARD 1 -i $INET_IFACE -o $LAN_IFACE -d 192.168.10.217 -p tcp -m multiport --port 80,443 -j ACCEPT

Смотрим, знает ли о нашем домене «мировое сообщество» :)

# nslookup my-cloud.ru
...
...
Non-authoritative answer:
Name:   my-cloud.ru
Address: 77.77.77.77

Знает!
Устанавливаем необходимые пакеты для получения бесплатных сертификатов от центра сертификации Let's Encrypt при помощи Certbot.

# sbopkg -Bki "configobj josepy zope.component zope.event zope.interface requests-toolbelt \
pyrfc3339 pytz python-parsedatetime python-augeas pyOpenSSL python3-configargparse letsencrypt"

Теперь останавливаем Apache и получаем сертификаты для доменов my-cloud.ru и для www.my-cloud.ru.

# /etc/rc.d/rc.httpd stop
# certbot certonly --rsa-key-size 2048 --standalone --agree-tos --no-eff-email --email it@my-cloud.ru -d my-cloud.ru -d www.my-cloud.ru

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for my-cloud.ru
http-01 challenge for www.my-cloud.ru
Waiting for verification...
Cleaning up challenges
...
...

Приведём файл /etc/httpd/extra/nc-vhosts.conf к следующему виду:

# Добавим этот блок для автоматической смены http на https
<VirtualHost *:80>
    RewriteEngine on
    ReWriteCond %{SERVER_PORT} !^443$
    RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
</VirtualHost>
 
# Nextcloud
<VirtualHost *:443>
 
   ServerAdmin it@my-cloud.ru
   ServerName my-cloud.ru
   ServerAlias www.my-cloud.ru
 
   DocumentRoot "/var/www/htdocs/nextcloud"
 
   <Directory "/var/www/htdocs/nextcloud">
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Require all granted
   </Directory>
 
# Указываем расположение сертификатов    
    SSLCertificateFile          /etc/letsencrypt/live/my-cloud.ru/cert.pem
    SSLCertificateKeyFile       /etc/letsencrypt/live/my-cloud.ru/privkey.pem
    SSLCertificateChainFile     /etc/letsencrypt/live/my-cloud.ru/chain.pem
 
# Добавляем блок для правильной обработки заголовков
   <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
   </IfModule>
 
# Используем http2
    <IfModule http2_module>
        Protocols h2 h2c http/1.1
        H2Direct on
    </IfModule>
 
# Работаем через php-fpm
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
 
   ErrorLog "/var/log/httpd/my-cloud-error_log"
   CustomLog "/var/log/httpd/my-cloud-access_log" common
 
</VirtualHost>

Добавим в файл /var/www/htdocs/nextcloud/config/config.php доверительные адреса с которых будут идти обращения.
Это локальный IP-адрес сервера Nextclod, IP-адрес шлюза, внешний IP-адрес и внешние домены.

  'trusted_domains' =>
  array (
    0 => '192.168.10.217',
    1 => '192.168.10.1',
    2 => '77.77.77.77',
    3 => 'my-cloud.ru',
    4 => 'www.my-cloud.ru',
  ),

Если используется обратное SSL-проксирование, то для правильной работы CalDAV или CardDAV, нужно прописать на проксирующем сервере в блоке VirtualHost для Nextcloud:

    SSLProxyEngine on
    RequestHeader set X-Forwarded-Proto "https"
 
    ProxyPreserveHost   On
    ProxyPass           "/" "http://192.168.10.217/"
    ProxyPassReverse    "/" "http://192.168.10.217/"
 
    RewriteEngine On
    RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
    RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]

И добавить в /var/www/htdocs/nextcloud/config/config.php

// IP-адрес(а) с обратным SSL-прокси. 
  'trusted_proxies'   => ['192.168.10.1'],
// Отменяем автоматическое определение имени хоста Nextcloud, задав его вручную.
  'overwritehost'     => 'my-cloud.ru',
// Отменяем автоматическое определение протокола, задав его вручную.  
  'overwriteprotocol' => 'https',
// Отменяем автоматическое определение webroot-каталога Nextcloud для генерации URL-адресов, задав его вручную.
  'overwritewebroot'  => '/',
// Перезаписываем значение IP-адреса на адрес(а) сервера с обратным SSL-прокси.
  'overwritecondaddr' => '^192\.168\.10\.1$'

Перезапускаем php-fpm и запускаем Apache.

# /etc/rc.d/rc.php-fpm restart
# /etc/rc.d/rc.httpd start

Почта

Для того, чтобы можно было получать уведомления от сервисов NextClod на свой адрес электронной почты, его необходимо внести в разделе «Параметры пользователя» → «Личная информация» поле «E-mail» или в настройках пользователей при входе админом.
И настроить или указать почтовый сервер через который будут отправляться письма в разделе «Параметры сервера»→«Основные параметры».



Предлагается два способа отправки: SMTP и Sendmail.
SMTP самый простой и, в данном случае, самый правильный способ, поскольку почтовый сервер находится не на том же компьютере, что и Nextcloud.
Если вы захотите использовать вариант Sendmail, то необходимо наличие почтового сервера на одном компьютере с Nextcloud. Это может быть и Postfix, и Exim, и даже, обычный, SSMTP, но их надо настраивать отдельно, а это уже другие статьи :).
Заполнив все поля, нажимаем кнопку «Отправить сообщение». И, если всё настроено правильно, то на указанную в личных настройках почту, придёт тестовое письмо.

Проверка

Теперь необходимо проверить, на сколько мы всё верно настроили.
Зайдя в «Параметры сервера»→«Общие сведения», должный увидеть:



Если не всё гладко, то будет описано какие обнаружены ошибки и как их исправить.
Рекомендуется заходить в этот раздел, после каждого обновления Nextcloud.

Тюнинг

Cron

Как советуют в пункте «Основные параметры» → «Фоновые задания»:
Для правильной работы сервера Nextcloud важно правильно настроить выполнение задач в фоновом режиме. Рекомендуемым вариантом запуска фоновых задач является использование планировщика «Cron».
и, дабы не получить сообщение об ошибке:
«Последнее задание было выполнено СТОЛЬКО-ТО часов (дней) назад. Похоже, что-то не в порядке.»
настроим cron на выполнение таких заданий в фоне.

Для этого выполним:

# crontab -u apache -e

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

*/5  *  *  *  * php -f /var/www/htdocs/nextcloud/cron.php

В веб-интерфейсе выставим переключатель на «Cron».

Office

Для рабы с офисными документами, будем использовать возможности LibreOffice. Веб-версия LibreOffice называется Collabora Online. Она разрабатывается компанией Collabora Productivity, дочерним предприятием компании Collabora, которая уже много лет является основным автором кода LibreOffice и имеет коммерческое партнерство с The Document Foundation.
Collabora Online Development Edition (CODE) - это бесплатная версия для сообщества Open Source (аналогично LibreOffice Community Edition), но у Collabora есть и коммерческая платная версия. Компании, использующие коммерческий вариант, в основном спонсируют Collabora за разработку версии с открытым исходным кодом.
CODE не является самостоятельным приложением. Это внутренний сервис редактора документов без пользовательского интерфейса, который взаимодействует с NextCloud через протокол WOPI (Web Application Open Platform Interface). Он ожидает, что NextCloud предоставит пользовательский интерфейс (веб-страницу).
CODE - это «клиент WOPI» с API, который предлагает возможности редактирования документов, размещенных в NextCloud («хост WOPI»).
Онлайн-редактор отображается во встроенном HTML-фрейме прямо в среде NextCloud.

Далее пойдёт описание интеграции CODE в наш NextCloud.
Для работы CODE будем использовать его образ в Docker-контейнере.
Поэтому, для начала, установим и запустим Docker. На момент написания статьи, это docker версии 23.0.1.

# wget http://slackware.su/forum/files/nc/docker.tar.gz
# tar xf ./docker.tar.gz
# wget https://download.docker.com/linux/static/stable/x86_64/docker-23.0.1.tgz
# tar -zxvf ./docker-23.0.1.tgz --strip-components=1 -C ./docker/usr/bin/ docker/
# cd docker
# makepkg  -l y -c n /tmp/docker-23.0.1-x86_64-1.txz
# upgradepkg --install-new /tmp/docker-23.0.1-x86_64-1.txz
# /etc/rc.d/rc.docker start

Не забываем прописать в /etc/rc.d/rc.local запуск docker'а.

Теперь, необходимо прописать поддомен для CODE в DNS, например - office. Это делается у хостеров, провайдеров, регистраторов и т.д., там где у вас есть права на изменения записей в DNS.
(Кусок конфигурации зоны в bind для домена my-cloud.ru)

$TTL 86400
@       IN      SOA     my-cloud.ru.  it.my-cloud.ru. (
...
...
)
...
...
@       IN      A       77.77.77.77
www     IN      CNAME   @
office  IN      CNAME   @
...

Для правильной работы CODE, на шлюзе пробросим пор 9980, в нашем случае, на сервер с Nextcloud.
т.е. просто добавим порт в уже существующую запись.

$IPTABLES -t nat -A PREROUTING -d $INET_IP -p tcp -m multiport --dport 80,443,9980 -j DNAT --to-destination 192.168.10.217
$IPTABLES -I FORWARD 1 -i $INET_IFACE -o $LAN_IFACE -d 192.168.10.217 -p tcp -m multiport --port 80,443,9980 -j ACCEPT

Смотрим, знает ли о нашем поддомене «мировое сообщество» :)

# nslookup office.my-cloud.ru
...
...
Non-authoritative answer:
Name:   office.my-cloud.ru
Address: 77.77.77.77

Знает!
Загрузим образ CODE c Docker HUB.

# docker pull collabora/code

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

# docker run -t -d -p 192.168.10.217:9980:9980 \
-e "domain=my-cloud.ru" \
-e "server_name=office.my-cloud.ru" \
-e "dictionaries= ru en" \
-e "username=admin" \
-e "password=SuperPassword" \
--privileged \
--name=CODE \
--restart always \
--cap-add MKNOD \
collabora/code

где:
run - создаём и запускаем новый контейнер из образа;
-t - выделяем псевдо-TTY (терминал);
-d - запускаем контейнер в фоновом режиме и выводим идентификатор контейнера;
-p - перенаправляем внутренний порт контейнера на локальный порт по IP-адресу;
domain - передаём доменное имя хоста (можно IP);
server_name - имя сервера. Без этого CODE может предоставить не правильный хост для подключения к веб-сокету, если перед ним прокси-сервер;
dictionaries - запускаем с дополнительными словарями;
username - имя пользователя для консоли администратора;
password - пароль пользователя для консоли администратора;
–privileged - для более быстрого создания jail через bind mount;
–name - присваиваем имя контейнеру;
–restart - политика перезапуска, применяемая при выходе из контейнера (always - всегда);
–cap-add - добавляем возможности Linux.

Дальше, останавливаем Apache и получаем сертификаты для домена office.my-cloud.ru

# /etc/rc.d/rc.httpd stop
# certbot certonly --rsa-key-size 2048 --standalone --agree-tos --no-eff-email --email it@my-cloud.ru -d office.my-cloud.ru

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for office.my-cloud.ru
Waiting for verification...
Cleaning up challenges
...
...

Добавим блок VirtualHost в файл /etc/httpd/extra/nc-vhosts.conf для работы CODE:

<VirtualHost *:443>
    ServerName office.my-cloud.ru
    ServerAdmin it@my-cloud.ru
 
    # Указываем сертификаты
    SSLEngine on
    SSLCertificateFile          /etc/letsencrypt/live/office.my-cloud.ru/cert.pem
    SSLCertificateKeyFile       /etc/letsencrypt/live/office.my-cloud.ru/privkey.pem
    SSLCertificateChainFile     /etc/letsencrypt/live/office.my-cloud.ru/chain.pem
 
    # Проксируем выданный сертификат для office.my-cloud.ru
    SSLProxyEngine On
    SSLProxyVerify None
    SSLProxyCheckPeerCN Off
    SSLProxyCheckPeerName Off
    RequestHeader set X-Forwarded-Proto "https"
 
    # Разрешаем кодированные слэши
    AllowEncodedSlashes NoDecode
 
    # Сохраняем host в заголовке при проксировании.
    ProxyPreserveHost On
 
    # Проксируем статические html, js, изображения и т.д., полученные от CODE
    # демона "coolwsd" и клиента "browser".
    ProxyPass           /browser https://192.168.10.217:9980/browser retry=0
    ProxyPassReverse    /browser https://192.168.10.217:9980/browser
 
    # URL-адрес обнаружения WOPI.
    ProxyPass           /hosting/discovery https://192.168.10.217:9980/hosting/discovery retry=0
    ProxyPassReverse    /hosting/discovery https://192.168.10.217:9980/hosting/discovery
 
    # Возможности
    ProxyPass           /hosting/capabilities https://192.168.10.217:9980/hosting/capabilities retry=0
    ProxyPassReverse    /hosting/capabilities https://192.168.10.217:9980/hosting/capabilities
 
    # Главный websocket.
    ProxyPassMatch      "/cool/(.*)/ws$"      wss://192.168.10.217:9980/cool/$1/ws nocanon
 
    # websocket консоли администратора
    ProxyPass           /cool/adminws wss://192.168.10.217:9980/cool/adminws
 
    # Загрузка как полноэкранных презентаций, так и изображений
    ProxyPass           /cool https://192.168.10.217:9980/cool
    ProxyPassReverse    /cool https://192.168.10.217:9980/cool
 
    # Совместимость с интеграциями, использующими конечную точку /lool/convert-to
    ProxyPass           /lool https://192.168.10.217:9980/cool
    ProxyPassReverse    /lool https://192.168.10.217:9980/cool
 
    # Перенаправляем все остальные запросы (эти строки обязательно прописать в конце после основных перенаправлений)
    ProxyPass           "/" "https://192.168.10.217:9980/"
    ProxyPassReverse    "/" "https://192.168.10.217:9980/"
 
    # Логи
    ErrorLog "/var/log/httpd/office.my-cloud.ru-error_log"
    CustomLog "/var/log/httpd/office.my-cloud.ru-access_log" common
 
</VirtualHost>

Добавим в файл /var/www/htdocs/nextcloud/config/config.php в доверительные домены адрес сервера CODE.

  'trusted_domains' =>
  array (
    0 => '192.168.10.217',
    1 => '192.168.10.1',
    2 => '77.77.77.77',
    3 => 'my-cloud.ru',
    4 => 'www.my-cloud.ru',
    5 => 'office.my-cloud.ru',
  ),

Перезапускаем docker, php-fpm и стартуем apache.

# /etc/rc.d/rc.docker restart
# /etc/rc.d/rc.php-fpm restart
# /etc/rc.d/rc.httpd start

Если зайти по адресу: https://office.my-cloud.ru/, то мы должно увидеть «OK».
Статистику можно посмотреть в консоли администратора по адресу: https://office.my-cloud.ru/browser/dist/admin/admin.html, введя логин-пароль заданный при запуске Docker-контейнера.

Для завершения настройки CODE перейдём в Nextclod и добавим наш сервер в «Параметры сервера» →«Офис»
(Данный апплет был установлен, если вы выбрали его на этапе начальной установки в рекомендованных приложениях. Если «нет», то установите его из магазина Nextcloud в панели администратора «Приложения» → «Nextcloud Office»).
Пропишем и сохраним разрешённые IP-адреса для использования нашим сервером CODE:



выберем «Использовать собственный сервер»;
поставим галку «Отключить проверку сертификата»;
пропишем и сохраним URL нашего сервера CODE - https://office.my-cloud.ru/
В конечном итоге, должны увидеть надпись - Сервер Collabora Online доступен.



Теперь можно создавать и редактировать офисные документы.

Посмотреть логи в контейнере:

# docker logs --follow CODE
  • Обновление Docker-образа

Обновление образа сводится к удалению старого, загрузки нового и запуску со соответствующими параметрами:

# docker stop CODE
# docker rm -f CODE
# docker rmi -f collabora/code
# docker pull collabora/code
# docker run -t -d -p 192.168.10.217:9980:9980 \
-e "domain=my-cloud.ru" \
-e "server_name=office.my-cloud.ru" \
-e "dictionaries= ru en" \
-e "username=admin" \
-e "password=SuperPassword" \
--privileged \
--name=CODE \
--restart always \
--cap-add MKNOD \
collabora/code

# /etc/rc.d/rc.docker restart
# /etc/rc.d/rc.php-fpm restart
# /etc/rc.d/rc.httpd restart

Внешнее хранилище

В Nextcloud есть возможность подключать дополнительные ресурсы в качестве удалённого хранилища.
ТУТ подробно описано как это делать.
Я хочу описать возможность подключения сетевого samaba-каталога, смонтированного локально, как внешнее хранилище.
Можно, конечно, подключить такой каталог и по протоколу SMB/CIFS, выбрав его в приложении которое мы установим чуть ниже по статье, но этот способ показался мне медленнее.

И так, для начала, на файловом сервере необходимо дать разрешение пользователю и группе apache на работу с samba-ресурсом.
Например, если имя ресурса будет users_data, то нужно его прописать в соответствующий параметр в smb.conf

[users_data]
        ...
        path = /opt/ud
        valid users = @users,apache,@apache
        write list = @users,apache,@apache
        ...

И рекурсивно дать полные права на соответствующий каталог пользователю при помощи которого будем монтировать ресурс на Nextcloud сервере.
Допустим, на файловом сервере, мы создали специального пользователя nc_user:

# setfacl -Rm u:nc_user:rwx /opt/ud
# setfacl -dRm u:nc_user:rwx /opt/ud

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

# /etc/rc.d/rc.samaba restart

Теперь на Nextcloud-сервере создадим файл /root/.smbclient с содержимым:

username=nc_user
password=SuperPuperPassword

Создадим каталог в который будем монтировать удалённый ресурс:

# mkdir -p /mnt/fileserver/u_data
# chown -R apache:apache /mnt/fileserver/u_data
# chmod -R 0770 /mnt/fileserver/u_data

Для автоматического монтирования при загрузке системы пропишем в /etc/fstab:

//192.168.10.244/user_data  /mnt/fileserver/u_data  cifs credentials=/root/.smbclient,uid=80,gid=80 0 0 

где, 192.168.10.244 - адрес файлового сервера.

установим и активируем php-плагин:

# pecl install smbclient
# echo "extension=smbclient.so" > /etc/php.d/smbclient.ini

Теперь войдём в Nextcloud администратором и у становим соответствующее приложение:
Администратор → Приложения → External storage support



После перейдём в Администратор → Параметры сервера → Внешнее хранилище и настроим наше хранилище как «Локальное».



Можно давать доступы внутри общего ресурса:



WebDAV

Давайте подключим наш сервер облачного хранилища по WebDAV, как сетевой ресурс для пользователя graf, через консоль.

  • Windows консоль
 net use Z: https://my-cloud.ru/remote.php/dav/files/graf/ /user:graf ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_graf
  • Linux консоль:

Для того, чтобы примонтировать наше облако в консоли, для начала, необходимо установить davfs2, создав, до этого, специальную группу и пользователя.

# groupadd -g 230 davfs2
# useradd -u 230 -d /var/cache/davfs2 -g davfs2 -s /bin/false davfs2
# sbopkg -Bi davfs2

Затем, пользователя graf добавить в группу davfs2. Создать каталог для монтирования и файл в скрытой директории, в котором будут записаны данные для подключения.

# usermod -aG davfs2 graf
# mkdir /home/graf/mycloud
# mkdir /home/graf/.davfs2
# cp /etc/davfs2/secrets /home/graf/.davfs2/secrets

Теперь пропишем в файл /home/graf/.davfs2/secrets строку

 https://my-cloud.ru/remote.php/dav/files/graf/ graf ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_graf

и обезопасим его.

# chown graf /home/graf/.davfs2/secrets
# chmod 600 /home/graf/.davfs2/secrets

Для автоматического монтирования при логине, добавим в /etc/fstab строчку.

https://my-cloud.ru/remote.php/dav/files/graf/ /home/graf/mycloud davfs user,rw,auto 0 0

Заходим пользователем graf и пробуем монтировать:

$ mount ~/mycloud/

В /home/graf/mycloud должен примонтироваться облачный ресурс пользователя graf.

Но, если на компьютере больше одного пользователя, лучше монтировать или вручную,

# mount -t davfs https://my-cloud.ru/remote.php/dav/files/graf/ /home/graf/mycloud

Please enter the username to authenticate with server
https://my-cloud.ru/remote.php/dav/files/graf/ or hit enter for none.
  Username: graf
Please enter the password to authenticate user graf with server
https://my-cloud.ru/remote.php/dav/files/graf/ or hit enter for none.
  Password:  

или добавить эту строчку в скрипт автозапуска.

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

VNC

Подключимся к удaлённому рабочему столу прямо из web-интерфейса Nextcloud.

Я покажу пример для подключения нескольких рабочих столов при помощи noVNC.
Делаем всё на сервере Nextcloud.
Клонируем исходники в /opt и создадим каталог для токенов:

# git clone https://github.com/novnc/noVNC.git /opt/novnc
# git clone https://github.com/novnc/websockify  /opt/novnc/utils/websockify
# mkdir -p /opt/novnc/tokens

В /opt/novnc/tokens создадим файл tokens.conf и пропишем туда:

kadr: 192.168.10.21:5900
buh: 192.168.10.22:5900
dir: 192.168.10.23:5900

где, подразумевается, что на указанных IP-адресах поднят VNC-сервер на порту 5900. Первый столбец, это название токена по которому мы будем обращаться для подключения. Может быть произвольным.
Запускаем WebSocket-server на порту 8686:

# /opt/noVNC/utils/websockify/websockify.py --web /opt/novnc --token-plugin TokenFile --token-source /opt/novnc/tokens/tokens.conf 8686 &

WebSocket server settings:
  - Listen on :8686
  - Web server. Web root: /opt/novnc
  - No SSL/TLS support (no cert file)
  - proxying from :8686 to targets generated by TokenFile

Улучшения

Всё, нижеописанное, относиться к добавлению параметров в файл /var/www/htdocs/nextcloud/config/config.php

  • Перенос каталога с данными в сетевой smb-каталог

Допустим, IP-адрес нашего файлового сервера - 192.168.10.244
А samba-ресурс - nc_data, то примерная конфигурация ресурса в cmb.conf на файловом сервере:

[nc_data]
        path = /opt/For_Nextcloud
        writeable = yes
        browseable = yes
        guest ok = no
        valid users = nc_user,apache,@apache
        write list = nc_user,apache,@apache
        create mask = 1770
        directory mask = 1770
        printable = no
        available = yes
        locking = yes
        oplocks = no
        level2 oplocks = no
        inherit permissions = yes

Здесь же, на файловом сервере, создадим каталог и пользователя при помощи которого будем монтировать ресурс на Nextcloud сервере:

# mkdir -p /opt/For_Nextcloud
# chown -R apache:apache /opt/For_Nextcloud
# chmod -R 0770 /opt/For_Nextcloud
# useradd -d /dev/null -s /bin/bash -g users nc_user
# passwd nc_user
# smbpasswd -a nc_user 
# setfacl -Rm u:nc_user:rwx /opt/For_Nextcloud
# setfacl -dRm u:nc_user:rwx /opt/For_Nextcloud
# /etc/rc.d/rc.samaba restart

Теперь на Nextcloud-сервере создадим файл /root/.smbclient с содержимым:

username=nc_user
password=SuperPuperPassword

Создадим каталог в который будем монтировать удалённый ресурс:

# mkdir -p /opt/4nc/data
# chown -R apache:apache /opt/4nc/data
# chmod -R 0770 /opt/4nc/data

Для автоматического монтирования при загрузке системы пропишем в /etc/fstab:

//192.168.10.244/nc_data  /opt/4nc/data   cifs   credentials=/root/.smbclient,uid=80,gid=80,dir_mode=0770,file_mode=0770  0 0

В /var/www/htdocs/nextcloud/config/config.php изменим параметр на новый:

'datadirectory' => '/opt/4nc/data',

если ранее не устанавливали, то установим и активируем php-плагин:

# pecl install smbclient
# echo "extension=smbclient.so" > /etc/php.d/smbclient.ini

и перезапустим php-fpm и apache:

# /etc/rc.d/rc.php-fpm restart
# /etc/rc.d/rc.httpd restart
  • Красивые URL

Удалим строку index.php, которая делает URL-адреса более красивыми:

'overwrite.cli.url' => 'https://my-cloud.ru' ,
'htaccess.RewriteBase' => '/',

чтобы обновить файл .htaccess выполним в терминале команду occ от имени apache:

# sudo -u apache php /var/www/htdocs/nextcloud/occ maintenance:update:htaccess

и перезапустим php-fpm и apache:

# /etc/rc.d/rc.php-fpm restart
# /etc/rc.d/rc.httpd restart
  • Прочее

Просто полезные фишки. Прописывать их или нет и с какими параметрами, решать вам.

 // Для удаления предупреждения - "Не указан регион размещения этого сервера Nextcloud"
 'default_phone_region' => 'RU',
 // Отключение ссылки на создание учётной записи
 'simpleSignUpLink.shown' => false,
 // Отключение ссылки на сброс пароля
 'lost_password_link' => 'disabled',
 // Отключение автозаполнения логина при входе
 'login_form_autocomplete' => false,
 // Отключить веб-обновление
 'upgrade.disable-web' => false,
 // Отключение режима обслуживания
 'maintenance' => false,
 // Разрешить предварительный просмотр файлов: изображений, обложек файлов MP3, текстовых документов
 'enable_previews' => true,
 // Разрешить администраторам устанавливать приложения из магазина Nextcloud
 'appstoreenabled' => true,
 // Запрещаем вносить изменения в файл конфигурации через web-интерфейс.
 // При обновление нужно установить в "false" (оно же стоит по умолчанию).
 'config_is_read_only' => true,
 // Запретить Nextcloud выход в Интернет.
 // Пропадёт много функций  связанных с Интернетом, например, возможность установки приложений из магазина Nextcloud
 'has_internet_connection' => false,
 // Настройки журнала. Каталог /var/log/nextcloud нужно создать с правами для apache:apache
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'log_type' => 'file',
  'logdateformat' => 'd-m-Y H:i:s',
  'loglevel' => 2,
  'log_rotate_size' => 10485760,
  'logtimezone' => 'Europe/Moscow',

Ссылки

Навигация
Печать/экспорт
QR Code
QR Code wiki:articles:nc15 (generated for current page)