生产环境中 Nextjs(T3 应用程序)和 Docker 出现网络问题 [TypeError: fetch failed at Object.fetch]

问题描述 投票:0回答:1

我有一个使用 create T3 应用程序堆栈的 Nextjs 项目(除了使用 drizzle orm 代替 pf Prisma)。 在我的开发环境中一切正常 现在我想使用 docker 在我的 Linux 服务器上部署我的项目。

Ubuntu 22.04.2 LTS - Platform: linux/arm64/v8

docker-compose 构建过程运行良好。两项服务均已启动并正在运行,并且环境变量已正确设置(除非我忘记设置重要的变量?),但我无法访问应用程序的任何页面。当我尝试打开它时,服务器正在记录几个运行时错误,抱怨与本地主机的连接被拒绝。 我的设置和错误发布在下面。

我的 Dockerfile(来自 T3 文档)

##### DEPENDENCIES

FROM --platform=linux/arm64/v8 node:16-alpine3.17 AS deps
RUN apk add --no-cache libc6-compat openssl1.1-compat
WORKDIR /app

# Install dependencies based on the preferred package manager

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml\* ./

RUN \
    if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
    elif [ -f package-lock.json ]; then npm ci; \
    elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \
    else echo "Lockfile not found." && exit 1; \
    fi

##### BUILDER

FROM --platform=linux/arm64/v8 node:16-alpine3.17 AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
    if [ -f yarn.lock ]; then SKIP_ENV_VALIDATION=0 yarn build; \
    elif [ -f package-lock.json ]; then SKIP_ENV_VALIDATION=0 npm run build; \
    elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && SKIP_ENV_VALIDATION=0 pnpm run build; \
    else echo "Lockfile not found." && exit 1; \
    fi

##### RUNNER

FROM --platform=linux/arm64/v8 node:16-alpine3.17 AS runner
WORKDIR /app

ENV NODE_ENV production

# ENV NEXT_TELEMETRY_DISABLED 1

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

COPY --from=builder /app/next.config.mjs ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

# USER nextjs
EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]

我的docker-compose

version: '3.8'
services:
  nextjs-app-bpl-v3:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: nextjs-app-bpl-v3
    restart: unless-stopped
    working_dir: /app
    ports:
      - '3187:3000'
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres-db-bpl-v3:5432/${POSTGRES_DB}
      - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
      - NEXTAUTH_URL=${NEXTAUTH_URL}
      - DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID}
      - DISCORD_CLIENT_SECRET=${DISCORD_CLIENT_SECRET}
    image: t3-app-bpl-v3
    depends_on:
      - postgres-db-bpl-v3
    networks:
      - nginx_network

  postgres-db-bpl-v3:
    image: postgres:latest
    container_name: postgres-db-bpl-v3
    restart: unless-stopped
    ports:
      - '5578:5432'
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    volumes:
      - postgres-data-bpl-v3:/var/lib/postgresql/data
    networks:
      - nginx_network

volumes:
  postgres-data-bpl-v3:


networks:
  nginx_network:
    external: true

我的环境(.env)

NEXTAUTH_SECRET="MY_SECRET"
NEXTAUTH_URL="https://example.com"
# Next Auth Providers
DISCORD_CLIENT_ID="DC_ID"
DISCORD_CLIENT_SECRET="DC_SECRET"

POSTGRES_USER="username"
POSTGRES_PASSWORD="my_password"
POSTGRES_DB="db_name"

下一个.config.mjs

await import("./src/env.mjs");

/** @type {import("next").NextConfig} */
const config = {
  reactStrictMode: true,
  i18n: {
    locales: ["en"],
    defaultLocale: "en",
  },
  webpackDevMiddleware: (
    /** @type {{ watchOptions: { poll: number; aggregateTimeout: number; }; }} */ config
  ) => {
    config.watchOptions = {
      poll: 1000,
      aggregateTimeout: 300,
    };
    return config;
  },
  swcMinify: true,
  output: "standalone",
};

export default config;

容器日志:

