在我访问过的几乎每个与 Nginx 相关的网页中,都说如果要从 Nginx 反向代理访问 docker 容器,则需要 VIRTUAL_HOST 环境变量。
然而,我发现情况似乎并非如此。例如,在这docker-compose 文件中,只有 1 个服务指定了 VIRTUAL_HOST,即“web”服务。当我测试使用此 docker-compose 文件的系统并检查 Wireshark 时,我注意到 Nginx 设法与“jobs”服务进行通信,尽管它没有 VIRTUAL_HOST 变量。这是怎么可能的?
答案1
首先,Nginx 中没有“虚拟主机”的概念。这些被称为“服务器”块,因为您可以指定监听不同主机名的不同服务器。VIRTURAL_HOST
环境变量是 Docker 特有的概念——实际上,它只是nginx-proxy
Docker 服务。
使用 Nginx 时外部Docker 环境,您可以将其配置为监听特定主机名,然后将传入的请求转发到正在运行的 Docker 容器公开的端口。例如,您的服务器块可能如下所示:
server {
listen 80;
server_name <DOMAIN>; # Replace this with your site's domain.
root /var/www/<DOMAIN>;
try_files $uri @docker;
location @docker {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded_Proto $scheme;
proxy_redirect off;
proxy_pass http://127.0.0.1:3000;
}
}
在这里,系统上运行的 Nginx 会将请求转发到公开端口 3000 的 Docker 容器。根据您的设置方式,您当然可以同时代理多个容器。
另一个版本运行的是 Nginx里面Docker 环境(通常在 Docker Compose 中),这样 Nginx 就可以知道其他 Docker 容器的存在,并从变量中推断出来VIRTUAL_HOST
。正如您在第二个链接中提到的那样,您添加了:
代理会查找
VIRTUAL_HOST
启用了变量的容器。(…)代理将看到人 A 已请求 blog.example.com,并将他们的请求路由(或代理!)到正确的容器。
这意味着,您无需明确指定 IP 地址和端口(如上面的 3000),而是可以直接将容器链接nginx-proxy
到应用程序容器。有关详细信息,请阅读本自述文件。