Nginx 역방향 프록시는 새로 고칠 때 다른 사이트를 로드합니다.

Nginx 역방향 프록시는 새로 고칠 때 다른 사이트를 로드합니다.

이 튜토리얼에 따라 nginx 역방향 프록시를 사용하여 하나의 서버에서 여러 웹사이트를 호스팅하고 싶습니다. https://www.datanovia.com/en/lessons/how-host-multiple-https-websites-on-one-server/

Nginx 프록시와 각 웹사이트는 Docker를 사용하여 별도로 시작됩니다. 하지만 웹사이트 중 하나를 다시 로드할 때마다 다른 웹사이트의 콘텐츠가 로드됩니다. 예를 들어:

  • websiteone.tk를 처음 로드하고, 웹사이트 ONE의 콘텐츠를 로드했습니다.

  • websiteone.tk 새로 고침, 로드된 웹사이트 TWO의 콘텐츠

  • websiteone.tk를 다시 새로 고치고 웹사이트 THREE의 콘텐츠를 로드하세요.

  • websitetwo.tk를 처음 로드하고, 웹사이트 TWO 콘텐츠를 로드했습니다.

  • websitetwo.tk , 로드된 웹사이트 3개 콘텐츠를 새로 고칩니다.

저는 nginx와 docker 모두의 초보자입니다. nginx나 docker에서 문제가 발생하는지 알 수 없습니다. 누구든지 친절하게 조언해 주실 수 있나요? 매우 감사합니다.

nginx-proxy default.conf는 다음과 같습니다.

map $http_x_forwarded_proto $proxy_x_forwarded_proto {  default $http_x_forwarded_proto;
  ''      $scheme;
}
map $http_x_forwarded_port $proxy_x_forwarded_port {
  default $http_x_forwarded_port;
  ''      $server_port;
}
map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}
server_names_hash_bucket_size 128;
map $proxy_x_forwarded_proto $proxy_x_forwarded_ssl {
  default off;
  https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss t>log_format vhost '$host $remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 '"$upstream_addr"';
access_log off;
                ssl_protocols TLSv1.2 TLSv1.3;
                ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA3>                ssl_prefer_server_ciphers off;
error_log /dev/stderr;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Original-URI $request_uri;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
        server_name _; # This is just an invalid value which will never trigger on a real hostname.
        server_tokens off;
        listen 80;
        access_log /var/log/nginx/access.log vhost;
        return 503;
}
server {
        server_name _; # This is just an invalid value which will never trigger on a real hostname.
        server_tokens off;
        listen 443 ssl http2;
        access_log /var/log/nginx/access.log vhost;
        return 503;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        ssl_certificate /etc/nginx/certs/default.crt;
        ssl_certificate_key /etc/nginx/certs/default.key;
}


# websiteone.tk
upstream websiteone.tk {
## Can be connected with "nginx-proxy" network
# websiteonetk_my-app_1
server 192.168.32.8:80;
}

server {
        server_name websiteone.tk;
        listen 80 ;
        access_log /var/log/nginx/access.log vhost;
        # Do not HTTPS redirect Let'sEncrypt ACME challenge
        location ^~ /.well-known/acme-challenge/ {
                auth_basic off;
                auth_request off;
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
                break;
                      }
        location / {
                return 301 https://$host$request_uri;
        }
}
server {
        server_name websiteone.tk;
        listen 443 ssl http2 ;
        access_log /var/log/nginx/access.log vhost;
        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        ssl_certificate /etc/nginx/certs/websiteone.tk.crt;
        ssl_certificate_key /etc/nginx/certs/websiteone.tk.key;
        ssl_dhparam /etc/nginx/certs/websiteone.tk.dhparam.pem;
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/nginx/certs/websiteone.tk.chain.pem;
        add_header Strict-Transport-Security "max-age=31536000" always;
        include /etc/nginx/vhost.d/default;
        
        location / {
                        proxy_pass http://websiteone.tk;
        }
}


# websitetwo.tk
upstream websitetwo.tk {
## Can be connected with "nginx-proxy" network
# websitetwotk_my-app_1
server 192.168.32.13:80;
}

server {
        server_name websitetwo.tk;
        listen 80 ;
        access_log /var/log/nginx/access.log vhost;
        # Do not HTTPS redirect Let'sEncrypt ACME challenge
        location ^~ /.well-known/acme-challenge/ {
                auth_basic off;
                auth_request off;
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
                break;
        }
        location / {
                return 301 https://$host$request_uri;
        }
}
server {
        server_name websitetwo.tk;
        listen 443 ssl http2 ;
        access_log /var/log/nginx/access.log vhost;
        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        ssl_certificate /etc/nginx/certs/websitetwo.tk.crt;
        ssl_certificate_key /etc/nginx/certs/websitetwo.tk.key;
        ssl_dhparam /etc/nginx/certs/websitetwo.tk.dhparam.pem;
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/nginx/certs/websitetwo.tk.chain.pem;
        add_header Strict-Transport-Security "max-age=31536000" always;
        include /etc/nginx/vhost.d/default;
        
        location / {
                        proxy_pass http://websitetwo.tk;
        }
}

