docker - Docker容器上的Next.js API URL问题
问题描述
我的问题是:
我用 Next.js 做了一个简单的网页。我从 /pages/api/ 端点以 JSON 格式获取一些内容,并将其显示在页面和组件中。在本地编译(npm run dev 或 npm run start)没问题。当我在 Windows 10 上的 Docker 上运行它时,我再也没有问题了。这适用于 Heroku 和 Vercel。我遇到的问题是:我把项目交给了 Devops 团队,他们在 Docker 上运行它。他们还将一个域定向到该项目。但是 api 端点毫无意义地尝试访问 ID URL。当我从 Chrome Devtools 中查看时,它看起来像这样:
http://013cfdde4910:3000/api/en/brands
我收到以下错误作为控制台消息。
混合内容:“https://beta..com/technologies”页面通过 HTTPS 加载,但请求了不安全的资源“http://013cfdde4910:3000/api/en/menu”。此请求已被阻止;内容必须通过 HTTPS 提供。
实际上应该是 http://localhost:3000/api/en/brands。我不明白这里的 013cfdde4910 来自哪里以及为什么。
我检查了它是否在代码中。我查看了来自 Google Devtools 的 Live 项目的 Source,即 Devops 团队发布的项目。
_next/static > 块 > 页面 > _app-eac17e226e00cc01a313.js
当我在这里搜索时,我在 3 个地方找到了 013cfdde4910 字符串。为什么建的时候会来这里?
例如,缩小后的代码如下。
.... return(0,u.useEffect)((function(){fetch("".concat("http://013cfdde4910:3000","/api/").concat(t.locale,"/) brands")).....
我可以在本地构建中将其视为 localhost,当我在 Windows 10 Docker 中发布它并查看时。那么是什么导致了 localhost -> 013cfdde4910 转换,我该如何解决呢?
我使用的 Dockerfile:
FROM node:current-alpine as base
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
FROM base AS build
ENV NODE_ENV=production
WORKDIR /build
COPY --from=base /app ./
RUN npm run build
FROM node:current-alpine AS production
ENV NODE_ENV=production
WORKDIR /app
COPY --from=build /build/package*.json ./
COPY --from=build /build/.next ./.next
COPY --from=build /build/public ./public
RUN npm install
EXPOSE 3000
CMD npm run start
我使用 docker-compose.yml
version: "3"
services:
ui:
container_name: web
restart: always
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
volumes:
- ./:/app
- /app/node_modules
- /app/.next
env_file:
- .env
这是 next.config.js
module.exports = {
webpackDevMiddleware: (config) => {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
return config;
},
async headers() {
return [
{
source: "/api/:path*",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
{
key: "Access-Control-Allow-Methods",
value: "GET,OPTIONS,PATCH,DELETE,POST,PUT",
},
{
key: "Access-Control-Allow-Headers",
value:
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
},
],
},
];
},
reactStrictMode: true,
generateEtags: false,
i18n: {
locales: ["en", "tr"],
defaultLocale: "en",
localeDetection: false,
},
env: {
VERSION: process.env.VERSION,
MODE: process.env.MODE,
APP_NAME: process.env.APP_NAME,
HOST: process.env.HOST,
HOSTNAME: process.env.HOSTNAME,
PORT: process.env.PORT,
GA_TRACKING_ID: process.env.GA_TRACKING_ID,
},
generateBuildId: async () => {
return new Date().toDateString();
},
eslint: {
ignoreDuringBuilds: false,
},
};
解决方案
感谢您发布配置,看来主机名被抓取为 docker 容器 ID - 您没有发布实际的获取代码,但我的猜测是 - 使用了这个环境变量。
`HOSTNAME: process.env.HOSTNAME`
它要么作为环境变量传递,要么被解释为容器 ID,您需要一种方法来创建domain:3000/api/brands
可能是 Docker 部署的一部分,可能是 nginx 代理。
推荐阅读
- c# - 使用反射时,为什么没有正确设置值?
- python - RuntimeError:无法初始化 SecretService:环境变量 DBUS_SESSION_BUS_ADDRESS 未设置
- c# - 加入查询 C# SQL Server
- django - 保护用户的模型视图不受其他用户的影响
- javascript - 检查 div 条件的 if 语句
- sql - 提取与另一列精确搜索匹配的值
- android - 从 Google Play Games API 获取用户 ID?
- javascript - 如何调整d3地图的大小
- c++ - 如何在 Linux unsing QProcess 下执行 shell 命令?
- pyspark - 如何在pyspark中的groupBy之后获得每个计数的总数百分比?