【发布时间】:2021-10-11 06:12:22
【问题描述】:
我正在使用 docker 通过 Google Cloud Build > Google Cloud Registry 构建映像。然后我设置了 Pub/Sub 触发器,以便在成功构建时使用新的 Docker 映像填充 Cloud Run 实例。
但是,我的前端代码无法访问我在仪表板中手动设置的 Cloud Run ENV 变量(它们返回 undefined)。我需要能够在没有定义 ENV 的情况下构建图像,因为我希望有许多基于同一图像的 Cloud Run 实例并稍后注入 ENV。
我正在使用 NEXT.js。
这是我的 next.config.js
module.exports = withPlugins(plugins, {
assetPrefix,
reactStrictMode: true,
eslint: {
ignoreDuringBuilds: true,
},
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
config.plugins.push(new Dotenv({
path: '../../../.env',
}))
return config
},
serverRuntimeConfig: {
NEXT_PUBLIC_FIREBASE_USER_ID: process.env.NEXT_PUBLIC_FIREBASE_USER_ID,
},
publicRuntimeConfig: {
NEXT_PUBLIC_FIREBASE_USER_ID: process.env.NEXT_PUBLIC_FIREBASE_USER_ID,
},
env: {
NEXT_PUBLIC_FIREBASE_USER_ID: process.env.NEXT_PUBLIC_FIREBASE_USER_ID,
},
async rewrites() {
return [
{
source: '/:any*',
destination: '/',
},
];
},
});
还有我的前端
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
const { NEXT_PUBLIC_FIREBASE_USER_ID } = serverRuntimeConfig
const { NEXT_PUBLIC_FIREBASE_STORE_ID } = publicRuntimeConfig
function App(props) {
useEffect(() => {
console.log("NEXT_PUBLIC_FIREBASE_USER_ID: ", NEXT_PUBLIC_FIREBASE_USER_ID)
console.log("NEXT_PUBLIC_FIREBASE_USER_ID: ", NEXT_PUBLIC_FIREBASE_USER_ID)
console.log("NEXT_PUBLIC_FIREBASE_USER_ID: ", NEXT_PUBLIC_FIREBASE_USER_ID)
console.log("uid: ", props.uid)
console.log("process.env.NEXT_PUBLIC_FIREBASE_USER_ID: ", process.env.NEXT_PUBLIC_FIREBASE_USER_ID)
}, [])
return <Routes />;
}
export async function getServerSideProps() {
return {
props: {
uid: process.env.NEXT_PUBLIC_FIREBASE_USER_ID,
}
}
}
在 Cloud Run 日志中,该变量将通过 next.config.js 文件准确记录在服务器端,但所有客户端变量在浏览器中返回 undefined。
本地测试,我可以检索客户端变量就好了。
Dockerfile:
# Stage 1: Compile and Build the app
# Node veersion
FROM node:14.17.3-alpine as build
# 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 git
# Set the working directory
WORKDIR /app
# Add the source code to app
COPY ./js /app
# Install all the dependencies
RUN yarn install
RUN yarn bootstrap
# Generate the build of the application
RUN yarn build
# Stage 2: Serve app with nginx server
# Production image, copy all the files and run next
FROM node:14.17.3-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# Copy the build output to replace the default nginx contents.
COPY --from=build /app/packages/web/next.config.js ./
COPY --from=build /app/packages/web/public ./public
COPY --from=build --chown=nextjs:nodejs /app/packages/web/.next ./.next
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/packages/web/package.json ./package.json
USER nextjs
EXPOSE 3000
CMD ["yarn", "start:prod"]
enter code here
【问题讨论】:
-
我建议您按照 Next.js (Environment Variables) 的建议设置环境变量。无需在
next.config.js中进行额外设置。 -
@juliomalves 我无法使用 NEXT_PUBLIC_ 因为我正在使用
dotenv定义我的 .env 文件的自定义路径,并且 Next 在使用dotenv时禁用了他们的 ENV 功能我的项目是monorepo lerna 应用程序 -
@juliomalves 当我用
dotenv-webpack替换dotenv时,客户端环境变量也可以在本地工作,但不能在云端运行:( -
你能分享你的 dockerfile 吗?
-
@guillaumeblaquiere 是的,将其添加到原始问题的底部
标签: reactjs typescript google-cloud-platform next.js google-cloud-run