从服务器端(从另一个容器)引用 Docker 容器,并从客户端(浏览器)使用相同的 URL
Referencing Docker container from server-side (from another container) AND from client-side (browser) with same URL
我有两个 docker 个容器 frontend
和 data-service
。
frontend
正在使用 NextJS,这只是相关的,因为 NextJS 有一个名为 getInitialProps()
的方法,它可以是服务器上的 运行,也可以是 运行 在访问者的浏览器(我无法控制这个)。
在 getInitialProps()
中,我需要调用一个 API 来获取页面的数据:
fetch('http://data-service:3001/user/123').then(...
在服务器上调用时 API returns 很好,因为我的前端容器可以访问内部 docker 网络,因此可以使用主机名引用数据服务http://data-service
.
然而,当在客户端调用它时,它失败了(显然),因为 Docker 现在公开为 http://localhost
,我不能再引用 http://data-service
。
如何配置 Docker 以便我可以将 1 URL 用于两种用例。如果可能的话,我宁愿不必在我的 NextJS 代码中弄清楚我所处的环境。
如果看到我的 docker-compose 有用,我将其包含在下面:
version: '2.2'
services:
data-service:
build: ./data-service
command: npm run dev
volumes:
- ./data-service:/usr/src/app/
- /usr/src/app/node_modules
ports:
- "3001:3001"
environment:
SDKKEY: "whatever"
frontend:
build: ./frontend
command: npm run dev
volumes:
- ./frontend:/usr/src/app/
- /usr/src/app/node_modules
environment:
API_PORT: "3000"
API_HOST: "http://catalog-service"
ports:
- "3000:3000"
这个 post 中描述了我找到的最优雅的解决方案:
示例实现:
在next.config.js
中:
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
URI: 'your-docker-uri:port'
},
publicRuntimeConfig: {
// Will be available on both server and client
URI: 'http://localhost:port'
}
}
在pages/index.js
中:
import getConfig from 'next/config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
const API_URI = serverRuntimeConfig.apiUrl || publicRuntimeConfig.apiUrl;
const Index = ({ json }) => <div>Index</div>;
Index.getInitialProps = async () => {
...
const res = await fetch(`${API_URI}/endpoint`);
...
}
我有两个 docker 个容器 frontend
和 data-service
。
frontend
正在使用 NextJS,这只是相关的,因为 NextJS 有一个名为 getInitialProps()
的方法,它可以是服务器上的 运行,也可以是 运行 在访问者的浏览器(我无法控制这个)。
在 getInitialProps()
中,我需要调用一个 API 来获取页面的数据:
fetch('http://data-service:3001/user/123').then(...
在服务器上调用时 API returns 很好,因为我的前端容器可以访问内部 docker 网络,因此可以使用主机名引用数据服务http://data-service
.
然而,当在客户端调用它时,它失败了(显然),因为 Docker 现在公开为 http://localhost
,我不能再引用 http://data-service
。
如何配置 Docker 以便我可以将 1 URL 用于两种用例。如果可能的话,我宁愿不必在我的 NextJS 代码中弄清楚我所处的环境。
如果看到我的 docker-compose 有用,我将其包含在下面:
version: '2.2'
services:
data-service:
build: ./data-service
command: npm run dev
volumes:
- ./data-service:/usr/src/app/
- /usr/src/app/node_modules
ports:
- "3001:3001"
environment:
SDKKEY: "whatever"
frontend:
build: ./frontend
command: npm run dev
volumes:
- ./frontend:/usr/src/app/
- /usr/src/app/node_modules
environment:
API_PORT: "3000"
API_HOST: "http://catalog-service"
ports:
- "3000:3000"
这个 post 中描述了我找到的最优雅的解决方案:
示例实现:
在next.config.js
中:
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
URI: 'your-docker-uri:port'
},
publicRuntimeConfig: {
// Will be available on both server and client
URI: 'http://localhost:port'
}
}
在pages/index.js
中:
import getConfig from 'next/config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
const API_URI = serverRuntimeConfig.apiUrl || publicRuntimeConfig.apiUrl;
const Index = ({ json }) => <div>Index</div>;
Index.getInitialProps = async () => {
...
const res = await fetch(`${API_URI}/endpoint`);
...
}