Nginx-Reverse-Proxy mit Docker-Containern und bestimmten verschachtelten Standorten

Nginx-Reverse-Proxy mit Docker-Containern und bestimmten verschachtelten Standorten

Ich möchte Nginx als Reverse-Proxy mit mehreren Apps auf Docker-Containern einrichten, die dauerhaft an bestimmten Standorten gespeichert sind, z. B.:

https://sub.example.com/wiki
https://sub.example.com/app1
https://sub.example.com/app2

Insbesondere möchte ich dieDocker-Image von MediaWikineben anderen Apps. Dies ist meine 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:

Mein Problem besteht darin default.conf, dass ich mit Folgendem zwar den MediaWiki-Container und die anderen Apps als Proxy verwenden kann, bestimmte Links und Ressourcen jedoch den Fehler 404 zurückgeben.

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;
    }
}

Ich vermute, dass der Grund für dieses Verhalten relationale URLs sind, wie z. B. <a href="/mw-config/index.php">complete the installation</a>, die Anfragen an den Stammspeicherort statt an den verschachtelten Speicherort weiterleiten. Ich habe vieles ausprobiert, wie z. B. rewrite(inkl. Regex), sub_filter, proxy_redirectund proxy_set_headerMethoden, aber das Beste, was mir eingefallen ist, ist:

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;
}

Da ich (noch) keine Basis-URL für das Mediawiki konfigurieren kann, habe ich versucht, eingehende Anfragen je nach an den Stammspeicherort weiterzuleiten http_referer. Dies funktioniert für alle anfänglichen GET-Anfragen, die an und gestellt werden https://sub.example.com/wiki/, auch für den oben genannten Link.

<a href="/mw-config/index.php">...Nach dem Klicken auf stellt jedoch index.phpweitere Anfragen - wiederum weitergeleitet an https://sub.example.com/. Da die URL nicht umgeschrieben wird und der Referrer lautet https://sub.example.com/mw-config/index.php, geben diese Anfragen 500 zurück.

Meine Frage ist nun: Wie kann ich dieses Verhalten beheben, damit meine Apps dauerhaft am jeweiligen Standort verbleiben? Die Subdomain kann ich an dieser Stelle leider nicht ändern.

Jede Hilfe ist willkommen!

Bearbeiten:


Da ich mehrere andere Apps verwenden möchte, bei denen möglicherweise ähnliche Probleme auftreten, möchte ich eine allgemeinere Lösung finden. In einigen Fällen habe ich keine Kontrolle über die Basis-URL.

Antwort1

Hier passieren einige Dinge, und damit das funktioniert, müssen wir uns einig werden:

  1. NGINXKonfiguration: pfadbasiertes Routing, Reverse-Proxy
    • Ich habe Ihre Konfiguration ausprobiert undIch glaube, Ihre Konfiguration ist korrekt
  2. Apache2Konfiguration: URI korrekt auf Dateipfade und Skripte abbilden
    • Verwenden Sie eine Direktive AliasMatch "^/wiki(.*)" "/var/www/html/$1", um die /wikiinternen Dateipfade korrekt zu entfernen und zuzuordnen.
  3. MediaWikiEinstellungen: Fügen Sie den /wikiPfad hinzu, damit Nginxbekannt ist, wohin die Links per Reverse-Proxy gesendet werden sollen. Anschließend Apache2können die Links entfernt /wikiund die richtigen internen Dateipfade verwendet werden.
    • Setzen Sie $wgScriptPath = "/wiki";die LocalSettings.phpDatei ein, die nach dem Ausführen des MediaWiki-Setups erstellt wurde, und überschreiben Sie diese Datei in Ihremdocker-compose.yml
  4. Docker Compose: Behalten Sie diese Änderungen bei, indem Sie unsere geänderten lokalen Dateien in den mediawikiDocker-Container einbinden

Apache2

Wir werden AliasMatch "^/wiki(.*)" "/var/www/html/$1"die Konfiguration unter ergänzen /etc/apache2/sites-enabled/000-default.conf. Sie müssen außerdem den Inhalt dieser Datei in Ihremdocker-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-Einstellungen:

Dies ist nur ein Ausschnitt der LocalSettings.phpDatei, die geändert werden muss. Es ist ein bisschen zu groß, um hier die gesamte Standardeinstellung einzuschließen. Es sieht so aus, als hätten Sie bereits eine lokale Kopie davon, LocalSettings.phpdie Sie mit Docker-Compose in den Docker-Container einbinden. Ändern Sie also einfach die $wgScriptPathVariable dort und starten Sie Ihren Container neu.

## 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 Compose

JetztWir werden den Abschnitt „Volumina“ änderndes MediaWiki-Teils der docker-compose.yml zuüberschreibe die Apache2-KonfigurationDatei für die MediaWiki-Site.

  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

Antwort2

Das Festlegen der Stamm-URL ist die einzige stabile Lösung für dieses Problem.

Ich suchte nach "MediaWiki-Stamm-URL" und der zweite Treffer zeigte aufhttps://www.mediawiki.org/wiki/Topic:Ry90289pdqa86yrd, wobei die erste Antwort erklärt, wie die Stamm-URL in MediaWiki festgelegt wird:

Die URL zu Ihrem Wiki muss in LocalSettings.php festgelegt werden (wie z. B. $wgLogo, das ebenfalls in dieser Datei festgelegt ist) und Sie können sie ändern, indem Sie $wgServer auf einen anderen Wert setzen. Dadurch gibt MediaWiki URLs aus, die mit der gewünschten Domäne beginnen.

verwandte Informationen