这里是Docker的新手。我的Nextjs应用程序一直遇到令人困惑的障碍,该应用程序与API和数据库容器一起在自己的容器中运行。
我的Nextjs应用程序使用API容器中的数据。这在服务器端非常有用:Nextjs应用程序应按需解析容器主机名。但是在客户端,应用程序中断了,因为容器主机名对浏览器没有任何意义(我认为?)。我不知道该如何处理。想法?
这是我的Docker Compose文件,以帮助阐明我的问题。请注意,我正在通过environment
字段将主机名传递给Nextjs应用程序:
version: '3.8'
services:
# Redis
redis:
image: redis
command: redis-server --requirepass ${REDIS_PASSWORD} --bind redis
ports:
- "6379:6379"
networks:
- mywebappio
# Data Processing Service
mywebapp-api:
container_name: mywebapp-api
restart: always
build:
context: packages/dps-api
dockerfile: Dockerfile
command: npm run dev # npm start prod
working_dir: /usr/src/dps-api
env_file:
- .env
volumes:
- ./packages/dps-api:/usr/src/dps-api
ports:
- "5000:5000"
networks:
- mywebappio
depends_on:
- redis
# SSR 'client' app
nextjs:
container_name: mywebapp-client
build:
context: packages/next-server
dockerfile: Dockerfile
command: /bin/bash -c "./wait-for-it.sh mywebapp-api:5000 -- npm run build && npm run start"
environment:
- NEXT_PUBLIC_API_BASE=mywebapp-api:5000
volumes:
- ./packages/next-server:/usr/src/app
ports:
- "3000:3000"
networks:
- mywebappio
depends_on:
- mywebapp-api
- redis
networks:
mywebappio:
driver: bridge
其他信息:
在我的API上使用curl
作为“ localhost:5000”可以使用。
在开发控制台中,Nextjs应用程序调用“ localhost:3000 /”以获取服务器端数据。鉴于Nextjs的工作原理,这很有意义。
在开发控制台中,Nextjs应用程序调用“ mywebapp-api:5000 /”以获取客户端数据。显然,这是行不通的。
答案 0 :(得分:1)
好的,所以我找到了解决方案/解决方法。我在网上阅读,我发现只有一种方法。这就是为{。{3}}这样的nextjs服务器设置反向代理。但是我以不同的方式解决了这个问题:nextjs有2种类型的env变量,那些仅暴露于SERVER(BACKEND_URL = http:// servicename:port),而那些暴露于SERVER AND CLIENT( NEXT_PUBLIC _BACKEND_URL = http:// localhost:port)-在此我定义了localhost,以便浏览器可以读取api。而且,您只需执行此操作即可设置axios:
import axios from 'axios';
const instance = axios.create({
baseURL: process.env.BACKEND_URL || process.env.NEXT_PUBLIC_BACKEND_URL,
});
export default instance;
现在在客户端它将使用http:// localhost:port,在SSR上将使用http:// servicename:port。
答案 1 :(得分:1)
如果你想在你的电脑(本地环境)中工作,你可以在 next.config.js 中更改后端的 IP。例如,如果您的计算机具有 IP 192.168.1.23 并且后端容器在端口 3000 中运行,那么您的 next.config.js 必须具有下一个:
env: {
backendUrl: 'http://192.168.1.23:3000/api/v1',
},
对于你的 axios 配置也可以如下所示:
import axios from 'axios';
const wrapperAxios = axios.create({
baseURL: process.env.backendUrl,
headers: { 'Content-type': 'application/json' },
});
export default wrapperAxios;