# websitethree.tk
upstream websitethree.tk {
## Can be connected with "nginx-proxy" network
# websitethreetk_my-app_1
server 192.168.32.3:80;
}
server {
        server_name websitethree.tk;
        listen 80 ;
        access_log /var/log/nginx/access.log vhost;
        # Do not HTTPS redirect Let'sEncrypt ACME challenge
        location ^~ /.well-known/acme-challenge/ {
                auth_basic off;
                auth_request off;
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
                break;
        }
        location / {
                return 301 https://$host$request_uri;
        }
}

server {
        server_name websitethree.tk;
        listen 443 ssl http2 ;
        access_log /var/log/nginx/access.log vhost;
        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        ssl_certificate /etc/nginx/certs/websitethree.tk.crt;
        ssl_certificate_key /etc/nginx/certs/websitethree.tk.key;
        ssl_dhparam /etc/nginx/certs/websitethree.tk.dhparam.pem;
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/nginx/certs/websitethree.tk.chain.pem;
        add_header Strict-Transport-Security "max-age=31536000" always;
        include /etc/nginx/vhost.d/default;
        location / {
                        proxy_pass http://websitethree.tk;
        }
}

nginx 프록시용 docker-compose는 다음과 같습니다.

version: '3.6'
services:
  nginx:
    image: nginx
    labels:
      com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./conf.d:/etc/nginx/conf.d
      - ./vhost.d:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:ro

  nginx-gen:
    image: jwilder/docker-gen
    command: -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    container_name: nginx-gen
    restart: unless-stopped
    volumes:
      - ./conf.d:/etc/nginx/conf.d
      - ./vhost.d:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro

  nginx-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-letsencrypt
    restart: unless-stopped
    volumes:
      - ./conf.d:/etc/nginx/conf.d
      - ./vhost.d:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      NGINX_DOCKER_GEN_CONTAINER: "nginx-gen"
      NGINX_PROXY_CONTAINER: "nginx"
networks:
  default:
    external:
      name: nginx-proxy

웹 사이트 중 하나에 대한 nginx default.conf는 다음과 같습니다.

server {
    root /application2;
    index index.php;

    location ~ \.php$ {
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        include fastcgi_params;
    }
}

웹 사이트 중 하나에 대한 docker-compose/yml은 다음과 같습니다.

웹사이트의 작업 디렉터리는 /application1입니다. Websitetwo 작업 디렉토리는 /application2입니다. 등

version: '3.1'
services:
    my-app:
        image: 'nginx:alpine'
        volumes:
            - '.:/application2'
            - './phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf'
        restart: always
        environment:
            - VIRTUAL_HOST=websitetwo.tk
            - VIRTUAL_PORT=80
            - LETSENCRYPT_HOST=websitetwo.tk
        expose:
            - 80
    mailhog:
        image: 'mailhog/mailhog:latest'
        ports:
            - '21001:8025'

    php-fpm:
        build: phpdocker/php-fpm
        working_dir: /application2
        volumes:
            - '.:/application2'
            - './phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/8.1/fpm/conf.d/99-overrides.ini'
networks:
    default:
        external:
            name: nginx-proxy

답변1

나는 그 답을 스스로 알아냈다. 같은 상황에 처한 사람이 있는 경우: 각 웹사이트의 docker-compose.yml에 대해 독립적인 네트워크를 설정해야 합니다.

먼저 nginx-proxy 네트워크 이름을 "default"에서 "proxy"로 변경합니다. 그런 다음 각 웹사이트에 대해 독립적인 네트워크(저는 "app"이라고 함)를 사용하여 컨테이너에 사용되는 각 서비스를 연결합니다. nginx 서비스도 프록시 네트워크를 사용해야 합니다.

웹사이트 docker-compose.yml:

version: '3.1'
services:
    my-app:
        networks: 
            - app
            - proxy
        image: 'nginx:alpine'
        volumes:
            - '.:/application2'
            - './phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf'
        restart: always
        environment:
            - VIRTUAL_HOST=websitetwo.tk
            - VIRTUAL_PORT=80
            - LETSENCRYPT_HOST=websitetwo.tk
        expose:
            - 80
    mailhog:
        networks: 
            - app
        image: 'mailhog/mailhog:latest'
        ports:
            - '21001:8025'

    php-fpm:
        networks: 
            - app
        build: phpdocker/php-fpm
        working_dir: /application2
        volumes:
            - '.:/application2'
            - './phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/8.1/fpm/conf.d/99-overrides.ini'
networks:
    proxy:
        external:
            name: nginx-proxy
    app:

관련 정보