如何将 Nginx 反向代理到本地托管(在具有 ssh 访问权限的服务器上)docker-compose
Posted
技术标签:
【中文标题】如何将 Nginx 反向代理到本地托管(在具有 ssh 访问权限的服务器上)docker-compose【英文标题】:How to Nginx reverse Proxy to a locally hosted (on a server with ssh access) docker-compose 【发布时间】:2022-01-19 00:12:07 【问题描述】:我不能完全确定如何在这种状态下让它工作,并且我喜欢如果可能的话,不必以不同的方式重做所有事情。
我有一个运行 nginx 服务器的数字海洋水滴以及一个 docker-compose,其中运行着客户端、服务器和数据库映像。
我的设想是通过 NGINX 保护流量并将其路由到服务器,该 NGINX 将代理到从 compose 公开的客户端应用程序。
so (internet) -> DNS(NGINX) -> 客户端 -> 服务器 -> DB
现在,当连接到 docker 中公开的 ip:port 时,这可以正常工作,因为我在 droplet 上使用 uwp 打开了它,很好的是它的 http 而不是 https。
我可以从 NGINX 代理到 ip:port,这很好,据我了解,这是从互联网到 nginx,再到互联网,再到客户端应用程序,但它可以工作。
现在我保护并设置了一个 DNS 并通过 NGINX 路由它,并收到“无效的主机标头”响应。
它是一个有角度的应用程序,所以我可以禁用主机头检查,它可能会很时髦,但我的下一步是关闭我暴露的端口,以便所有流量都必须通过 NGINX 代理,但我认为甚至代理也在使用 droplet 上的暴露端口来路由流量。
问:
我可以将来自 NGINX 的流量路由到服务器中的 docker-compose 地址,而不是使用服务器 ip 和端口组合来访问客户端站点,以便我可以关闭我暴露的端口吗?
或者,我是否只需要在 compose 中运行 NGINX 容器,以便我可以使用 compose 网络来管理流量?我不喜欢这样,因为我将不得不改变服务器上的东西,而且它对我来说有点脆弱。
TLDR:
工作 Internet -> http://ip:port(NGINX) -> http://ip:port docker-compose(客户端端口)== App Served! Internet -> http://ip:port docker-compose(客户端端口)== App Served 不工作 Internet -> https://DNS:port:80/443(NGINX) -> http://ip:port docker-compose (client port) == "Invalid Host Header" 想工作 Internet -> https://DNS:port:80/443(NGINX) -> 本地 compose not over http == App Servedsites-enabled # 这是我手动配置最多的地方 这个 conf 和许多其他 nginx 文件都在 etc/nginx 中
server
listen 80;
server_name <dns>.net;
index index.html index.htm index.nginx-debian.html;
location /
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header Connection 'upgrade';
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_pass http://<ip>:<port>;
listen 443 ssl;
ssl_certificate <server filepath>;
ssl_certificate_key <filepath>;
include <letsencrypt nginx conf path>;
ssl_dhparam <letsencrypt pem path>;
server
if ($host = <dns>.net)
return 301 https://$host$request_uri;
listen 80;
server_name <dns>.net;
listen 443 ssl default_server;
server_name _;
return 404;
码头工人撰写
networks:
client:
server:
services:
client:
container_name: clientName
image: "repoImage"
ports:
- 1:1
environment:
- VIRTUAL_HOST=SERVERIPADDRESS
- LETSENCRYPT_HOST=SERVERIPADDRESS
networks:
- client
restart: always
server:
container_name: serverName
networks:
- client
- server
image: "repoImage"
command npm run startProd
ports:
- 2:2
restart: always
env_file:
- <envfilepath>
database:
container_name: dbInstance
networks:
- server
restart: always
image: dbimage
ports:
- 3:3
- 4:4
volumes:
- many
environment
- envVars
【问题讨论】:
你能发布你的 compose 文件和 NGINX conf 吗? @MrDiggles 感谢您的回复 文件已添加,请告诉我是否需要添加任何其他内容以使其更清晰 【参考方案1】:如果您对整个系统使用docker-compose
,它往往会简化事情,特别是如果它们都在同一台机器上运行。这样,您就可以利用 Docker 的网络并最大限度地减少需要公开的端口数量。
例如,你可以这样设置
NGINX 是“前门”,根据主机名或路径将流量引导至client
和 server
服务通过服务名+端口相互引用
docker-compose.yml
networks:
db-net:
proxy-net:
services:
nginx:
networks:
proxy-net:
ports:
# These are the only ports that will be open on your machine
- 80:80
- 443:443
database:
networks:
db-net:
# no ports exposed
command: <run on port 3306>
server:
networks:
db-net:
proxy-net:
# no ports exposed
command: <run on port 3000>
environment:
- DATABASE_URL=database:3306
client:
networks:
proxy-net:
# no ports exposed
command: <run on port 3000>
nginx.conf
server
...
location /client
...
proxy_pass http://client:3000;
...
location /server
...
proxy_pass http://server:3000;
...
如果您有任何问题或我误解了您的问题,请告诉我。
【讨论】:
这绝对是理想的状态,也是我想要的状态!但是,当在 docker-compose 中使用时,让letsencrypt 和 certbot 运行并没有提供太多的教程方式。如果我不需要在 https 上运行,我现在会这样做,但是因为它可以更容易地在服务器上运行 NGINX 并连接加密服务,因为我可以访问代码。我确实认为我可能拥有它,在代理通行证中我可以只定位本地主机,如果我没有弄错这个路由直接到服务而不希望通过网络以上是关于如何将 Nginx 反向代理到本地托管(在具有 ssh 访问权限的服务器上)docker-compose的主要内容,如果未能解决你的问题,请参考以下文章
如何强制更新/防止在 Linux 上运行并由 nginx 反向代理服务器托管的 .NET Core Web 应用程序的 HTML 缓存