Docker中Next.js应用仅监听单接口,无法被反向代理访问求助
NextJS 应用在Docker多网络环境下仅监听单一IP,无法通过反向代理访问
我有一个依赖MySQL数据库的NextJS应用,已通过docker-compose创建两个容器:grades_web(应用容器)和grades_mysql(数据库容器)。
网络配置:
sys_apps_net(10.200.5.x):用于连接反向代理,实现外部网络访问grades_web_db(10.200.7.x):用于应用容器与MySQL容器通信
应用容器grades_web拥有两个IP:
- 10.200.7.2(归属
grades_web_db网络) - 10.200.5.3(归属
sys_apps_net网络)
启动容器时我设置了HOSTNAME=0.0.0.0,理论上NextJS应监听所有IP,且应用采用standalone模式构建,但容器启动日志显示:
▲ Next.js 13.5.3
- Local: http://b0772d4dfb3c:3000
- Network: http://10.200.7.2:3000
这说明应用仅监听10.200.7.2,导致反向代理和外部无法访问。请问如何让应用监听所有IP地址?
环境版本:
- NextJS 13.5.3
- MySQL 8.1
- Docker 24.0.6
相关配置文件
Dockerfile
FROM node:20-alpine AS dependencies WORKDIR /app COPY package.json package-lock.json ./ RUN npm install FROM node:20-alpine AS build WORKDIR /app COPY --from=dependencies /app/node_modules ./node_modules COPY . . RUN npx prisma generate RUN npx next telemetry disable RUN npm run build FROM node:20-alpine AS deploy WORKDIR /app ENV NODE_ENV production COPY --from=build /app/public ./public COPY --from=build /app/package.json ./package.json COPY --from=build /app/.next/standalone ./ COPY --from=build /app/.next/static ./.next/static COPY --from=build /app/prisma ./prisma EXPOSE 3000 ENV PORT 3000 CMD ["npm", "run", "start:migrate:prod"]
docker-compose.yml
version: '3' services: app: image: gdr.htl-villach.at/htl-it/htl-it-docker-registry/grades:0.9 container_name: grades_web restart: unless-stopped networks: - sys_apps_net - web_db environment: HOST: 0.0.0.0 DATABASE_URL: ${DATABASE_URL} NEXTAUTH_URL: ${NEXTAUTH_URL} NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} AZURE_CLIENT_ID: ${AZURE_CLIENT_ID} AZURE_CLIENT_SECRET: ${AZURE_CLIENT_SECRET} AZURE_TENANT_ID: ${AZURE_TENANT_ID} db: image: mysql:8.1 container_name: grades_mysql restart: unless-stopped networks: - web_db volumes: - mysql_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} MYSQL_ROOT_HOST: ${MYSQL_ROOT_HOST} volumes: mysql_data: networks: web_db: external: false sys_apps_net: external: true
package.json(脚本片段)
... "scripts": { ... "start:migrate:prod": "HOSTNAME=0.0.0.0 npx prisma migrate deploy && node prisma/seed.mjs && node server.js" },
解决方法
问题核心是NextJS standalone模式对环境变量的识别规则,以及启动参数的传递逻辑,调整以下几点即可解决:
1. 替换HOSTNAME为HOST环境变量
NextJS standalone模式下,识别的是HOST而非HOSTNAME作为监听地址的配置项。你当前在docker-compose.yml中设置了HOST: 0.0.0.0,但启动脚本里用了HOSTNAME=0.0.0.0,导致配置冲突。
修改package.json的启动脚本,移除HOSTNAME,改用HOST:
"start:migrate:prod": "HOST=0.0.0.0 npx prisma migrate deploy && node prisma/seed.mjs && node server.js"
2. 强制指定启动参数绑定0.0.0.0
如果环境变量仍未生效,可以直接在启动server.js时传递参数,强制绑定所有IP:
"start:migrate:prod": "npx prisma migrate deploy && node prisma/seed.mjs && node server.js -H 0.0.0.0"
3. 验证监听状态
修改后重启容器,查看日志是否显示:
- Network: http://0.0.0.0:3000
也可以进入容器执行netstat -tulpn,确认node进程监听的是0.0.0.0:3000而非单一IP。
额外检查
- 确保
docker-compose.yml中的HOST环境变量未被容器内其他配置覆盖 - 确认Dockerfile中的
EXPOSE 3000配置正确(虽为声明性配置,但可避免遗漏)
内容的提问来源于stack exchange,提问作者Robert Hufsky
相关产品推荐
相关产品推荐

