도커 컨테이너와 특정 중첩 위치가 있는 nginx 역방향 프록시

도커 컨테이너와 특정 중첩 위치가 있는 nginx 역방향 프록시

특정 위치에 영구적으로 상주하는 도커 컨테이너의 여러 앱을 사용하여 nginx를 역방향 프록시로 설정하고 싶습니다. 예:

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

특히, 저는 다음을 사용하고 싶습니다.미디어위키 도커 이미지다른 앱 옆에 이것은 내 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미디어위키 컨테이너와 다른 앱을 프록시할 수 있지만 특정 링크와 리소스가 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;
    }
}

<a href="/mw-config/index.php">complete the installation</a>이 동작의 이유는 요청을 중첩된 위치 대신 루트 위치로 전달하는 등의 관계형 URL 때문인 것 같습니다 . 나는 rewrite(정규식 포함), 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을 구성할 수 없기 때문에 http_referer. 이는 https://sub.example.com/wiki/위에 언급된 링크 및 해당 링크에 대한 모든 초기 GET 요청에 대해 작동합니다 .

그러나 을 클릭하면 <a href="/mw-config/index.php">...추가 index.php요청이 발생하여 다시 로 연결됩니다 https://sub.example.com/. URL이 다시 작성되지 않고 리퍼러가 이라고 말하므로 https://sub.example.com/mw-config/index.php이러한 요청은 500을 반환합니다.

내 질문은: 내 앱이 해당 위치에 영구적으로 상주하도록 하려면 이 동작을 어떻게 수정해야 합니까? 안타깝게도 지금은 하위 도메인을 변경할 수 없습니다.

도움을 주시면 감사하겠습니다!

편집하다:


비슷한 문제가 발생할 수 있는 다른 여러 앱을 사용하고 싶기 때문에 보다 일반적인 해결책을 찾고 싶습니다. 어떤 경우에는 기본 URL을 제어할 수 없습니다.

답변1

이것이 작동하려면 동일한 페이지에 있어야 하는 몇 가지 일이 있습니다.

  1. 엔진엑스구성: 경로 기반 라우팅, 역방향 프록시
    • 나는 당신의 구성을 시도했고나는 당신의 구성이 정확하다고 생각합니다
  2. 아파치2구성: URI를 파일 경로 및 스크립트에 올바르게 매핑합니다.
    • 지시문을 사용하여 내부 파일 경로를 올바르게 AliasMatch "^/wiki(.*)" "/var/www/html/$1"제거 하고 매핑합니다./wiki
  3. 미디어위키설정: 링크를 역방향 프록시할 위치를 알 수 /wiki있도록 경로를 추가한 다음 제거하고 올바른 내부 파일 경로를 사용할 수 있습니다. NginxApache2/wiki
    • MediaWiki 설정을 실행한 후 생성된 파일 $wgScriptPath = "/wiki";에 설정하고 해당 파일을LocalSettings.phpdocker-compose.yml
  4. 도커 작성mediawiki: 수정된 로컬 파일을 Docker 컨테이너 에 마운트하여 변경 사항을 유지합니다.

아파치2

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>

미디어위키 설정:

LocalSettings.php이는 변경해야 하는 파일 의 일부일 뿐입니다 . 여기에 전체 기본값을 포함하기에는 약간 큽니다. LocalSettings.phpdocker-compose를 사용하여 docker 컨테이너에 탑재하려는 로컬 복사본이 이미 있는 것 같으니 $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-compose.yml의 MediaWiki 부분을apache2 구성을 재정의미디어위키 사이트용 파일입니다.

  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을 설정하는 것이 이 문제에 대한 유일하고 안정적인 해결책입니다.

"mediawiki 루트 URL"을 검색했는데 두 번째 히트가 다음을 가리켰습니다.https://www.mediawiki.org/wiki/Topic:Ry90289pdqa86yrd, 첫 번째 응답은 MediaWiki에서 루트 URL을 설정하는 방법을 알려줍니다.

위키에 대한 URL은 LocalSettings.php에 설정되어야 하며(예: 해당 파일에 설정된 $wgLogo와 마찬가지로) $wgServer를 다른 값으로 설정하여 변경할 수 있습니다. 그러면 원하는 도메인으로 시작하는 MediaWiki 출력 URL이 만들어집니다.

관련 정보