React/Next.js Docker构建失败,当尝试到达本地API端点时

jei2mxaa  于 12个月前  发布在  Docker
关注(0)|答案(5)|浏览(153)

我似乎无法获得我的node:alpine Docker镜像来构建react/next.js。
我可以让它在本地构建得很好,但是当Docker构建到达API端点时,我从来没有在我的API日志中看到流量,它本身运行在Docker容器(nginx,无头craft cms等)中。
构建似乎不喜欢localhost,因为我已经尝试过了:
http://localhost:9000/api
……这是我在日志中得到的信息:

#15 13.76 > Build error occurred
#15 13.76 FetchError: request to http://localhost:9000/api failed, reason: connect ECONNREFUSED 127.0.0.1:9000

字符串
我听说我可以使用hostname来代替“localhost”,所以在我的MacOS终端中我输入了“hostname”,并将localhost替换为这个值。这并没有完全出错,但是构建挂起在构建的“生成页面.”步骤上。
如何让Docker构建识别localhost,或者换句话说,如何将我的API URL设置为本地Docker容器托管的端点?
下面是我的Dockerfile:

# Install dependencies only when needed
FROM node:alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn --frozen-lockfile

# Rebuild the source code only when needed
FROM node:alpine AS builder

WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn static

# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

USER nextjs

EXPOSE 3000

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1

CMD ["yarn", "start"]

czq61nw1

czq61nw11#

好吧,我想出了解决办法,或者说是一个解决办法。
四处挖掘后,我发现我需要连接到“桥梁网络”。
我通过首先输入“docker network ls”找到了网桥网络IP是什么:
x1c 0d1x的数据
这给了我需要获取IP的网络的名称,我通过输入“docker network inspect craftcms_default”来做到这一点:



在我的例子中,这会输出很多,但我唯一需要的是“Gateway”IP,这里是172.19.0.1
我的nginx服务器Map为9000:80,因此无头Craft CMS API位于:
http://172.19.0.1:9000/api
.然而,作为一个快速的健全性检查,我把它输入到浏览器中,结果是一个不断旋转/加载的页面。我没有被吓倒,我把它作为PUBLIC_NEXT_API_URL输入到env.local中,静态站点生成在Docker构建期间完成得很好。
我仍然在尝试一种优雅的方式来在Docker构建中设置这个env var,所以如果有人有任何建议,我很乐意听到!
这是一个有趣的挑战,考虑到我找不到任何答案/谷歌结果,特别是由于Docker构建无法获取托管在另一个本地运行的容器中的URL而运行的进程。希望这能帮助其他任何人解决这个问题!

bvjxkvbb

bvjxkvbb2#

感谢你的帖子-它帮助我找到了一个解决方案,应该做的伎俩。我发现定义网桥网络网关是一个更优雅的解决方案;它允许你定义PUBLIC_NEXT_API_URL,从来没有改变它。
以下是如何在docker-compose文件中执行此操作:

services:
  db:
    image: postgres
    restart: always
    networks:
      - stagingnetwork

  api:
    image: express
    restart: always
    ports:
      - '3008:3008'
    depends_on:
      - db
    networks:
      - stagingnetwork

  adminer:
    image: adminer
    restart: always
    networks:
      - stagingnetwork
    ports:
      - 8080:8080

networks:
  stagingnetwork:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

字符串
现在,您可以设置PUBLIC_NEXT_API_URL to http://172.28.0.1:3008/api,,并确信这将是每次启动docker-compose时的端点。
此外,请注意,您可能需要删除现有网络,然后删除"docker-compose up --force-recreate",以获得正确的IP。

b4wnujal

b4wnujal3#

我知道这是一个老问题,但我会把我的解决方案留给任何新的人。虽然给定的解决方案对我来说确实有效,但我还是想找一些更优雅的解决方案。出现这个问题显然是因为localhost主机名总是引用当前容器的localhost,而不是主机的localhost。
在docker for mac文档中,他们提到使用host.docker.internal从一个容器连接到另一个服务。使用许多其他答案中推荐的容器名称对我没有帮助,但使用host.docker.internal解决了这个问题。
文档:
https://docs.docker.com/docker-for-mac/networking/
参考:
https://forums.docker.com/t/localhost-and-docker-compose-networking-issue/23100/5

w46czmvw

w46czmvw4#

如果你使用的是docker-compose,通常你可以使用容器的名称来引用容器,这将在Docker的默认网络中解析为它们的IP。然而,这在构建时似乎不起作用。
在Mac上,你可以像@MikejdeGroot说的那样通过host.docker.internal连接到主机上的容器。所以你可以使用http://host.docker.internal:9000/api
在Linux上,您可以考虑在构建时使用主机网络,例如:

nextjs-app:
  build:
    network: "host"
  # ...
  network_mode: "host"

字符串
有了这个配置,你可以使用http://localhost:9000/api

wgeznvg7

wgeznvg75#

如果你使用的是docker compose,你的服务名将是你将要访问的URL端点:例如,如果你的后端的docker compose是

build:
      context: ./backend
    ports:
      - "8000:8000"
    env_file:
      - ./backend/.env

字符串
然后,您可以通过

相关问题