Attaching to nextjs-app-bpl-v3
nextjs-app-bpl-v3     | - ready started server on 07135160c06c:3000, url: http://07135160c06c:3000
nextjs-app-bpl-v3     | Listening on port 3000 url: http://07135160c06c:3000
nextjs-app-bpl-v3     | Warning - Configuring `keepAlive: false` is deprecated. Use `{ headers: { connection: "close" } }` instead.
nextjs-app-bpl-v3     | - error Failed to handle request for /
nextjs-app-bpl-v3     | TypeError: fetch failed
nextjs-app-bpl-v3     |     at Object.fetch (/app/node_modules/next/dist/compiled/undici/index.js:1:26669)
nextjs-app-bpl-v3     |     at processTicksAndRejections (node:internal/process/task_queues:96:5)
nextjs-app-bpl-v3     |     at async invokeRequest (/app/node_modules/next/dist/server/lib/server-ipc/invoke-request.js:21:12)
nextjs-app-bpl-v3     |     at async requestHandler (/app/node_modules/next/dist/server/lib/start-server.js:336:33)
nextjs-app-bpl-v3     |     at async Server.<anonymous> (/app/node_modules/next/dist/server/lib/start-server.js:152:13) {
nextjs-app-bpl-v3     |   cause: Error: connect ECONNREFUSED 127.0.0.1:45761
nextjs-app-bpl-v3     |       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) {
nextjs-app-bpl-v3     |     errno: -111,
nextjs-app-bpl-v3     |     code: 'ECONNREFUSED',
nextjs-app-bpl-v3     |     syscall: 'connect',
nextjs-app-bpl-v3     |     address: '127.0.0.1',
nextjs-app-bpl-v3     |     port: 45761
nextjs-app-bpl-v3     |   }
nextjs-app-bpl-v3     | }
nextjs-app-bpl-v3     | - error Failed to handle request for /favicon.ico
nextjs-app-bpl-v3     | TypeError: fetch failed
nextjs-app-bpl-v3     |     at Object.fetch (/app/node_modules/next/dist/compiled/undici/index.js:1:26669)
nextjs-app-bpl-v3     |     at processTicksAndRejections (node:internal/process/task_queues:96:5)
nextjs-app-bpl-v3     |     at async invokeRequest (/app/node_modules/next/dist/server/lib/server-ipc/invoke-request.js:21:12)
nextjs-app-bpl-v3     |     at async requestHandler (/app/node_modules/next/dist/server/lib/start-server.js:336:33)
nextjs-app-bpl-v3     |     at async Server.<anonymous> (/app/node_modules/next/dist/server/lib/start-server.js:152:13) {
nextjs-app-bpl-v3     |   cause: Error: connect ECONNREFUSED 127.0.0.1:45761
nextjs-app-bpl-v3     |       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) {
nextjs-app-bpl-v3     |     errno: -111,
nextjs-app-bpl-v3     |     code: 'ECONNREFUSED',
nextjs-app-bpl-v3     |     syscall: 'connect',
nextjs-app-bpl-v3     |     address: '127.0.0.1',
nextjs-app-bpl-v3     |     port: 45761
nextjs-app-bpl-v3     |   }
nextjs-app-bpl-v3     | }

为什么运行时尝试连接到本地主机?我看不出有任何地方可以提及这一点。错误发生在服务器上(而不是打开页面时发生在客户端) 客户端仅显示 500:内部服务器错误。

我现在的解决方法是: 我删除了

output: "standalone"
并通过删除 RUNNER 部分更新了 Dockerfile,并使用
npm run start
(
next start
) 启动服务器 这是有效的,尽管我仍然想知道为什么它不能与独立输出一起工作

我的问题和目标是通过修复此问题来按预期使用独立服务器

TypeError: fetch failed
。 不使用 docker 容器内部的独立构建的确切缺点是什么? 感谢您的任何解释!

node.js docker docker-compose next t3
1个回答
0
投票

我可能是错的,但我认为在构建时需要一些 ENV 变量,而在运行时使用

output: standalone
文件中的
next.config.{m}js
选项时需要一些 ENV 变量。我不确定这是否正确,但这就是我处理 Dockerfile 的方式
next 13.4.12
:

FROM base AS builder

ARG DATABASE_URL
ARG VERCEL_URL
ARG NEXT_PUBLIC_CLIENTVAR

ENV DATABASE_URL=${DATABASE_URL}
ENV VERCEL_URL=${VERCEL_URL}
ENV NEXT_PUBLIC_CLIENTVAR=${NEXT_PUBLIC_CLIENTVAR}
...
FROM base AS runner

ARG DATABASE_URL
ARG VERCEL_URL
ARG NEXT_PUBLIC_CLIENTVAR

ENV DATABASE_URL=${DATABASE_URL}
ENV VERCEL_URL=${VERCEL_URL}
ENV NEXT_PUBLIC_CLIENTVAR=${NEXT_PUBLIC_CLIENTVAR}

在我的

docker-compose.yml

services:
  next-app:
    restart: unless-stopped
    build:
      context: ./
      dockerfile: Dockerfile
      args:
        NEXT_PUBLIC_CLIENTVAR: ${NEXT_PUBLIC_CLIENTVAR}
    environment:
      - DATABASE_URL=${DATABASE_URL}
    ports:
      - 3000:3000

还值得注意的是,目前存在一个未解决的问题,涉及

next 13.4.13
及以上的 ENV 变量和
output: standalone

© www.soinside.com 2019 - 2024. All rights reserved.