Friday, September 18, 2026

3..env

 

Complete .env Guide


1. What is .env

.env = environment variables file
     = a file that stores sensitive or environment-specific values
       outside your actual code

Simple text file. Just key=value pairs.

DATABASE_URL=postgres://user:pass@localhost:5432/mydb
JWT_SECRET=mysecretkey123
PORT=5000

2. Where .env is Used — React, Node or Both

Both use .env but for different purposes.

main-folder/
├── react/
│   └── .env          ← React's own .env
├── nodejs/
│   └── .env          ← Node's own .env
└── docker-compose.yml

React .env — Frontend Config Only

REACT_APP_API_URL=https://yourdomain.com/api
REACT_APP_GOOGLE_MAPS_KEY=AIzaSyXXXXXXXX
REACT_APP_APP_NAME=MyApp

Rule: React env variables MUST start with REACT_APP_
Otherwise React ignores them completely.

Node .env — Backend + Database + Secrets

PORT=5000
DATABASE_URL=postgres://user:pass@db:5432/mydb
JWT_SECRET=supersecretkey
EMAIL_USER=noreply@yourdomain.com
EMAIL_PASS=emailpassword123
RAZORPAY_KEY=rzp_live_XXXXXXXX
RAZORPAY_SECRET=XXXXXXXXXXXXXXX
NODE_ENV=production

3. What Each .env Variable Does

Node .env breakdown

PORT=5000
# Which port your Node server runs on

DATABASE_URL=postgres://user:pass@db:5432/mydb
# Full connection string to Postgres
# user     = postgres username
# pass     = postgres password
# db       = docker service name (hostname)
# 5432     = postgres port
# mydb     = database name

JWT_SECRET=supersecretkey
# Used to sign and verify login tokens
# If leaked → anyone can fake login as any user

NODE_ENV=production
# Tells your app which environment it is running in
# Changes behavior — logging, error messages, optimizations

EMAIL_USER=noreply@yourdomain.com
EMAIL_PASS=emailpassword123
# SMTP credentials for sending emails

RAZORPAY_KEY=rzp_live_XXXXXXXX
RAZORPAY_SECRET=XXXXXXXXXXXXXXX
# Payment gateway credentials

React .env breakdown

REACT_APP_API_URL=https://yourdomain.com/api
# The base URL React uses to call your Node API
# In development → http://localhost:5000/api
# In production  → https://yourdomain.com/api

REACT_APP_GOOGLE_MAPS_KEY=AIzaSyXXXXXXXX
# Public API keys that browser needs directly

4. How .env is Used in Code

In Node (server.js)

// First install dotenv package
// npm install dotenv

// At top of server.js
require('dotenv').config()

// Now use anywhere in your code
const PORT = process.env.PORT
const db = process.env.DATABASE_URL
const secret = process.env.JWT_SECRET

