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.

Production deployment throws fetch error

default discord avatar
mr.dumbledore2 years ago
14

I was setting up my CI/CD pipeline for deploying my payload app to app engine, where I dockerize the app, push it GCR and then deploy the image to app engine.


I have been successful in doing so. But the react app is making request to

http://localhost:3000/api/users/me

instead of

<PROVIDED HOSTNAME>/api/users/me

.


I've tried passing all the different environment variables

PAYLOAD_PUBLIC_PAYLOAD_URL

,

PAYLOAD_PUBLIC_PAYLOAD_API

and

PAYLOAD_URL

.



Production deployment throws fetch error



import { buildConfig } from "payload/config";
import path from "path";
import Categories from "./collections/Categories";
import Posts from "./collections/Posts";
import Tags from "./collections/Tags";
import Users from "./collections/Users";
import Media from "./collections/Media";
import { gcsAdapter } from "@payloadcms/plugin-cloud-storage/gcs";
import { cloudStorage } from "@payloadcms/plugin-cloud-storage";

let adapter = gcsAdapter({
  options: {
    // apiEndpoint: process.env.GCS_ENDPOINT,
    projectId: process.env.GCS_PROJECT_ID,
  },
  bucket: process.env.GCS_BUCKET,
});

if (!process.env.PAYLOAD_PUBLIC_PAYLOAD_URL) {
  // throw new Error("");
  console.error("Cannot get the env variables");
}

export default buildConfig({
  serverURL: process.env.PAYLOAD_PUBLIC_PAYLOAD_URL ?? "http://localhost:3000",
  admin: {
    user: Users.slug,
  },

  collections: [
    Categories,
    Posts,
    Tags,
    Users,
    Media,
  ],
  plugins: [
    cloudStorage({
      collections: {
        media: {
          adapter,
        },
      },
    }),
  ],
  typescript: {
    outputFile: path.resolve(__dirname, "payload-types.ts"),
  },
  graphQL: {
    schemaOutputFile: path.resolve(__dirname, "generated-schema.graphql"),
  },
});


FROM node:18.8-alpine as base

FROM base as builder

WORKDIR /home/node/app
COPY package*.json ./

COPY . .
RUN yarn install
RUN yarn build

FROM base as runtime

ARG PAYLOAD_PUBLIC_PAYLOAD_URL="http://localhost"

ENV NODE_ENV=production
ENV PAYLOAD_CONFIG_PATH=dist/payload.config.js
ENV GCS_BUCKET=my-test-bucket-2002
ENV GCS_PROJECT_ID=payloadcms-test
ENV PAYLOAD_PUBLIC_PAYLOAD_URL=${PAYLOAD_PUBLIC_PAYLOAD_URL}

WORKDIR /home/node/app
COPY package*.json  ./

COPY key.json ./key.json
ENV GOOGLE_APPLICATION_CREDENTIALS=./key.json

RUN yarn install --production
COPY --from=builder /home/node/app/dist ./dist
COPY --from=builder /home/node/app/build ./build

# EXPOSE 3000

CMD ["node", "dist/server.js"]
  • discord user avatar
    alessiogr
    2 years ago
    @643912278244065292

    can you hard-code that serverURL field instead of using an environment variable and see if that works - just to test?

  • default discord avatar
    mr.dumbledore2 years ago
    @360823574644129795

    I did that as a temporary fix and it works. But I'm work on make it a reusable template with terraform for provisioning the infrastucture i.e creating storage bucket, provisioning mongodb database on atlas, enabling gcr, gae apis in gcp and a script that use github cli to add env secret to your git repo so that I can work on the schema and when I make a commit to the main branch the github actions deploy the new version of the app to app engine. In short, I want to automate all the tedious tasks before I start using it for something serious without going through the hassel setting things up.

  • default discord avatar
    hades2000822 years ago

    This is the same issue I had with DevOps deployment to Azure.



    The PAYLOAD_PUBLIC env cars have to be present when you run the “build” command to be compiled into the admin app



    If you’re using the dockerfile you’ll need to set the env var inside there before build is called.

  • default discord avatar
    mr.dumbledore2 years ago

    I figured that too and I used docker args to inject the variable from github secrets when building the docker image. But that didn't cut it, so I had to hardcode the url in the build config as a temporary fix.

  • default discord avatar
    hades2000822 years ago

    I found I had to have a different dockerfile for each environment and set the bars in the dockerfile

  • default discord avatar
    mr.dumbledore2 years ago

    I'm still trying make it work in a single environment i.e production. Once thats done then I'll move on working on provisioning different environment using IaaC and dedicate main and staging branch to deploy to those environment. But that's after I figure out this problem.

  • default discord avatar
    hades2000822 years ago

    After the issues I had I opened up a discussion on github

    https://github.com/payloadcms/payload/discussions/2288
  • default discord avatar
    mr.dumbledore2 years ago

    Did you hardcode the url in your config or did passing the environment variable at build time work for you?

  • default discord avatar
    hades2000822 years ago

    I created a separate Dockerfile for each environment and hardcoded a

    ENV PAYLOAD_PUBLIC_SERVER_URL=http....

    in each just above the

    npm install

    line.



    In DevOps Pipelines I then have a dynamic variable that selects which Dockerfile to build and publish based on the branch that triggered it.

  • default discord avatar
    mr.dumbledore2 years ago

    Though I'm exposing the endpoint in the repo currently, but that's not what I want it to be. I want to be able to pass the

    PAYLOAD_URL

    via some secrets manager like github for one.

  • default discord avatar
    hades2000822 years ago

    Basically we need the ability for the hosting environment variables to be passed to the admin (i.e. allow Admin to see/know about them at runtime rather than just at build time) ... not sure how feasible that is.

  • default discord avatar
    mr.dumbledore2 years ago

    Thats the problem I'm trying to figure out

  • default discord avatar
    hades2000822 years ago

    I think the safest solution at the moment is to use

    .env.xxxxxx

    files for all

    PAYLOAD_PUBLIC_

    vars and create a separate build script in package.json for each environment.



    This way, you don't need to set the public vars in any hosting environment, you just have them all in the relevant file and that gets deployed alongside the app.



    You can set private env vars in the hosting environment and use them in the Express server side of things still. This just means that some vars (like API keys) might require you to create a custom Express route that can use the private var, proxying the secured API.

  • default discord avatar
    mr.dumbledore2 years ago

    I guess this would have been lot easier than what I just did. I added an additional step that during the CD creates

    .env

    that holds all the env, currently its just the

    PAYLOAD_PUBLIC_

    and feeds this to docker during the build.

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.