如何使用nginx将请求重定向到适当的网站而不指定其端口?

a7qyws3x  于 2023-03-01  发布在  Nginx
关注(0)|答案(1)|浏览(224)

我有2个网站(使用docker,部署在一个数字海洋微滴)。我目前能够访问这两个网站分别通过在docker组成文件中指定的端口如下:

ports:
      - "3001:443"

现在的问题是,我希望用户不必手动输入端口(比如自动将请求重定向到端口80/443),但由于我的droplet上运行的是nginx,所以我无法使用端口80来处理任何可能通过端口80进入我网站的请求,而且我只能有一个网站使用443,当我调出另一个网站时,我得到一个错误,因为443被另一个网站使用。
所以简而言之,我想直接通过http/https访问这两个网站,只是通过他们的域名,但不确定如何正确地做到这一点。
这是我的droplet上的nginx conf,它监听每个网站的请求。

server {
    listen 443;
    server_name example.com;

    location ~ ^/(api) {
            proxy_pass http://example-backend:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_cache_bypass $http_upgrade;
    }
}

server {
    listen 443;
    server_name demo.com;

    location ~ ^/(api) {
            proxy_pass http://demo-backend:9090;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_cache_bypass $http_upgrade;
    }
}

这是我的一个网站的docker合成文件

version: '3.7'
services:
  example-backend:
    build:
      context: ./backend
    ports:
      - "8080:8080"
    restart: always
    environment:
      SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL}
      SPRING_DATASOURCE_USERNAME: ${MYSQL_DB_USER}
      SPRING_DATASOURCE_PASSWORD: ${MYSQL_DB_PASSWORD}
      SPRING_JPA_HIBERNATE_DDL-AUTO: update
      SPRING_MAIL_USERNAME: ${SPRING_MAIL_USERNAME}
      SPRING_MAIL_PASSWORD: ${SPRING_MAIL_PASSWORD}

  // This is an NGINX container with the static content placed inside after building
  example-frontend:
    build:
      context: ./frontend
    ports:
      - "3001:443"
    restart: always
    depends_on:
      - example-backend
    volumes:
      - ./web/conf.d:/etc/nginx/conf.d
      - ./web/dhparam:/etc/nginx/dhparam
      - ./web/certbot/data:/usr/share/nginx/html/letsencrypt
      - ./web/certbot/conf/:/etc/nginx/ssl

最后,这个特定网站的nginx conf文件

server {
    listen 80;
    server_name example.com;
    location ~ /.well-known/acme-challenge/ {
        allow all;
        root /usr/share/nginx/html/letsencrypt;
    }

    location / {
        return 301 https://example.com:3001$request_uri;
    }
}

server {
     listen 443 ssl;
     server_name example.com;

     server_tokens off;
     ssl_certificate /etc/nginx/ssl/live/example.com/fullchain.pem;
     ssl_certificate_key /etc/nginx/ssl/live/example.com/privkey.pem;
     ssl_dhparam /etc/nginx/dhparam/dhparam-2048.pem;

    location / {
        root /usr/share/nginx/html/;
        try_files $uri /index.html;
    }

    location /api/ {
        proxy_pass http://example-backend:8080;
    }

}

所以现在我可以在打开容器后访问网站,只是在https://example.com:3001上,http请求(使用端口80)不起作用,因为我已经在droplet/vps中的端口80上运行了nginx。
第二个网站也是如此,只是我使用了不同的端口,而不是3001

h5qlskok

h5qlskok1#

嘿,这是因为你所有的服务器块共享相同的server_name,我想。
你可以使用nginx转发端口80和433上的http请求,将其重定向到你的container,为此,nginx使用http请求的Host报头,使其与server_name匹配。
你应该试试这样的方法:

server {
     listen 443 ssl;
     listen 80;
     server_name example.com;

     server_tokens off;
     ssl_certificate /etc/nginx/ssl/live/example.com/fullchain.pem;
     ssl_certificate_key /etc/nginx/ssl/live/example.com/privkey.pem;
     ssl_dhparam /etc/nginx/dhparam/dhparam-2048.pem;

    if ($scheme != 'https') {
      return 301 https://$host$request_uri;
    }

    location ~ /.well-known/acme-challenge/ {
        allow all;
        root /usr/share/nginx/html/letsencrypt;
    }

    location / {
        proxy_pass http://example.com:3001;
    }

    location /api/ {
        proxy_pass http://example-backend:8080;
    }
}

我建议您尝试使用nanocl来部署容器!
如果你需要进一步的帮助,你可以添加我的不和谐,你可以在我的个人资料中找到它

相关问题