// Example usage
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`)
})

// Database connection
const pool = new Pool({
    connectionString: process.env.DATABASE_URL
})

// JWT signing
const token = jwt.sign(payload, process.env.JWT_SECRET)

In React (any component)

// No extra package needed
// React reads .env automatically at build time

const API_URL = process.env.REACT_APP_API_URL

// Example usage
const response = await fetch(`${API_URL}/users`)

// In development hits → http://localhost:5000/api/users
// In production hits  → https://yourdomain.com/api/users

5. How .env Helps in Production

The Problem Without .env

// BAD — values hardcoded in code
const pool = new Pool({
    host: 'localhost',
    password: 'mypassword123',    // visible to everyone
    database: 'mydb'
})

// pushed to git → anyone who sees your repo
// sees your database password

The Solution With .env

// GOOD — values come from environment
const pool = new Pool({
    connectionString: process.env.DATABASE_URL
    // actual password never appears in code
    // never pushed to git
})

Production Benefits

Local .env                    Production .env
──────────────────            ──────────────────────────
DATABASE_URL=localhost         DATABASE_URL=prod-db-server
NODE_ENV=development           NODE_ENV=production
JWT_SECRET=devkey123           JWT_SECRET=Xk9#mP2$qL8@nR5!
PORT=5000                      PORT=5000

Same code runs in both environments
Just .env values change
No code changes needed

6. .env and .gitignore — Critical Step

.env must NEVER be pushed to git.

# Create .gitignore in each folder
nano .gitignore
# Inside .gitignore
.env
node_modules/
build/
git push
    ↓
.gitignore blocks .env from uploading
    ↓
Git repo has NO passwords or secrets
    ↓
Safe to make repo public or share with team

What gets pushed vs what stays local

Gets pushed to git          Stays on machine only
──────────────────          ──────────────────────
server.js                   .env
package.json                node_modules/
Dockerfile                  build/
docker-compose.yml
.gitignore
.env.example                ← this gets pushed (see below)

7. .env.example — Industry Standard Practice

You push a .env.example file to git so teammates know what variables are needed — but with no real values.

# nodejs/.env.example
PORT=
DATABASE_URL=
JWT_SECRET=
NODE_ENV=
EMAIL_USER=
EMAIL_PASS=
RAZORPAY_KEY=
RAZORPAY_SECRET=
# react/.env.example
REACT_APP_API_URL=
REACT_APP_GOOGLE_MAPS_KEY=

New developer joins team:

git clone repo
cp .env.example .env
# fill in real values
# app runs immediately

8. If .env is NOT Used — Pros and Cons

Pros (almost none)

✓ Slightly simpler for a throwaway script
✓ One less file to manage

Cons (serious problems)

✗ Passwords hardcoded in code
  → visible to anyone with repo access

✗ Code pushed to GitHub with real credentials
  → bots scan GitHub and steal credentials within minutes

✗ Different values for dev and production
  → must manually change code every deployment
  → high risk of deploying wrong values

✗ Team members see production passwords
  → security risk

✗ Payment keys, JWT secrets in plain code
  → major security breach risk

✗ Cannot change password without changing code
  → requires new git commit and deployment

9. How to Create .env — Step by Step

Local Development

# Go into nodejs folder
cd nodejs

# Create .env file
touch .env

# Open and add variables
nano .env
PORT=5000
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
JWT_SECRET=devlocalsecretkey
NODE_ENV=development
EMAIL_USER=test@gmail.com
EMAIL_PASS=testpassword
# Go into react folder
cd ../react

# Create .env file
touch .env
nano .env
REACT_APP_API_URL=http://localhost:5000/api
REACT_APP_APP_NAME=MyApp

On Production Server

# SSH into server
ssh user@your-server-ip

# Go to your project
cd /home/user/your-repo/nodejs

# Create production .env
nano .env
PORT=5000
DATABASE_URL=postgres://user:strongpassword@db:5432/mydb
JWT_SECRET=Xk9#mP2$qL8@nR5!vB3&wZ7
NODE_ENV=production
EMAIL_USER=noreply@yourdomain.com
EMAIL_PASS=realemailpassword
RAZORPAY_KEY=rzp_live_XXXXXXXX
RAZORPAY_SECRET=XXXXXXXXXXXXXXX

10. .env with Docker — How It Connects

Option 1 — Docker reads .env file directly

# docker-compose.yml
services:
  backend:
    build: ./nodejs
    env_file:
      - ./nodejs/.env        ← docker reads this file
    ports:
      - "5000:5000"

  db:
    image: postgres:15
    env_file:
      - ./nodejs/.env        ← postgres gets credentials from same file

Option 2 — Hardcode in docker-compose (not recommended)

services:
  backend:
    environment:
      - PORT=5000
      - JWT_SECRET=mysecret   ← secret visible in docker-compose

Option 1 is always better — secrets stay in .env, not in docker-compose.


11. Industry Standard Summary

Rule 1:  .env never goes to git
Rule 2:  .env.example always goes to git
Rule 3:  Production .env has stronger secrets than dev
Rule 4:  Never hardcode passwords, keys, URLs in code
Rule 5:  Each environment has its own .env
         (local, staging, production)
Rule 6:  Rotate secrets regularly (change passwords periodically)
Rule 7:  Minimum access — .env only contains what that service needs

12. Complete Picture

YOUR CODE (git repo)              YOUR SECRETS (.env)
────────────────────              ──────────────────────
server.js                         PORT=5000
  process.env.PORT          ←───  DATABASE_URL=postgres://...
  process.env.JWT_SECRET    ←───  JWT_SECRET=Xk9#mP2$...
  process.env.DATABASE_URL  ←───  NODE_ENV=production

Code is public safe               .env stays private
Push to git freely                Never pushed to git
Same code everywhere              Different per environment

One codebase. Multiple environments. Zero hardcoded secrets. That is the purpose of .env.

No comments:

Post a Comment