不同的域具有不同的 phpmyadmin 服务和 "same port" 问题(nginx 反向代理,docker)

Different domain with different phpmyadmin service and the "same port" problem (nginx reverse proxy, docker)

我有一个带有 nginx-proxy 容器的 VPS,我用 phpmyadmin 服务创建了一些 wordpress 网站。如果我想用这个定义创建另一个站点,我会遇到“相同端口”问题。 好的,我可以将端口更改为 2998,它工作正常,但我需要向我的 VPS 添加一个新的开放端口。我不想为每个站点添加或更改端口。

现在:

有没有办法通过域地址将我定向到适当的容器?

我的 nginx 代理定义

networks:
  nginx-proxy:
    external: false
    name: nginx-reverse-proxy
  default:
    name: nginx-reverse-proxy-default

version: '2'
services:

  nginx-proxy:
    build:
      context: .nginx-proxy
      dockerfile: Dockerfile
    container_name: nginx-proxy
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - .nginx-proxy/certs:/etc/nginx/certs:ro
      - .nginx-proxy/vhost.d:/etc/nginx/vhost.d
      - .nginx-proxy/dhparam:/etc/nginx/dhparam
      - /usr/share/nginx/html
    networks:
      - nginx-proxy

  nginx-proxy-acme:
    image: nginxproxy/acme-companion
    container_name: nginx-proxy-acme
    restart: always
    volumes_from:
     - nginx-proxy
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock:ro
     - .nginx-proxy/certs:/etc/nginx/certs:rw
     - .nginx-proxy-acme/acme:/etc/acme.sh

这是我的 wordpress 站点定义

version: "3.9"

volumes:
  database_volume: {}

x-logging:
  &default-logging
  driver: json-file
  options:
    max-size: '1m'
    max-file: '3'
    
services:

  web:
    build:
      context: ./.docker
      dockerfile: Dockerfile_web
    container_name: test_web
    ports:
      - '3000:80'
    volumes:
      - ./wp:/var/www
    depends_on:
      - database
      - php
    restart: always
    logging: *default-logging

  database:
    image: mariadb:latest
    container_name: test_database
    environment:
      MYSQL_USER: wp
      MYSQL_PASSWORD: wp
      MYSQL_DATABASE: wp
      MYSQL_ROOT_PASSWORD: wp
    volumes:
      - ./database_volume:/var/lib/mysql
    expose:
      - 3306
    restart: always
    logging: *default-logging
  
  php:
    build:
      context: ./.docker
      dockerfile: Dockerfile_php
    container_name: test_php
    working_dir: /var/www/
    volumes:
      - ./wordpress:/var/www
    restart: always
    logging: *default-logging
  
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: test_phpmyadmin
    links:
      - database:db
    ports:
      - '2999:80'
    restart: always
    logging: *default-logging

你想要的是不可能的,但你可能实际上并不想要它。一旦您仔细考虑要配置的内容,以及如果用户转到 URL:

会发生什么,就会变得很清楚
  • 您已将 example-a.com 配置为指向您的 IP
  • 您已将 example-b.com 配置为指向您的 IP
  • 您已将 nginx-proxy 容器配置为侦听端口 80443
  • 您想将 WordPress 容器配置为同时侦听端口 2999
  • 你,或者更确切地说 acme-companion,已经配置了你的 nginx 容器来转发 HTTP 请求,要求主机 example-a.com 转到容器,例如 A 端口 2999,并请求 example-b.com 到端口为 2999
  • 的容器 B

现在,您可以立即看到您有两件东西试图在端口 2999 的同一网络接口上进行侦听 - 这是行不通的,它不能,因为谁来处理选择在解析请求以找出它想要的主机之前启动传入请求?容器 A 无法接受请求,如果它是针对 B 的,则将请求移交 - A 不了解 B。

因此,如果您考虑用户向 example-a.com:2999 发送请求,实际发生的情况是请求发送至 <yourip>:2999,就像用户发送至 example-b.com:2999 一样,它最终会转到 <yourip>:2999.

如何解决这个问题?通过让第三个容器 C 接受用户请求,查看请求,并根据他们是想要容器 A 还是 B,将请求移交给 A 或 B。

最棒的是:你已经拥有了!容器 C 实际上是您的 nginx 容器,它正在侦听端口 80/443。因此,如果您的用户在未提供端口的情况下转到 example-a.com,它将转到 80443(取决于他们使用的是 http 还是 https)。然后,nginx 将分析请求,并将其发送到正确的容器。为此,A 和 B 监听什么端口并不重要,因为在外界看来,他们正在监听 80/443.

所以真正的答案是,虽然你不能将自定义端口与虚拟主机结合起来,也不能为多个容器使用相同的端口(除了 80/443),但你不会实际上 首先需要 自定义端口!如果您只是使用默认端口配置您的容器,用户可以同时使用 https://example-a.comhttps://example-b.com,它将 'just work'™