我正在使用Docker Compose来部署我的应用程序。在我的docker-compose.yml
我有一个容器my-frontend
,它必须知道后端my-backend
的公共IP。图像my-frontend
是NodeJS应用程序,它在客户端的浏览器中运行。
在我这样做之前:
my-backend:
image: my-backend:latest
ports:
- 81:80
my-frontend:
image: my-frontend:latest
ports:
- 80:80
environment:
- BACKEND=http://localhost:81
当我部署到本地Docker守护程序并且客户端在本地运行时,这可以正常工作。
我现在正在迁移到远程Docker守护程序。在这种情况下,客户端不再与Docker守护程序在同一主机上运行。因此,我需要更改BACKEND
中的环境变量my-frontend
:
environment:
- BACKEND=http://<ip-of-daemon>:81
当我将<ip-of-daemon>
硬编码到Docker守护程序的实际ip时,一切正常。但我想知道是否有办法动态填写此内容?所以我可以对任何远程Docker守护进程使用相同的docker-compose.yml
。
答案 0 :(得分:2)
使用Docker Compose,您的Docker容器将全部显示在同一台计算机上。也许您正在使用Swarm或Kubernetes等工具来将容器分发到不同的主机上,这意味着您的后端和前端容器确实可以通过不同的公共IP地址访问。
处理此问题的常用方法是在单个入口点上使用Traefik之类的前端代理。这意味着从浏览器的角度来看,前端和后端的IP地址是相同的。在内部,代理将使用过滤规则将流量定向到正确的LAN名称。通常的方法是使用像/backend/
这样的URL路径前缀。
您在评论中正确地提到,假设您的前端容器可以在静态公共IP上访问,您可以使用NginX从内部代理到您的后端。这应该可以正常工作。
这些方法中的任何一种都允许单个IP看起来“共享”端口 - 这解决了想要在多个容器中监听80/443上的相同IP的问题。您需要尝试避免用于后端呼叫的非标准端口,因为某些网络可能会阻止它们(例如移动网络,公司防火墙环境)。
我不确定这些方法会有什么替代方案。如果您可以在主机上运行代码,您当然可以获取计算机的公共IP,但如果您的容器编排正在将容器发送到计算机,那么将运行的唯一代码位于每个容器内,我不相信公开的IP信息会暴露那里。
我最初从你的问题中假设你期望你的容器在Docker服务器场中的任意主机上启动。实际上,您在评论中确认的当前方法是许多未连接的Docker主机,因此无论何时部署,您的容器都可以保证共享公共IP。我现在更了解您的问题背后的目的 - 您想要为后端指定基本URL,包括完全限定的域,非标准端口和URL路径前缀。
正如我在讨论中指出的那样,这可能不是必需的,因为您可以在前端NginX中放置代理URL路径前缀(/backend
)。这消除了对非标准端口的需求。
如果您想指定自定义后端前缀(例如/backend/v1
以对您的API进行版本控制),那么您可以在Docker Compose配置中的env vars中执行此操作。
如果您需要在JavaScript中引用后端的完全限定地址以便连接到AJAX / WebSocket服务器,您可以从window.location.host
派生出来。在你的开发环境中,这将是一个裸IP地址,在你的远程环境中,听起来你有一个域名。
关于这个问题的一些混淆是关于我们指的是什么类型的IP地址。例如:
我相信my-backend的公共IP等于docker守护程序的IP
嗯,您的Docker主机有几个IP地址,公共地址只是其中之一。例如,虚拟网络接口docker0
是您的Docker主机的LAN IP,如果您要求Docker主机的IP,那确实是一个正确的答案(当然,它无法在公共互联网)。
事实上,我会说,守护进程的LAN地址属于(因为Docker设置了它)而公共IP没有(它是盒子的一个特性,而不是Docker)。
在任何Docker主机中,请尝试以下命令:
ifconfig docker0
这将为您提供有关主机IP的一些信息,如果Docker容器希望与主机联系(例如,如果要连接到未在容器中运行的服务),则非常有用。将此处的IP作为env var传递到容器中非常有用,以便允许进行此连接。
答案 1 :(得分:0)
my-backend:
image: my-backend:latest
ports:
- 81:80
my-frontend:
image: my-frontend:latest
ports:
- 80:80
environment:
- BACKEND="${BACKEND_ENV}"
其中BACKEND_ENV和环境变量设置为docker守护程序的ip。
在docker-compose执行的机器中,先设置环境变量。
导出BACKEND_ENV =&#34; http://remoteip..."
或者只是启动指向远程地址的前端
docker run -p 80:80 -e BACKEND='http://remote_backend_ip:81' my-frontend:latest