Nginx 反向代理在刷新时加载不同的站点

Nginx 反向代理在刷新时加载不同的站点

我想按照本教程使用 nginx 反向代理在一台服务器上托管多个网站 https://www.datanovia.com/en/lessons/how-host-multiple-https-websites-on-one-server/

Nginx 代理和每个网站都是用 Docker 单独启动的。但每次我重新加载其中一个网站时,它都会加载其他网站的内容。例如:

  • 首次加载websiteone.tk,加载website ONE的内容。

  • 刷新 websiteone.tk ,加载网站 TWO 的内容

  • 再次刷新 websiteone.tk,加载网站 THREE 的内容

  • 首次加载 websitetwo.tk,加载网站 TWO 内容

  • 刷新 websitetwo.tk ,加载网站 THREE 的内容。

我是 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 如下。

Websiteone 的工作目录是 /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:

相关内容