Kodokon kodokon.com

Configuration and secrets

Pull configuration out of the code with dotenv, separate development from production, and keep your secrets out of Git.

8 min · 3 questions

Open this lesson in Kodokon

The listening port, the database URL, the API keys: none of these belong in the source code. These values change between your machine and production, and some are secrets. The standard solution: environment variables, loaded from a .env file in development. Install dotenv with npm install dotenv, then create the file at the root of the project.

BASH
PORT=3000
DATABASE_URL=postgres://localhost:5432/kodokon
SESSION_SECRET=change-this-value
.env - one variable per line

Import dotenv/config at the very start of your entry point: the file's variables are copied into process.env. A good professional habit: centralize the reading in a single configuration module, validate the variables at startup, and fail immediately if one is missing. A server that refuses to start is better than a server that crashes on the first request.

JAVASCRIPT
import "dotenv/config";

const required = ["PORT", "SESSION_SECRET"];

for (const name of required) {
  if (!process.env[name]) {
    throw new Error("Missing variable: " + name);
  }
}

export const config = {
  port: Number(process.env.PORT),
  secret: process.env.SESSION_SECRET,
  isProd: process.env.NODE_ENV === "production"
};
config.js - the only module that reads process.env

In production, there's no .env file: the host provides the real values, and NODE_ENV is production. Use config.isProd to adapt behavior: detailed logs in development, restrained error messages in production. Also commit a .env.example file listing the expected variables with dummy values: it documents the configuration without exposing the secrets.

JAVASCRIPT
import express from "express";
import { config } from "./config.js";

const app = express();

if (!config.isProd) {
  console.log("Development mode");
}

app.listen(config.port, () => {
  console.log("Port: " + config.port);
});
server.js - the rest of the code ignores process.env

Knowledge check

Make sure you remember the key points of this lesson.

  1. Where do you put the database password?
    • In a constant in the source code
    • In a .env file ignored by Git
    • In the project README
    • In a comment in the configuration file
  2. What is the purpose of the .env.example file?
    • To hold the real backup values
    • To document the expected variables, without sensitive values
    • To configure the test environment
  3. A secret was committed by mistake. What do you do first?
    • Delete the commit and move on
    • Revoke the secret and generate a new one
    • Add the file to .gitignore