我有两个docker容器frontend
和data-service
。
frontend
使用的是NextJS,这仅是相关的,因为NextJS有一个称为getInitialProps()
的方法,该方法可以在服务器上运行,也可以在访问者的浏览器中运行(我对此无能为力)
在getInitialProps()
中,我需要调用API来获取页面数据:
fetch('http://data-service:3001/user/123').then(...
在服务器上调用此API时,API返回正常,因为我的前端容器可以访问内部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"
答案 0 :(得分:2)
这篇文章中介绍了我找到的最优雅的解决方案:Docker-compose make 2 microservices (frontend+backend) communicate to each other with http requests
示例实现:
在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`);
...
}