英文:
Networking a NextJS development server in docker
问题
我目前的设置是,我有一个在Docker Compose中以开发模式运行的NextJS应用,我们称之为"frontend"。
后端是一个ExpressJS应用,我们称之为"backend"。
在我的NextJS应用中有一个环境变量,它指定了后端的终端点,我可以将其设置为"http://backend:3000"或"http://localhost:3000"。根据我设置的终端点,NextJS会遇到一个问题(客户端与"服务器"端查询)。
有没有办法我可以从我的主机机器以及前端容器使用相同的"url"访问我的后端?
为了更清楚编辑:
version: "3.9"
services:
frontend:
image: node:18.14.2
ports:
- "8000:8000"
volumes:
- ./Frontend:/app
# - /app/node_modules/
- /app/.next/
environment:
- NEXT_PUBLIC_BACKEND_BASE_URI=http://backend:3000
- NEXT_PUBLIC_CMS_URL=http://cms:1337
working_dir: /app
command: sh -c "npm install --silent && npm run dev"
frontend-graphql:
image: node:18.14.2
volumes:
- ./Frontend:/app
# - /app/node_modules/
- /app/.next/
environment:
- NEXT_PUBLIC_BACKEND_BASE_URI=http://backend:3000
- NEXT_PUBLIC_CMS_URL=http://cms:1337
working_dir: /app
command: sh -c "npm install --silent && npm run dev"
backend:
image: node:18.14.2
ports:
- "3000:3000"
working_dir: /app
volumes:
- ./Backend:/app
# - /app/node_modules/
command: sh -c "npm install && npm install -g ts-node && npm run dev"
cms:
image: node:18.14.2
ports:
- "1337:1337"
working_dir: /app
volumes:
- ./CMS:/app
- /app/node_modules/
command: sh -c "npm install && npm install --platform=linux --arch=arm64v8 sharp && npm run dev"
以上是您提供的Docker Compose文件中的配置,无需翻译代码部分。
英文:
I currently have a setup where I have a NextJS app in development mode in a docker-compose lets call frontend.
The backend is an expressjs app lets call backend.
I have an environment variable in my NextJS app that specifies the backend endpoint which I can either set as http://backend:3000 or http://localhost:3000. Depending on which endpoint I set, NextJS runs into an issue (client vs "server" side querying).
Is there a way I can access my backend from my host machine as well as frontend container using the same "url"?
Edited for clairty
version: "3.9"
services:
frontend:
image: node:18.14.2
ports:
- "8000:8000"
volumes:
- ./Frontend:/app
# - /app/node_modules/
- /app/.next/
environment:
- NEXT_PUBLIC_BACKEND_BASE_URI=http://backend:3000
- NEXT_PUBLIC_CMS_URL=http://cms:1337
working_dir: /app
command: sh -c "npm install --silent && npm run dev"
frontend-graphql:
image: node:18.14.2
volumes:
- ./Frontend:/app
# - /app/node_modules/
- /app/.next/
environment:
- NEXT_PUBLIC_BACKEND_BASE_URI=http://backend:3000
- NEXT_PUBLIC_CMS_URL=http://cms:1337
working_dir: /app
command: sh -c "npm install --silent && npm run dev"
backend:
image: node:18.14.2
ports:
- "3000:3000"
working_dir: /app
volumes:
- ./Backend:/app
# - /app/node_modules/
command: sh -c "npm install && npm install -g ts-node && npm run dev"
cms:
image: node:18.14.2
ports:
- "1337:1337"
working_dir: /app
volumes:
- ./CMS:/app
- /app/node_modules/
command: sh -c "npm install && npm install --platform=linux --arch=arm64v8 sharp && npm run dev"
答案1
得分: 1
目前我找到的最佳解决方案是绕过 host.docker.internal 主机名的黑客手段。
如前所述,host.docker.internal 可以在 docker 容器内直接访问,但由于 nextjs 还需要从容器的“外部”(浏览器中)访问后端服务器,我在 /etc/hosts 中映射了
127.0.0.1 到 host.docker.internal
(在 Mac 和 Windows 上测试通过)。
这允许客户端请求访问 http://host.docker.internal:3000,使您能够使用与“服务器端查询”相同的主机名。
英文:
The best solution I have found so far was hacking around the host.docker.internal hostname.
As mentioned before, host.docker.internal can be accessed directly inside of a docker container but as nextjs also needs to access the backend server from "outside" the container (in the browser) I mapped
127.0.0.1 to host.docker.internal
in /etc/hosts (tested on both mac and windows).
This allows the client-side requests to access http://host.docker.internal:3000, allowing you to use the same hostname as the "server-side-queries".
答案2
得分: 0
我找到了这个。看起来我们可以轻松设置服务器和公共运行时配置,但我担心它已经被弃用。不过,仍然可以设置服务器运行时配置。
- 在
next.config.js
中
const nextConfig = {
serverRuntimeConfig: {
// 仅在服务器端可用
apiUrl: process.env.NEXT_SERVER_API_URL || 'http://dockerbackend:8000'
},
publicRuntimeConfig: {
// 在服务器和客户端都可用
apiUrl: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'
}
}
- 在
@/config/index.ts
中
import getConfig from 'next/config';
const config = getConfig();
let apiUrl = process.env.NEXT_PUBLIC_API_URL;
if (config) {
apiUrl = config?.serverRuntimeConfig?.apiUrl
}
export {
apiUrl
}
- 在需要 API URL 的地方导入配置文件:
import { apiUrl } from '@/config';
英文:
I found this. It looks like we can easily set up server and public runtime configurations but I'm afraid it's been deprecated. Nevertheless, setting up server runtime configurations is still possible.
- In
next.config.js
const nextConfig = {
serverRuntimeConfig: {
// Will only be available on the server side
apiUrl: process.env.NEXT_SERVER_API_URL || 'http://dockerbackend:8000'
},
publicRuntimeConfig: {
// Will be available on both server and client
apiUrl: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'
}
}
- In
@/config/index.ts
import getConfig from 'next/config';
const config = getConfig();
let apiUrl = process.env.NEXT_PUBLIC_API_URL;
if (config) {
apiUrl = config?.serverRuntimeConfig?.apiUrl
}
export {
apiUrl
}
- Import the config file wherever you need the API URL:
import { apiUrl } from '@/config'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论