Networking a NextJS development server in Docker

huangapple go评论55阅读模式
英文:

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

我找到了这个。看起来我们可以轻松设置服务器和公共运行时配置,但我担心它已经被弃用。不过,仍然可以设置服务器运行时配置。

  1. 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'
  }
}
  1. @/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
}
  1. 在需要 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.

  1. 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'
  }
}
  1. 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
}
  1. Import the config file wherever you need the API URL:
import { apiUrl } from '@/config'

huangapple
  • 本文由 发表于 2023年3月7日 11:07:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657695.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定