【发布时间】:2021-06-23 09:38:39
【问题描述】:
我正在尝试根据 [本教程][1] 建立一个基本的反向代理来处理多个网站,但将其调整为使用 单个 docker-compose 文件 和 proxy_pass 到 上游容器。这似乎是最简洁的方式,因为它适用于我的学习/测试服务器,我将经常启动和停止容器。在开始添加更复杂的应用程序容器之前,我想将其锁定。我不确定我应该在配置的哪个部分转发端口,因为网上的大多数问题和教程都没有使用上游容器。
编辑 - 默认服务器未在 443 上侦听,修复此问题消除了一个混乱。现在我只从x.x.x.x/ 获得预期的 index.html,从x.x.x.x/site1 或x.x.x.x/site2(或其他任何东西)获得反向代理自定义 404 页面
根据我的阅读,只要容器是链接的(在同一个 docker 网络上),端口就由 docker 在内部处理,而且只要容器以docker-compose up
我已经尝试在 docker-compose.yml 中将自定义端口转发到容器
ports:
- 8081:443
这在 nginx default.conf
upstream docker-site1 {
server website1-container:8081;
}
但这给了我502 Bad Gateway
我正在使用命名容器和外部网络来保持名称静态,以保持容器间网络与主机分离,并在这方面利用 Docker 功能。
我现在已经花了两天时间,我真的需要一些方向来避免绕圈子!
编辑-仍在转圈。感谢 lmsec 更新了 default.conf,并且还在 docker-compose.yml 的卷路径中添加了 /site1
我的 docker-compose.yml(在顶级目录中)已编辑 - 我最好的工作配置
version: '3.6'
services:
proxy:
build: ./proxy/
container_name: reverse-proxy
hostname: reverse-proxy
networks:
- public
- website1
- website2
ports:
- 80:80
- 443:443
site1_app:
build:
./site1/
volumes:
- ./site1/html:/usr/share/nginx/html/site1
container_name: website1-container
hostname: website1-container
networks:
- website1
site2_app:
build:
./site2/
volumes:
- ./site2/html:/usr/share/nginx/html/site2
container_name: website2-container
hostname: website2-container
networks:
- website2
networks:
public:
external: true
website1:
external: true
website2:
external: true
./proxy/中的Dockerfile
FROM nginx:1.20-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ./backend-not-found.html /var/www/html/backend-not-found.html
COPY ./index.html /var/www/html/index.html
# Proxy and SSL configurations
COPY ./includes/ /etc/nginx/includes/
# Proxy SSL certificates
COPY ./ssl/ /etc/ssl/certs/nginx/
网站 Dockerfiles 仅包含 FROM nginx:1.20-alpine
./proxy/ 中的 default.conf 已编辑 - 我最常用的配置,不链接 JS、CSS、图像
# Default
server {
# listen on port 80 (http)
listen 80 default_server;
server_name _;
location / {
# redirect any requests to the same URL but on https
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2 default_server;
server_name _;
root /var/www/html;
charset UTF-8;
# Path for SSL config/key/certificate
ssl_certificate /etc/ssl/certs/nginx/proxy.crt;
ssl_certificate_key /etc/ssl/certs/nginx/proxy.key;
include /etc/nginx/includes/ssl.conf;
error_page 404 /backend-not-found.html;
location = /backend-not-found.html {
allow all;
}
location / {
index index.html;
}
location /site1 {
include /etc/nginx/includes/proxy.conf;
proxy_pass http://website1-container;
}
location /site2 {
include /etc/nginx/includes/proxy.conf;
proxy_pass http://website2-container;
}
access_log off;
log_not_found off;
error_log /var/log/nginx/error.log error;
}
./proxy/includes/中的proxy.conf
proxy_set_header Host $host;
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 $scheme;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_intercept_errors on;
每个网站容器都有自己的网络,它与代理容器共享。
{
"Name": "website1",
"Id": "9477470a8689d08776b38c4315882caff75573b7244f77091aa5e5438804ce36",
"Created": "2021-06-21T02:52:25.402118801Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.160.0/20",
"Gateway": "192.168.160.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"7c1a8b62864642afd5366ef88d762e4c5450eee02acb8c3f1890444b59379340": {
"Name": "website1-container",
"EndpointID": "f04d96343737574ca869270954461774f731851b781120119c21e02c0aa9968e",
"MacAddress": "02:42:c0:a8:a0:02",
"IPv4Address": "192.168.160.2/20",
"IPv6Address": ""
},
"a88326952fb5f25f9084eb038f22f56b7331032a5ba71848ea6ada677a2ed998": {
"Name": "reverse-proxy",
"EndpointID": "b0c97c7f8dfe0febddbd6668481a009cce0c4f20dae3c3d3280dad0069c90394",
"MacAddress": "02:42:c0:a8:a0:03",
"IPv4Address": "192.168.160.3/20",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
我可以通过这个网络访问网站容器,甚至可以通过 curl 获取 index.html:
sudo docker exec reverse-proxy curl 192.168.160.2/site1/index.html
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0<!DOCTYPE html>
<html>
<head>
<title>Site 1</title>
</head>
<body>
<h1>This is a sample "site1" response</h1>
</body>
</html>
100 142 100 142 0 0 20285 0 --:--:-- --:--:-- --:--:-- 23666
我将此问题标记为已关闭。我得出的结论是,最新版本的 docker 在使用 proxy_pass 到 docker 容器时不需要任何特殊的端口转发,尽管如果需要,可以在 docker-compose 和 nginx default.conf 中完成 - 正如 lmsec 回答所解释的那样。
【问题讨论】:
标签: docker nginx docker-compose reverse-proxy