不同的域具有不同的 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 添加一个新的开放端口。我不想为每个站点添加或更改端口。
现在:
- example-a.com:2999 -> example-a phpmyadmin 登录页面
- examlpe-b.com:2998 -> example-b phpymadmin 登录页面
有没有办法通过域地址将我定向到适当的容器?
- 示例-a.com:2999 -> 示例-a phpmyadmin 登录页面
- examlpe-b.com:2999 -> example-b phpymadmin 登录页面
我的 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
容器配置为侦听端口 80
和 443
- 您想将 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
,它将转到 80
或 443
(取决于他们使用的是 http
还是 https
)。然后,nginx
将分析请求,并将其发送到正确的容器。为此,A 和 B 监听什么端口并不重要,因为在外界看来,他们正在监听 80
/443
.
所以真正的答案是,虽然你不能将自定义端口与虚拟主机结合起来,也不能为多个容器使用相同的端口(除了 80
/443
),但你不会实际上 首先需要 自定义端口!如果您只是使用默认端口配置您的容器,用户可以同时使用 https://example-a.com
和 https://example-b.com
,它将 'just work'™
我有一个带有 nginx-proxy 容器的 VPS,我用 phpmyadmin 服务创建了一些 wordpress 网站。如果我想用这个定义创建另一个站点,我会遇到“相同端口”问题。 好的,我可以将端口更改为 2998,它工作正常,但我需要向我的 VPS 添加一个新的开放端口。我不想为每个站点添加或更改端口。
现在:
- example-a.com:2999 -> example-a phpmyadmin 登录页面
- examlpe-b.com:2998 -> example-b phpymadmin 登录页面
有没有办法通过域地址将我定向到适当的容器?
- 示例-a.com:2999 -> 示例-a phpmyadmin 登录页面
- examlpe-b.com:2999 -> example-b phpymadmin 登录页面
我的 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
容器配置为侦听端口80
和443
- 您想将 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
,它将转到 80
或 443
(取决于他们使用的是 http
还是 https
)。然后,nginx
将分析请求,并将其发送到正确的容器。为此,A 和 B 监听什么端口并不重要,因为在外界看来,他们正在监听 80
/443
.
所以真正的答案是,虽然你不能将自定义端口与虚拟主机结合起来,也不能为多个容器使用相同的端口(除了 80
/443
),但你不会实际上 首先需要 自定义端口!如果您只是使用默认端口配置您的容器,用户可以同时使用 https://example-a.com
和 https://example-b.com
,它将 'just work'™