什么时候用 docker 中的服务名称替换 localhost?
When to replace localhost with service name in docker?
我已经 docker 化了 reactjs 应用程序和 express 应用程序。
这是我的 docker-compose.yml 文件:
version: "3"
services:
client:
image: react-app
build: ./client
ports:
- "3000:3000"
volumes:
- ./client/:/usr/src/app
- /usr/src/app/node_modules
container_name: mern-app-client
environment:
CHOKIDAR_USEPOLLING: "true"
server:
image: express-app
build: ./server
ports:
- "5000:5000"
volumes:
- ./server/:/usr/src/app
- /usr/src/app/node_modules
container_name: mern-app-server
environment:
CHOKIDAR_USEPOLLING: "true"
我有 2 个 docker 文件,每个客户端和服务器各 1 个(从节点映像构建)。
运行 docker 完成后,我在 http://localhost:5000 有服务器 运行 并在 http://localhost:3000 有反应应用程序。
当我在 React 应用程序的 axios/fetch 中将 base_url 作为 http://localhost:5000 时,一切正常。在一些博客中,不一定是 mern,我看到 localhost 被替换为服务名称。
我尝试了同样的方法并将 React 应用程序中的 base_url 替换为 http://server:5000 但它没有用。
现在我对什么时候应该更换 base_url 以及为什么需要它的核心概念感到困惑?
如果有人可以解释,我将不胜感激。
谢谢你的时间。
当您转到浏览器并在其中键入 http://localhost:3000
时,浏览器会调用 client
容器,执行 HTTP GET 以检索 Javascript 代码,然后浏览器实际运行代码。这是一个关键的区别:来自 React 应用程序的任何 fetch
调用或类似调用都在最终用户的浏览器中 运行,而不是在 Docker.
中
如果调用来自浏览器;它是您的前端应用程序的一部分;或者它来自外部 Docker,那么您需要使用主机系统的 DNS 名称和第一个发布的 ports:
号码。如果浏览器和容器都在同一系统上 运行,你可以使用 localhost
;如果 Docker 在 VM 中是 运行(可能在较旧的 Docker Toolbox 设置中),您需要 VM 的 IP 地址。
+-------------+ +-----------------------+
| Browser | http://localhost:3000/ | client: |
| React app | ----------------------> | ports: ['3000:...'] |
+-------------+ +-----------------------+
一个容器之间直接调用也是可以的。也许 client
容器会调用 server
作为预呈现页面的一部分,然后再将其发送回浏览器;也许 server
有支持 db
。在这种情况下,您可以使用 Compose 服务名称作为主机名,以及服务器进程正在侦听的任何端口。 ports:
不是必需的,如果存在则会被忽略。
+----------+ +-------------------------+
| server: | postgres://db:5432/ | db: |
| | -------------------> | # ports: ['...:5432'] |
+----------+ +-------------------------+
此设置在 Docker 文档的 Networking in Compose 中有进一步描述。您通常不需要显式指定 container_name:
或 networks:
; Compose 为您提供了合理的工作默认值。
对于需要为应用程序本身和单独的 API 服务器配置 URLs 的基于浏览器的应用程序,一个好的做法是将反向代理设置为一个容器。这可能是 Nginx 之类的东西,或者在纯开发环境中 Webpack 的代理服务器。由于代理在两个容器之间进行调用,因此您需要为后端配置 Docker-internal URL http://server:5000
。这意味着浏览器内代码和后端 APIs 都在同一主机和端口上,因此您可以使用仅路径相对 URL /api/...
,绕过使用哪个主机和端口的问题。
我已经 docker 化了 reactjs 应用程序和 express 应用程序。
这是我的 docker-compose.yml 文件:
version: "3"
services:
client:
image: react-app
build: ./client
ports:
- "3000:3000"
volumes:
- ./client/:/usr/src/app
- /usr/src/app/node_modules
container_name: mern-app-client
environment:
CHOKIDAR_USEPOLLING: "true"
server:
image: express-app
build: ./server
ports:
- "5000:5000"
volumes:
- ./server/:/usr/src/app
- /usr/src/app/node_modules
container_name: mern-app-server
environment:
CHOKIDAR_USEPOLLING: "true"
我有 2 个 docker 文件,每个客户端和服务器各 1 个(从节点映像构建)。
运行 docker 完成后,我在 http://localhost:5000 有服务器 运行 并在 http://localhost:3000 有反应应用程序。
当我在 React 应用程序的 axios/fetch 中将 base_url 作为 http://localhost:5000 时,一切正常。在一些博客中,不一定是 mern,我看到 localhost 被替换为服务名称。
我尝试了同样的方法并将 React 应用程序中的 base_url 替换为 http://server:5000 但它没有用。
现在我对什么时候应该更换 base_url 以及为什么需要它的核心概念感到困惑?
如果有人可以解释,我将不胜感激。
谢谢你的时间。
当您转到浏览器并在其中键入 http://localhost:3000
时,浏览器会调用 client
容器,执行 HTTP GET 以检索 Javascript 代码,然后浏览器实际运行代码。这是一个关键的区别:来自 React 应用程序的任何 fetch
调用或类似调用都在最终用户的浏览器中 运行,而不是在 Docker.
如果调用来自浏览器;它是您的前端应用程序的一部分;或者它来自外部 Docker,那么您需要使用主机系统的 DNS 名称和第一个发布的 ports:
号码。如果浏览器和容器都在同一系统上 运行,你可以使用 localhost
;如果 Docker 在 VM 中是 运行(可能在较旧的 Docker Toolbox 设置中),您需要 VM 的 IP 地址。
+-------------+ +-----------------------+
| Browser | http://localhost:3000/ | client: |
| React app | ----------------------> | ports: ['3000:...'] |
+-------------+ +-----------------------+
一个容器之间直接调用也是可以的。也许 client
容器会调用 server
作为预呈现页面的一部分,然后再将其发送回浏览器;也许 server
有支持 db
。在这种情况下,您可以使用 Compose 服务名称作为主机名,以及服务器进程正在侦听的任何端口。 ports:
不是必需的,如果存在则会被忽略。
+----------+ +-------------------------+
| server: | postgres://db:5432/ | db: |
| | -------------------> | # ports: ['...:5432'] |
+----------+ +-------------------------+
此设置在 Docker 文档的 Networking in Compose 中有进一步描述。您通常不需要显式指定 container_name:
或 networks:
; Compose 为您提供了合理的工作默认值。
对于需要为应用程序本身和单独的 API 服务器配置 URLs 的基于浏览器的应用程序,一个好的做法是将反向代理设置为一个容器。这可能是 Nginx 之类的东西,或者在纯开发环境中 Webpack 的代理服务器。由于代理在两个容器之间进行调用,因此您需要为后端配置 Docker-internal URL http://server:5000
。这意味着浏览器内代码和后端 APIs 都在同一主机和端口上,因此您可以使用仅路径相对 URL /api/...
,绕过使用哪个主机和端口的问题。