I am using docker to build an image via Google Cloud Build > Google Cloud Registry. Then I have Pub/Sub triggers setup to populate Cloud Run instances with new Docker images on a successful build.
However my frontend code is unable to access the Cloud Run ENV variables I manually set in the dashboard (they return undefined
). I need to be able to build images without the ENVs already defined since I wish to have many Cloud Run instances based on the same image and inject ENVs later on.
I am using NEXT.js.
This is my 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: / ,
},
];
},
});
And my frontend
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,
}
}
}
In Cloud Run logs, the variable will log accurately on the server side via the next.config.js file but all of the client side variables return undefined
in the browser.
Locally testing, I can retrieve client side variables just fine.
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