Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Env/environment variable undefined on deployments

default discord avatar
augdustlast year
17

i'm trying to set up a dynamic env variable based on environment.



what im trying to do is have a env-variable for a URL to use for livepreview that is localhost when running locally, a specific URL when the project is deployed to dev environment and another URL when the project is deployed to a prod environment.



we are using gitlab and openshift, and i have defined the variable in gitlabs CI/CD settings with different value per environment, but on my deployed app it's still rendering as "undefined".



have tried importing and running "dotenv.config()" in my server.ts-file and payload.config.ts file.



I believe I might have to add the variable to my Dockerfile, but not sure how to do that when I want the variable to be dynamic based on environment. Would love any help/pointers :)



Tried creating two Dockerfiles, one for dev and one for prod and adding the variable in there as well - it's still showing up as undefined in the browser

  • default discord avatar
    notchrlast year
    @170674545965924352

    Are all of the variables ones you would expect to log in browser?



    They are prefixed with PAYLOAD_PUBLIC ?

  • default discord avatar
    augdustlast year

    they are prefixed with PAYLOAD_PUBLIC, and they make their way to the deployment in openshift just fine.



    i suspect it's because I'm trying to reference them from a collectionconfig-file, which probably runs on the client, while the env-variables are stored on the server

  • default discord avatar
    notchrlast year

    even the public ones?



    Oh i see what you're saying



    What kind of env vars would you want to have for the client?

  • default discord avatar
    augdustlast year

    i am setting up live preview, and need the URL for that property to be dynamic based on deployment environment. thought it'd be nice to use an env variable for it, but it's a struggle being able to read it from the client haha

  • default discord avatar
    weetikveelmanlast year

    Sounds like you are doing everything correct so I don't know what the problem could be, but maybe the live-preview example can help to spot differences

    https://github.com/payloadcms/payload/tree/main/examples/live-preview/payload#quick-start

    (might also be worth checking that the example works)

  • default discord avatar
    augdustlast year

    i believe my issue might be related to how Openshift runs my deployment - i suspect my collection runs on the client and my .env-variables are stored on the server, hence them returning "undefined" even though they show up with correct info in my configmap in the openshift deployment itself.



    not sure how to check/verify if my suspicion is correct, and if it is correct, how to work around it 🥴



    Found a fix! I had placed the env variables after the build in my Dockerfiles, moving them up before it runs the build process fixed it :)

  • default discord avatar
    rentpromptslast year

    how did this get fixed ? I am trying to push payload cms to hetzner through coolify using Dockerfile and I am not getting env variables as it is looking for .env file which isnt there.

  • default discord avatar
    markatomniuxlast year

    Hey

    @170674545965924352

    , would you mind sharing an example of this in your Dockerfile? I've run into a similar problem since doing a Turbopack & Docker deployment and wanted to see which one was causing the issue

  • default discord avatar
    augdustlast year

    My Dockerfile looks like this:



    FROM node:18.8-alpine as base
    
    FROM base as builder
    
    WORKDIR /
    COPY package*.json ./
    
    ARG PAYLOAD_PUBLIC_SOME_URL=https://some.site
    ENV PAYLOAD_PUBLIC_SOME_URL=$PAYLOAD_PUBLIC_SOME_URL
    
    ARG PAYLOAD_PUBLIC_OTHER_URL=https://some.other.site
    ENV PAYLOAD_PUBLIC_OTHER_URL=$PAYLOAD_PUBLIC_OTHER_URL
    
    ARG PAYLOAD_PUBLIC_ANOTHER_URL=https://another.site
    ENV PAYLOAD_PUBLIC_ANOTHER_URL=$PAYLOAD_PUBLIC_ANOTHER_URL
    
    COPY . .
    RUN npm install
    RUN npm run build
    
    FROM base as runtime
    
    ENV NODE_ENV=production
    ENV PAYLOAD_CONFIG_PATH=dist/payload.config.js
    
    WORKDIR /
    COPY package*.json  ./
    COPY /src/assets ./
    
    RUN npm install --production
    COPY --from=builder /dist ./dist
    COPY --from=builder /build ./build
    
    EXPOSE 3030
    
    CMD ["node", "dist/server.js"]
  • default discord avatar
    markatomniuxlast year

    ahh of course



    Would I be correct in thinking you could leave ARG empty seeing as those values will get populated when you run your container

  • default discord avatar
    augdustlast year

    i know next to nothing about Docker, so I dont really know



    :kek_dog:

    this just worked for me

    :shrugok:
  • default discord avatar
    rentpromptslast year

    I have one question, why does payload requires env variables at build time ? like db url, cloud storage s3 envs ? I dont think it is safe ? or envs in payload config is for only static content at server side ?

  • default discord avatar
    markatomniuxlast year

    It requires react environment variables at build time. This is actually not unique to Payload. In a server context, the environment variables can be substituted at run time, but with React, Webpack does the variable replacement during build in order to generate a static bundle



    Just to be clear, only variables that require PAYLOAD_PUBLIC are required at build time. All other environment variables can be substituted at run time

  • default discord avatar
    rentpromptslast year

    Yeah but don’t you think db url and s3 envs at payload config (with PAYLOAD_CONFIG) isn’t a safe option ? May be my understanding is wrong about it.

  • default discord avatar
    markatomniuxlast year

    Your DB url can be set using runtime environment variables. Db is never used in react and thus Webpack does not require it. Only the express side of payload uses the db



    The payload config does not reach your frontend code. It is used to configure your express app and Webpack settings for react

  • default discord avatar
    rentpromptslast year

    Gotcha! Good to know about the payload config doesn’t pass to build and I did the test myself. Got little confused about db url as I’ve given as build time var, without build time it doesn’t passes my build, as per your comment I can replace db url at run time, it means I can have different value at run time and build time ? What if I don’t want to declare it as build time var ? Can I give a mock url for webpack to build ?

  • default discord avatar
    ritsu0455last year

    theoretically, you can have a normal (not a public one) env variable + an endpoint on the backend that just returns it. Then, on the frontend, you fetch and save it into some provider to have access anywhere



    with server components it's even easier and SSR-friendly, just pass it down to a client component (but as value directly, not the whole

    process.env

    )



    public env vars suck really in a dockerized envs , you only need them for the SSG process (because you do that at the build time).

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.