node.jstypescriptbuildproductiondotenv

Why is production Build Not Reading .env Variables in Node.js (TypeScript)?


I'm having an issue with my Node.js backend project written in TypeScript. Locally, everything works fine, and my environment variables defined in the .env file are correctly loaded using the dotenv package. However, after building the project for production, the environment variables don't seem to be loaded when I run the built JavaScript files.

Here's what I'm doing:

Project Structure:

I'm using dotenv to load environment variables in my index.ts file. My index.ts file initializes an Express server and connects to a PostgreSQL database using Sequelize. After building the project using npm run build, I run the production build using node dist/index.js. Environment Variables:

I'm defining the variables in a .env file at the root of my project. Here's a sample of the .env file:

PORT=3000
POSTGRES_URL=postgres://default:****@*****:5432/verceldb?sslmode=require

Database Configuration:

My database.ts file reads the PostgreSQL connection string from the environment variables like this:

import { Sequelize } from 'sequelize';

const databaseUrl = process.env.POSTGRES_URL;

if (!databaseUrl) {
    throw new Error('Database URL is not defined');
}

console.log('Database URL:', databaseUrl);


const sequelize = new Sequelize(databaseUrl, {
    dialect: 'postgres',
    dialectOptions: {
        ssl: {
            require: true,
            rejectUnauthorized: false,
        },
    },
});

export default sequelize;

Production Build:

I build the project using the TypeScript compiler with npm run build. The tsc command generates JavaScript files in the dist/ directory.

When I try to run the production build with node dist/index.js, I get the following error:


throw new Error('Database URL is not defined');
    ^

Error: Database URL is not defined
    at Object.<anonymous> (/home/tauseef/fastiya/backend/dist/config/database.js:7:11)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Module._load (node:internal/modules/cjs/loader:1022:12)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (/home/tauseef/fastiya/backend/dist/index.js:11:36)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)

Node.js v20.12.2

What I've Tried:

  1. Verifying that dotenv.config() is called at the top of my index.ts file.
  2. Ensuring that the .env file is present in the root directory.
  3. Checking the deployment environment to ensure that the .env file is correctly configured and accessible.

Why aren't my environment variables from the .env file being loaded in the production build, and how can I fix this?


Solution

  • Problem is when you run build it doesn't generate .env in dist folder.

    You can have a script to copy the .env to dist folder

    "build": "cp .env ./dist/.env && tsc build"