Docker 容器可从 Dockerfile 运行,但获取下一个:未从 docker-compose 容器中找到

Ale*_*dre 3 docker dockerfile docker-compose next.js

我的 docker-compose 配置文件有问题。我的目标是使用 docker-compose 文件运行 Next.js 应用程序并启用热重载。

从 Dockerfile 运行 Next.js 应用程序可以工作,但热重载不起作用。从 docker-compose 文件运行 Next.js 应用程序会触发错误:/bin/sh: next: not found并且我无法弄清楚出了什么问题......

Dockerfile:(取自 Next.js 的文档网站)

[但请注意,这是一个多阶段构建,我仅引用builderdocker-compose 文件中的阶段。]

# Install dependencies only when needed
FROM node:18-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install # --frozen-lockfile

# Rebuild the source code only when needed
FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# 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 during the build.
ENV NEXT_TELEMETRY_DISABLED 1

RUN yarn build

# If using npm comment out above and use below instead
# RUN npm run build

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

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

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

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3001

ENV PORT 3001

CMD ["node", "server.js"]
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml:

version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${POSTGRESQL_PASSWORD}
  backend:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      DATABASE_USERNAME: ${MYAPP_DATABASE_USERNAME}
      DATABASE_PASSWORD: ${POSTGRESQL_PASSWORD}
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      target: builder
    command: yarn dev
    volumes:
      - ./frontend:/app
    expose:
      - "3001"
    ports:
      - "3001:3001"
    depends_on:
      - backend
    environment:
      FRONTEND_BUILD: ${FRONTEND_BUILD}
      PORT: 3001
Run Code Online (Sandbox Code Playgroud)

package.json:

# Install dependencies only when needed
FROM node:18-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install # --frozen-lockfile

# Rebuild the source code only when needed
FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# 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 during the build.
ENV NEXT_TELEMETRY_DISABLED 1

RUN yarn build

# If using npm comment out above and use below instead
# RUN npm run build

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

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

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

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3001

ENV PORT 3001

CMD ["node", "server.js"]
Run Code Online (Sandbox Code Playgroud)

yarn devdocker-compose.yml它实际调用时next dev,它就会触发错误/bin/sh: next: not found。但是,直接从工作中运行容器Dockerfile不会导致此错误。

[更新]:

如果我volumedocker-compse.yml文件中删除该属性,我不会收到错误/bin/sh: next: not found并且容器会运行,但是,我现在没有获得我正在寻找的热重加载功能。知道为什么音量会与命令混淆吗/bin/sh next

joe*_*joe 6

发生这种情况是因为您的本地文件系统正在安装在 docker 容器中。您的 docker 容器确实在阶段中构建了节点模块builder,但我猜测您的本地文件系统中没有可用的节点模块。

要查看是否发生了这种情况,在本地文件系统上,您可以执行yarn install. 然后再次尝试通过 docker 运行容器。我预测这会起作用,就像在本地yarn安装一样next,它实际上是本地文件系统的节点模块将在 docker 容器中运行。

解决此问题的一种方法是卷安装除节点模块文件夹之外的所有内容。有关如何执行此操作的详细信息:向 Docker 添加卷,但排除子文件夹

因此,就您而言,我相信您可以在撰写文件中添加一行:

frontend:
    ...
    volumes:
      - ./frontend:/app
      - ./frontend/node_modules # <-- try adding this!
    ...
Run Code Online (Sandbox Code Playgroud)

这应该允许 docker 容器node_modules不会被任何卷安装覆盖。