I would like to set up nginx as a reverse proxy with multiple apps on docker containers permanently residing under specific locations, e.g.:
https://sub.example.com/wiki
https://sub.example.com/app1
https://sub.example.com/app2
In particular, I want to use the mediawiki docker image next to other apps. This is my 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:
The problem I am facing is that with the following default.conf
, I am able to proxy the mediawiki container as well as the other apps, but certain links and resources return 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;
}
}
I suspect the reason for this behavior is due to relational URLs, such as <a href="/mw-config/index.php">complete the installation</a>
, directing requests to the root location instead of the nested one. I have tried a lot of things, such as rewrite
(incl. regex), sub_filter
, proxy_redirect
and proxy_set_header
methods, but the best I have come up with is:
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;
}
Since I am not able to configure a baseurl for the mediawiki (yet), I tried to proxy incoming requests at the root location depending on the http_referer
. This works for all inital GET requests made at https://sub.example.com/wiki/
and also for the link mentioned above.
However, after clicking <a href="/mw-config/index.php">...
, index.php
makes further requests - again directed to https://sub.example.com/
. Since the URL is not rewritten and the referer says https://sub.example.com/mw-config/index.php
, these requests return 500.
My question is: How can I fix this behaviour to make my apps permanently reside at their respective location? I can unfortunately not change the subdomain at this point.
Any help is appreciated!
Edit:
Since I want to use multiple other apps that may encounter similar problems, I would like to come up with a more general solution. In some cases I do not have control over the base URL.