Environment Variables — .env, .env.local, .env.production

~15 daq · Next.js · Deployment va DevOps

Muammodan boshlaylik

const stripe = new Stripe('sk_live_51Hx...')
const db = 'postgresql://admin:Parol123@db.dokon.uz/prod'

Maxfiy kalitlar kodda — va kod GitHub da. Bundan tashqari:

  • Development da test kalitlari, production da haqiqiylari kerak
  • Ba'zi qiymatlar brauzerga kerak (Google Analytics ID), ba'zilari hech qachon brauzerga ketmasligi kerak (bazaga parol)
  • Yangi dasturchi loyihani ishga tushirish uchun qaysi o'zgaruvchilar kerakligini bilmaydi

Hayotiy o'xshatma

Mehmonxona kalitlari. Xona raqami (ochiq qiymat) — hamma ko'rishi mumkin, eshikda yozilgan. Seyf kodi (maxfiy kalit) — faqat sizda. Har bir mehmonga (muhitga) — o'z kodi. Seyf kodini eshikka yozib qo'ymaysiz.


.env fayllari

Fayl Qachon yuklanadi Git ga
.env Hamma muhitda ✅ (maxfiy bo'lmagan standart qiymatlar)
.env.local Hamma muhitda (test dan tashqari), ustidan yozadi ❌
.env.development next dev ✅
.env.production next build, next start ✅
.env.development.local, .env.production.local Shu muhit, eng yuqori ustuvorlik ❌
.env.test NODE_ENV=test (Vitest) ✅

Ustuvorlik (yuqoridan pastga): process.env (tizim) → .env.$(NODE_ENV).local → .env.local → .env.$(NODE_ENV) → .env.

# .env.local — sizning shaxsiy, git da emas
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/dokon"
AUTH_SECRET="development-uchun-tasodifiy-satr"
STRIPE_SECRET_KEY="sk_test_..."
NEXT_PUBLIC_SITE_URL="http://localhost:3000"

create-next-app .gitignore ga .env* ni allaqachon qo'shgan.


Server va brauzer

Faqat server — oddiy nom

// Server Component, Route Handler, Server Action
const db = process.env.DATABASE_URL

Brauzerga hech qachon ketmaydi. Client Component da process.env.DATABASE_URL — undefined.

Brauzer uchun — NEXT_PUBLIC_

NEXT_PUBLIC_SITE_URL="https://dokon.uz"
NEXT_PUBLIC_GA_ID="G-XXXXXXX"
'use client'
const url = process.env.NEXT_PUBLIC_SITE_URL
  • NEXT_PUBLIC_ o'zgaruvchilar build paytida JavaScript ga matn sifatida yoziladi
  • Ularni o'zgartirish — qayta build talab qiladi
  • Ular ochiq: har kim brauzer kodida ko'radi

[!WARNING] NEXT_PUBLIC_ prefiksini maxfiy kalitga hech qachon qo'ymang: NEXT_PUBLIC_STRIPE_SECRET_KEY, NEXT_PUBLIC_DATABASE_URL, NEXT_PUBLIC_OPENAI_KEY — bu kalitni butun dunyoga e'lon qilish. Brauzerga faqat ochiq qiymatlar: sayt manzili, analitika ID, publishable (ochiq) kalitlar.


Dinamik o'qish — runtime

NEXT_PUBLIC_ qiymatlari build da "muzlatiladi". Bitta Docker image ni turli muhitlarda (staging, production) ishlatmoqchi bo'lsangiz — bu muammo. Yechim: qiymatni serverda o'qib, client ga uzatish:

// app/layout.tsx (Server Component)
export default function RootLayout({ children }: { children: React.ReactNode }) {
  const sozlama = { saytUrl: process.env.SITE_URL, gaId: process.env.GA_ID }
  return (
    <html lang="uz">
      <body>
        <SozlamaProvider qiymat={sozlama}>{children}</SozlamaProvider>
      </body>
    </html>
  )
}

Dinamik render qilinadigan sahifalarda server o'zgaruvchilari so'rov paytida o'qiladi.


Tekshirish — Zod bilan

// lib/env.ts
import 'server-only'
import { z } from 'zod'

const schema = z.object({
  DATABASE_URL: z.string().url(),
  AUTH_SECRET: z.string().min(32),
  STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
  NODE_ENV: z.enum(['development', 'test', 'production']),
})

export const env = schema.parse(process.env)
import { env } from '@/lib/env'
const stripe = new Stripe(env.STRIPE_SECRET_KEY)

O'zgaruvchi yo'q yoki noto'g'ri bo'lsa — ilova darhol aniq xato bilan to'xtaydi, yarim tunda emas. @t3-oss/env-nextjs paketi server/client o'zgaruvchilarini alohida tekshirish va client da server o'zgaruvchisiga murojaatni taqiqlash imkonini beradi.


Jamoa uchun — .env.example

# .env.example — git da, qiymatlarsiz
DATABASE_URL=
AUTH_SECRET=            # npx auth secret
STRIPE_SECRET_KEY=      # Stripe Dashboard → Developers → API keys (test)
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Yangi dasturchi: cp .env.example .env.local → qiymatlarni to'ldiradi.


Production da

Production serverda .env fayllar odatda ishlatilmaydi — o'zgaruvchilar platforma orqali beriladi:

Platforma Qayerda
Vercel Project → Settings → Environment Variables (66-dars)
Docker docker run --env-file, Compose environment (67-dars)
VPS PM2 ecosystem.config.js, systemd EnvironmentFile (68-dars)
GitHub Actions Repository Secrets (69-dars)

[!TIP] Vercel da: vercel env pull .env.local — platformadagi development o'zgaruvchilarini lokal faylga tortib oladi. Jamoa bir xil sozlamalar bilan ishlaydi.


Tez-tez uchraydigan xatolar

1. Client da undefined

process.env.API_URL Client Component da — NEXT_PUBLIC_ prefiksi yo'q. Lekin maxfiy bo'lsa — prefiks qo'shmang, serverda ishlating.

2. .env.local ni o'zgartirib, serverni qayta ishga tushirmaslik

next dev o'zgaruvchilarni ishga tushishda o'qiydi (ba'zi versiyalar .env ni qayta yuklaydi, lekin ishonmang).

3. Kalit git tarixida

Faylni o'chirish yetmaydi — kalit tarixda qoladi. Kalitni almashtiring (rotate).

4. Dinamik kalit nomi

// ❌ — build da almashtirilmaydi
process.env[`NEXT_PUBLIC_${nom}`]

// ✅ — to'liq nom
process.env.NEXT_PUBLIC_GA_ID

Xulosa

.env (standart) → .env.local (shaxsiy, git da emas) → .env.[muhit] → .local
Oddiy nom — faqat server; NEXT_PUBLIC_ — brauzerga, build da yoziladi, OCHIQ
Maxfiy kalit — hech qachon NEXT_PUBLIC_ emas
Runtime qiymat client ga — server da o'qib, prop/provider orqali
Zod bilan tekshirish — darhol aniq xato
.env.example — jamoa uchun; production — platforma sozlamalari
Sizib chiqqan kalit — almashtiring

Keyingi dars

66-dars: Vercel — deploy qilish, environment, domain sozlash

Next.js ni yaratuvchilarning platformasiga bir necha daqiqada joylash.