Некоторые картинки не загружаются из РФ и РК, используйте VPN.

воскресенье, 21 апреля 2024 г.

Docker Nextcloud изменить BaseURL

Казалось бы, что может проще как изменить базовый URL?

А что такое базовый url? Классический базовый URL раньше выглядел так http://mydomen.ru/nextcloud
При этом nextcloud установлен по пути /var/www/html/nextcloud, а DocumentRoot в настройках веб-сервера  /var/www/html
Потом появился параметр RewriteBase, который позволял убрать из url nextcloud, тем самым сократив его и сделав красивым.

Мне же попалась задача следующего рода - имеется сервер, с доступом только по 443 порту. На нем крутятся разные контейнеры для работы приложения и связаны с разными портами. Фронтенд принимает запросы через nginx на 443 порт. Бэкенд на порт 8090. Nextcloud на порт 9000. И еще какие то сервисы. С бэкендом сложностей не было, так как вся логика завязана на location /app или /static, в конфиге nginx я описал данную секцию с proxy-pass:

# backend
    location ~ ^/(api|static) {
        proxy_pass  http://$host:8090;
        proxy_set_header    HOST    $host;
        proxy_set_header    X-Forwarded-Proto    $scheme;
        proxy_set_header    X-Real-IP    $remote_addr;
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

        # Allow the use of websockets
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

А в с nextcloud задача сложнее, если бы приложению нужно было только вытянуть файл и вывести на фронт, то решалось бы просто - в коде программы добавить мнимый суффикс "nextcloud" для того же адреса, а конфиге nginx его убрать (rewrite) и proxy-pass на внутренний адрес:порт. Но разработчики хотят налепить ссылок с переходом на nextcloud! В таком случае ничего не выйдет, так как сам nextcloud формирует свои ссылки и вот они будут без мнимого суффикса. Тогда нужно изменить базовый URL для nextcloud. И вот тут начались проблемы. Если бы речь шла об установленной полноценной версии, которую не будут пересобирать каждые несколько часов, то проблем особых нет, это везде описано:

  • Переместить файлы в под папку (или симлинк)
  • В config.php поправить overwritewebroot и overwrite.cli.url (остальные параметры по вкусу)
  • В .htaccess поправить RewriteBase
И все. А как быть с контейнером?, эти файлы закрыты от редактирования. Для overwritewebroot и overwrite.cli.url проблем нету, они выведены в ENV - OVERWRITEWEBROOT и OVERWRITECLIURL, но они никак не влияют на .htaccess и уж тем более на положение файлов.
В ходе экспериментов я выяснил, что config/apache-pretty-urls.config.php влияет на .htaccess, т.е. можно попробовать примонтировать его volume в контейнер. Так и сделал, но как бы я ни старался указать идентичные права, .htaccess формировался правильно только несколько раз из двадцати! Тогда я решил монтировать весь каталог config, но и тут меня постигла неудача!

Перемещение же файлов в подкаталог приводило к пересборке при перезапуске контейнера, restart, а не down

Раньше я обратил внимание на файл entrypoint.sh, который собственно и собирает всю эту кашу. Тут выяснилось, что контейнер поддерживает автоматизацию сборки при помощи hook, это описано в документации на git (ищи Auto configuration via hook folders). В итоге родилось вот такое решение (выполнять в каталоге с compose файлом, под вариант без compose файла логика такая же):
mkdir -p app-hooks/pre-installation
chmod -R 755 app-hooks

В compose.yml добавляем ENV и монтируем hook

    environment:
      - NEXTCLOUD_ADMIN_USER=airfow
      - NEXTCLOUD_ADMIN_PASSWORD=airfow
      - NEXTCLOUD_TRUSTED_DOMAINS=172.18.103.122
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_HOST=db:5432
      - OVERWRITEWEBROOT=/nextcloud
      - OVERWRITECLIURL=http://172.18.103.122:9000/nextcloud
    volumes:
      - ./nextcloud_share:/var/www/html/data
      - ./app-hooks/pre-installation:/docker-entrypoint-hooks.d/pre-installation

Сам скрипт app-hooks/pre-installation/change_RewriteBase.sh

#!/bin/sh

if [ ! -n "$OVERWRITEWEBROOT" ]; then
        exit
fi

filePrettyUrl="/var/www/html/config/apache-pretty-urls.config.php"
if [ -f $filePrettyUrl ]; then
        echo "Trying to change RewriteBase"
        echo " '$OVERWRITEWEBROOT',\n);" > $filePrettyUrl
fi;

echo "Trying to create a symbolic link $OVERWRITEWEBROOT"
symLink=/var/www/html$OVERWRITEWEBROOT
if [ -L $symLink ]; then
        unlink $symLink
fi
ln -s /var/www/html/ $symLink

Скрипт создает симлинк на основе ENV OVERWRITEWEBROOT, и изменяет config/apache-pretty-urls.config.php.

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

echo, в данном случае, регистрируется в логах, в т.ч. и в dozzle, удобно для отладки 

Один момент выяснился потом, порт 443, но протокол http, и банальный proxy_pass не прокатил. Система либо перебрасывала на 9000 порт, либо вообще ничего не делала, либо перебрасывала на https и переставала работать, так как https никто не слушает. Решение оказалось простым:

ENV в docker-compose.yml:

      - OVERWRITEWEBROOT=/nextcloud
      - OVERWRITECLIURL=http://172.18.103.122:9000/nextcloud
      - OVERWRITEHOST=172.18.103.122:443

Секция в nginx.conf

    location ~ ^/(nextcloud) {
        proxy_pass  http://$host:9000;
        proxy_set_header    HOST    $host;
        proxy_set_header    X-Forwarded-Proto    $scheme;
        proxy_set_header    X-Real-IP    $remote_addr;
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
    }

Комментариев нет:

Отправить комментарий