Hello!
I've made a small util for batch uploading images. In my local environment, it works fine. But in production (northflank),
fetch
is returning 404 because
process.env.PAYLOAD_PUBLIC_PAYLOAD_API
is
undefined
. I've double checked that the correct env var is in production, and I'm out of ideas of what can be the problem :/
Here's a snippet from the upload function:
const uploadFile = async (file): Promise<string> => {
const formData = new FormData();
formData.append("file", file);
const response = await fetch(
`${process.env.PAYLOAD_PUBLIC_PAYLOAD_API}/media`,
{
method: "POST",
body: formData,
}
);
return `${file.path} – ${response.status} ${response.statusText}`;
};
@arielarial What about other env vars?
@notchr there's only one other paylod_public var:
PAYLOAD_PUBLIC_PAYLOAD_URL
, which I'm using in payload.config for
serverURL
prop
How are you verifying the env vars on that platform? Are the vars set during
the buildof the frontend bundle?
@denolfe I've just checked on the container logs:
2023-02-17T21:21:01.069936761Z stdout F [2023-02-17T21:21:01Z INFO ] Successfully fetched environment variables.
2023-02-17T21:21:00.742615986Z stdout F [2023-02-17T21:21:00Z INFO ] Securely fetching environment variables...
It is also in the Build logs:
2023-02-17T21:15:58.44691136Z stdout F [2023-02-17T21:15:58Z INFO ] Successfully fetched environment variables.
2023-02-17T21:15:58.409839571Z stdout F [2023-02-17T21:15:58Z INFO ] Securely fetching environment variables...
This is a monorepo, and payload is in the
cms
folder. I had to change the Docker file a little bit to make it work. Could this be the problem?
Env variables are only available on the serverside, you would have to configure webpack to replace them in the clientside build.
To clarify, Payload
already does this substitutioninto the frontend bundle if the proper PAYLOAD_PUBLIC prefix is used.
@arielarial Are you able to log the
actual valuesto be certain they're being loaded?
Thanks @thgh. and @denolfe !
The values aren't being loaded :/ I made a local build to check if it was some issue in northflank, but logging a
process.env.PAYLOAD_PUBLIC_XXXX
env var is returning undefined in the frontend
@arielarial Not sure if this is helpful, but you can access your env vars in your webpack config
And then you can use something like Define plugin
new webpack.DefinePlugin({
'process.env.foo': 'bar'
})
and then thats available on process.env in your app
Webpack also accepts an env command
webpack --config webpack.config.js --env.foo=bar
Thanks, @notchr ! I'm trying to find out why Payload isn't exposing public env vars (as Elliot said). I think is better to make this work as intended. But I will try that approach if I can't figure this out, thanks!
I was ready to dig in payload's source code, and found an issue about this solved by @jarrod_not_jared
Adding this in the top of my payload config file solved the problem:
import path from 'path';
import dotenv from 'dotenv';
dotenv.config({
path: path.resolve(__dirname, '../.env'),
});
Source:
https://github.com/payloadcms/payload/issues/1654#issuecomment-1355693467Thanks again @denolfe and @notchr 🙂
Okay, so you weren't pointing to where the actual .env file was before this, therefore no values were being loaded 👍
@denolfe I guess that's it.
So in production I should do a custom build script.
But where should I store the fetched env vars, so Payload can expose them?
// customAdminBuild.js
const path = require('path');
// Tell Payload where to find your Payload config - can do it either here, or in package.json script
process.env.PAYLOAD_CONFIG_PATH = path.resolve(__dirname, 'src/payload.config.ts');
const { build } = require('payload/dist/bin/build');
const buildPayloadAdmin = async () => {
// Fetch your environment variables here
// And then run `build`
build();
}
buildPayloadAdmin();
You shouldn't need this. The create-payload-app scaffolds this out for you. It does this:
"build:payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload build"
I'm not sure what problem you're trying to solve
Depending on if you have a CI process or not. The most straight-forward deploy would be to just have a separate .env file for prod
and it's always in the spot your code loads from
My initial problem was that using a PAYLOAD_PUBLIC env var in a collection hook was working in development but not in production.
After setting
dotenv.config
, it worked for builds in my machine, as I do have an .env file to point to.
But now I'm not sure how to solve this in production, as I'm deploying to Northflank via Github
The .env files are not being commited, because they have credentials. I've set the environment variables in the admin panel configs for this project
I thought that I would need to use the snippet above to fetch the PAYLOAD_PUBLIC env vars and set them somehow, in
buildPayloadAdmin
, before calling payload's build
Hi @denolfe, did this make sense? I'm stuck on this now
@arielarial Github / Gitlab allow you to set enviornment variables through the control panel
So that your project can securely reference them
https://docs.github.com/en/actions/learn-github-actions/variables
Didn't know about that! But still, this won't produce an .env file, which is what payload is expecting from me to point at. It looks like this works just like Northflank's environment variables, which are available at build, but that I can't make Payload expose to the frontend
Those env vars will need to be set during build time. Payload doesn't care
howyou go about reading in those env vars, that's more of a CI concern for you to solve.
to add,
the .env file is only one method of declaring .env variables- you don't need to use it at all
Northflank likely lets you set env vars another way in their interface
typically platforms like Northflank + Vercel / + Netlify, etc. allow you to set env variables in their own CI
^^ yep
AKA no need for
.env
in that point
Thank you all for the responses! I am setting my env vars via Northflank's panel:
The problem is: during build, I'm using this vars to build Payload without problems.
But in Payload's admin interface I'm using a hook that needs payload api url. That is one of my env vars, that is not being set for the admin panel of payload.
At this point I was asking myself if there's another easier way to get payload REST API URL from inside a hook? Is this exposed in any var?
Recently used this, based on how it's done in Payload internally:
const { serverURL, routes: { api } } = useConfig()
fetch(
`${serverURL}${api}/${props.relationTo}`,
{ method: 'POST', body }
).then((r) => r.json())
Thank you so much, @thgh. ! I'm gonna try this, but it seems to be exactly what I need
@arielarial Could you share your batch upload snippet?
I've deploy my payload app to app engine I've specified PAYLOAD_PUBLIC_PAYLOAD_URL, PAYLOAD_PUBLIC_PAYLOAD_API, PAYLOAD_URL but the react app is still making request to
http://localhost:3000/api/user/me. What should I do?
sure @joekr ! I made a gist for it. Just note that this was more like a POC, and I never ended up using it in production. So there are quite a few adjustments and verifications left to do:
@arielarial any suggestions for me?
hi @mr.dumbledore ! I was going to suggest that you make a new thread, but I see you already did that 🙂 I'm sorry but I don't know what could be your problem. I think it would help if you add a snippet of your payload.config to that thread
I just did
sorry to bump such an old thread but thank you @thgh.!
Yes thank you @thgh. helped a bunch!
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.