
Я хотел бы настроить nginx как обратный прокси-сервер с несколькими приложениями в контейнерах Docker, постоянно размещенными в определенных местах, например:
https://sub.example.com/wiki
https://sub.example.com/app1
https://sub.example.com/app2
В частности, я хочу использоватьизображение докера mediawikiрядом с другими приложениями. Это мой docker-compose.yml:
version: '3.5'
services:
mediawiki:
image: mediawiki
restart: unless-stopped
hostname: mediawiki
ports:
- "8080:80"
links:
- database
volumes:
- images:/var/www/html/images
# - ./wiki/LocalSettings.php:/var/www/html/LocalSettings.php
networks:
- wiki
database:
image: mariadb
restart: unless-stopped
hostname: database
environment:
MYSQL_DATABASE: my_wiki
MYSQL_USER: wikiuser
MYSQL_PASSWORD: example
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
volumes:
- db:/var/lib/mysql
networks:
- wiki
app1:
# ...
expose:
- "4000"
networks:
- apps
nginx:
image: nginx:1.23-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./certbot/conf:/etc/nginx/ssl
- ./certbot/data:/usr/share/nginx/html/letsencrypt
depends_on:
- app1
- mediawiki
networks:
- apps
- wiki
certbot:
image: certbot/certbot:latest
# ...
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/logs:/var/log/letsencrypt
- ./certbot/data:/usr/share/nginx/html/letsencrypt
networks:
- apps
- wiki
networks:
apps:
wiki:
Проблема, с которой я столкнулся, заключается в том default.conf
, что с помощью следующего я могу проксировать контейнер MediaWiki, а также другие приложения, но некоторые ссылки и ресурсы возвращают ошибку 404.
upstream testwiki {
server mediawiki:80;
}
server {
listen 80;
listen [::]:80;
server_name sub.example.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name sub.example.com;
ssl_certificate /etc/nginx/ssl/live/sub.example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/sub.example.com/privkey.pem;
location /wiki/ {
proxy_pass http://testwiki/;
proxy_set_header Host $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-Host $server_name;
}
}
Я подозреваю, что причина такого поведения кроется в реляционных URL, таких как <a href="/mw-config/index.php">complete the installation</a>
, направляющих запросы в корневое местоположение вместо вложенного. Я перепробовал много вещей, таких как rewrite
(включая regex), sub_filter
, proxy_redirect
и proxy_set_header
методы, но лучшее, что я придумал, это:
location /wiki/ {
proxy_pass http://mediawiki:80/;
proxy_set_header Host $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-Host $server_name;
}
location /app1/ {
proxy_pass http://app1:4000/;
proxy_set_header Host $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-Host $server_name;
}
if ($http_referer = "https://sub.example.com/wiki/") {
set $proxypass http://mediawiki:80;
}
if ($http_referer = "https://sub.example.com/app1/") {
set $proxypass http://app1:4000;
}
location / {
proxy_pass $proxypass;
proxy_set_header Host $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;
}
Поскольку я не могу настроить baseurl для mediawiki (пока), я попытался проксировать входящие запросы в корневом расположении в зависимости от http_referer
. Это работает для всех начальных запросов GET, сделанных в , https://sub.example.com/wiki/
а также для ссылки, упомянутой выше.
Однако после нажатия <a href="/mw-config/index.php">...
, index.php
делает дальнейшие запросы - снова направленные на https://sub.example.com/
. Поскольку URL не перезаписывается и реферер говорит https://sub.example.com/mw-config/index.php
, эти запросы возвращают 500.
Мой вопрос: как исправить это поведение, чтобы мои приложения постоянно находились в соответствующем месте? К сожалению, на данный момент я не могу изменить поддомен.
Любая помощь приветствуется!
Редактировать:
Поскольку я хочу использовать несколько других приложений, которые могут столкнуться с похожими проблемами, я хотел бы предложить более общее решение. В некоторых случаях у меня нет контроля над базовым URL.
решение1
Здесь есть несколько вещей, по которым нам нужно прийти к единому мнению, чтобы это сработало:
- NGINXконфигурация: маршрутизация на основе пути, обратный прокси-сервер
- Я попробовал вашу конфигурацию, иЯ считаю, что ваша конфигурация правильная.
- Apache2конфигурация: правильно сопоставлять URI с путями к файлам и скриптами
- Используйте директиву
AliasMatch "^/wiki(.*)" "/var/www/html/$1"
для правильного удаления/wiki
и сопоставления с внутренними путями файлов
- Используйте директиву
- МедиаВикинастройки: добавьте
/wiki
путь, чтобыNginx
знать, куда следует перенаправлять ссылки через прокси-сервер, а затемApache2
можно удалить/wiki
и использовать правильные внутренние пути к файлам.- Установите
$wgScriptPath = "/wiki";
файлLocalSettings.php
, созданный после запуска установки MediaWiki, и переопределите этот файл в вашемdocker-compose.yml
- Установите
- Docker-композитор: Сохраните эти изменения, смонтировав наши измененные локальные файлы в
mediawiki
контейнер Docker.
Apache2
Мы собираемся добавить AliasMatch "^/wiki(.*)" "/var/www/html/$1"
в конфигурацию в /etc/apache2/sites-enabled/000-default.conf
. Вам также нужно будет переопределить содержимое этого файла в вашемdocker-compose.yml
#/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
AliasMatch "^/wiki(.*)" "/var/www/html/$1"
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
AllowEncodedSlashes NoDecode
</VirtualHost>
Настройки MediaWiki:
Это всего лишь фрагмент файла LocalSettings.php
, который нужно изменить. Он немного великоват, чтобы включать здесь все значение по умолчанию. Похоже, у вас уже есть локальная копия, LocalSettings.php
которую вы монтируете в контейнер docker с помощью docker-compose, поэтому просто измените $wgScriptPath
там переменную и перезапустите контейнер.
## The URL base path to the directory containing the wiki;
## defaults for all runtime URL paths are based off of this.
## For more information on customizing the URLs
## (like /w/index.php/Page_title to /wiki/Page_title) please see:
## https://www.mediawiki.org/wiki/Manual:Short_URL
$wgScriptPath = "/wiki";
Docker-композитор
Сейчасмы изменим раздел томовчасти MediaWiki docker-compose.yml впереопределить конфигурацию apache2файл для сайта MediaWiki.
mediawiki:
image: mediawiki
restart: unless-stopped
hostname: mediawiki
ports:
- "8080:80"
links:
- database
volumes:
- ./images:/var/www/html/images
- ./wiki/LocalSettings.php:/var/www/html/LocalSettings.php
- ./apache2/000-default.conf:/etc/apache2/sites-enabled/000-default.conf
networks:
- wiki
решение2
Единственным стабильным решением этой проблемы является установка корневого URL-адреса.
Я искал «корневой URL mediawiki», и второе совпадение указало наhttps://www.mediawiki.org/wiki/Тема:Ry90289pdqa86yrd, где первый ответ рассказывает, как установить корневой URL в MediaWiki:
URL вашей вики должен быть установлен в LocalSettings.php (как, например, $wgLogo, который также установлен в этом файле), и вы можете изменить его, установив $wgServer на другое значение. Это заставит MediaWiki выводить URL, начинающиеся с нужного вам домена.