
Me gustaría configurar nginx como un proxy inverso con múltiples aplicaciones en contenedores acoplables que residen permanentemente en ubicaciones específicas, por ejemplo:
https://sub.example.com/wiki
https://sub.example.com/app1
https://sub.example.com/app2
En particular, quiero usar elimagen acoplable de mediawikijunto a otras aplicaciones. Este es mi 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:
El problema al que me enfrento es que con lo siguiente default.conf
, puedo hacer proxy del contenedor mediawiki y de otras aplicaciones, pero ciertos enlaces y recursos devuelven 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;
}
}
Sospecho que el motivo de este comportamiento se debe a que las URL relacionales, como <a href="/mw-config/index.php">complete the installation</a>
, dirigen las solicitudes a la ubicación raíz en lugar de a la anidada. He probado muchas cosas, como rewrite
(incluidas expresiones regulares), sub_filter
y proxy_redirect
métodos proxy_set_header
, pero lo mejor que se me ocurrió es:
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;
}
Como no puedo configurar una URL base para mediawiki (todavía), intenté enviar solicitudes entrantes en la ubicación raíz dependiendo del archivo http_referer
. Esto funciona para todas las solicitudes GET iniciales realizadas en https://sub.example.com/wiki/
y también para el enlace mencionado anteriormente.
Sin embargo, después de hacer clic en <a href="/mw-config/index.php">...
, index.php
realiza más solicitudes, nuevamente dirigidas a https://sub.example.com/
. Dado que la URL no se reescribe y el referente dice https://sub.example.com/mw-config/index.php
, estas solicitudes devuelven 500.
Mi pregunta es: ¿Cómo puedo solucionar este comportamiento para que mis aplicaciones residan permanentemente en su ubicación respectiva? Lamentablemente no puedo cambiar el subdominio en este momento.
¡Cualquier ayuda es apreciada!
Editar:
Como quiero utilizar muchas otras aplicaciones que pueden encontrar problemas similares, me gustaría encontrar una solución más general. En algunos casos no tengo control sobre la URL base.
Respuesta1
Aquí suceden algunas cosas que debemos coordinar para que esto funcione:
- NGINXconfiguración: enrutamiento basado en ruta, proxy inverso
- Probé tu configuración yCreo que tu configuración es correcta.
- apache2configuración: asigne correctamente URI a rutas de archivos y scripts
- Utilice una directiva
AliasMatch "^/wiki(.*)" "/var/www/html/$1"
para eliminar/wiki
y asignar correctamente las rutas de archivos internas
- Utilice una directiva
- MediosWikiconfiguración: agregue la
/wiki
ruta paraNginx
saber dónde invertir el proxy de los enlaces y luegoApache2
pueda eliminarlos/wiki
y usar las rutas de archivos internas correctas.- Establezca
$wgScriptPath = "/wiki";
elLocalSettings.php
archivo creado después de ejecutar la configuración de MediaWiki y anule ese archivo en sudocker-compose.yml
- Establezca
- Composición acoplable: persista esos cambios montando nuestros archivos locales modificados en el
mediawiki
contenedor acoplable
apache2
Vamos a agregar AliasMatch "^/wiki(.*)" "/var/www/html/$1"
a la configuración en /etc/apache2/sites-enabled/000-default.conf
. También necesitarás anular el contenido de este archivo en tudocker-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>
Configuración de MediaWiki:
Este es sólo un fragmento del LocalSettings.php
archivo que debe modificarse. Es un poco grande incluir todo el valor predeterminado aquí. Parece que ya tiene una copia local LocalSettings.php
que está montando en el contenedor de la ventana acoplable usando docker-compose, así que simplemente modifique la $wgScriptPath
variable allí y reinicie su contenedor.
## 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";
Composición acoplable
AhoraModificaremos la sección de volúmenes.de la pieza de MediaWiki de docker-compose.yml paraanular la configuración de apache2archivo para el sitio 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
Respuesta2
Configurar la URL raíz es la única solución estable a este problema.
Busqué "URL raíz de mediawiki" y el segundo resultado señalóhttps://www.mediawiki.org/wiki/Topic:Ry90289pdqa86yrd, donde la primera respuesta indica cómo configurar la URL raíz en MediaWiki:
La URL de su wiki debe estar configurada en LocalSettings.php (al igual que, por ejemplo, $wgLogo, que también está configurada en ese archivo) y puede cambiarla configurando $wgServer con otro valor. Esto hará que MediaWiki genere URL que comiencen con el dominio que desea.