There is really only one main possibility here and you need to do a little bit of your own debugging to verify it.
Because this statement does not generate an error:
const config = require(path.join(__dirname, '..', 'config', 'config.json'))[env];
That means that require(path.join(__dirname, '..', 'config', 'config.json')) is returning a Javascript object. So, there must indeed be a file at the path you construct and it must be giving you an object when you require() it.
But, the error itself: TypeError: Cannot read property 'database' of undefined when you try to reference config.database means that config is undefined. The only way that happens is that you're using a value for env that is not in your config object.
That's like trying to do this:
const obj = {development: {someKey: "someValue"}}; // what require() gives you
const env = "test"; // your value for env
const config = obj[env]; // reading non-existent [env] property
console.log(config); // undefined
So, add console.log(env) to your code to see what env actually is and then verify that you have an object in your config data structure for that specific value (or set the desired value in the environment).
If you had verified the value of env yourself with basic debugging steps before posting here, you probably would have solved your own problem (hoping you can learn simple techniques to solve more of your own problems).
If you didn't follow all of my original logic, you could also just debug it like this:
const env = process.env.NODE_ENV || "development";
console.log("env: ", env);
const configPath = path.join(__dirname, '..', 'config', 'config.json');
console.log("configPath: ", configPath);
const configObj = require(configPath);
console.log("configObj: ", configObj);
const config = configObj[env];
console.log("config: ", config);
envbeing set todevelopment? Or is there something else inprocess.env.NODE_ENVNODE_ENVtoproduction.config.jsonand renamed to "production" so will see if that does it. Deploying now...