۱۷ — Environment و Secrets
Stack: Next.js full-stack — بدون FastAPI/RabbitMQ/Celery
.env.local (root پروژه Next.js)
env
# ─── App ─────────────────────────────────────
APP_NAME=TakeEat
APP_ENV=development
NEXT_PUBLIC_APP_NAME=TakeEat
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Stage: true — noindex + robots Disallow (see src/lib/indexing.ts)
BLOCK_SEARCH_INDEXING=false
# ─── Database ────────────────────────────────
DATABASE_URL=postgresql://TakeEat:TakeEat@localhost:5432/TakeEat
# ─── Redis ───────────────────────────────────
REDIS_URL=redis://localhost:6379
# ─── JWT ─────────────────────────────────────
JWT_SECRET=change-me-in-production-min-64-random-chars
JWT_REFRESH_SECRET=change-me-in-production-min-64-random-chars-refresh
JWT_ACCESS_TTL_MINUTES=15
JWT_REFRESH_TTL_DAYS=30
# ─── Admin login rate limit (optional) ───────
ADMIN_LOGIN_MAX_ATTEMPTS=5
ADMIN_LOGIN_WINDOW_SEC=900
# ─── OTP ─────────────────────────────────────
OTP_TTL_SECONDS=120
OTP_MAX_ATTEMPTS=5
OTP_SEND_COOLDOWN_SECONDS=60
OTP_SEND_LIMIT_PER_HOUR=3
# ─── SMS — Panelchi (primary) / Kavenegar (legacy) ─
SMS_DEV_MODE=true
PANELCHI_API_KEY=
PANELCHI_SOURCE_NUMBER=10001
PANELCHI_OTP_PATTERN=takeeat-otp # optional — pattern slug in panel
KAVENEGAR_API_KEY= # fallback if PANELCHI_* empty
KAVENEGAR_SENDER=
# ─── Payment — Zarinpal ──────────────────────
ZARINPAL_MERCHANT_ID=
ZARINPAL_SANDBOX=true
ZARINPAL_CALLBACK_URL=http://localhost:3000/api/payments/zarinpal/callback
# ─── Cron ────────────────────────────────────
CRON_SECRET=change-me-random-secret
# اگر روی Vercel: در dashboard تنظیم کنید
# ─── Ops (server — doc/23-self-host-ops.md) ──
ARVAN_API_KEY= # DNS automation + certbot
KUMA_USERNAME= # بعد از ساخت admin در status.takeeat.ir
KUMA_PASSWORD=
# Caddy basic auth → /etc/caddy/ops.env (OPS_BASIC_AUTH_USER/HASH) — server only
# ─── Upload ──────────────────────────────────
MAX_UPLOAD_MB=5
# اگر Arvan/Liara S3 اضافه شد:
# S3_ENDPOINT=
# S3_BUCKET=
# S3_ACCESS_KEY=
# S3_SECRET_KEY=CORS / Origin
Next.js همه در یک origin است — CORS نیاز نیست.
API فقط از همان next.js app صدا زده میشود.
Ports (docker-compose dev)
| Service | Port |
|---|---|
| next (dev) | 3000 |
| postgres | 5432 |
| redis | 6379 |
Test Environment
برای API integration tests از .env.test استفاده میشود. فایل نمونه: ../.env.test.example
env
DATABASE_URL=postgresql://takeeat:takeeat@localhost:5432/takeeat_test
REDIS_URL=redis://localhost:6379/1
SMS_DEV_MODE=true
ZARINPAL_MERCHANT_ID=test-merchant
CRON_SECRET=test-cron-secretراهاندازی لوکال:
bash
docker compose up -d
npm run db:test:setup
npm run test:integrationدر CI از دیتابیس ephemeral همان job استفاده میشود و workflow reusable-test.yml قبل از build، npm run test:ci را اجرا میکند.
docker-compose.yml
yaml
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: TakeEat
POSTGRES_USER: TakeEat
POSTGRES_PASSWORD: TakeEat
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:Secrets handling
| Secret | کجا | هرگز |
|---|---|---|
JWT_SECRET | server env | git، client bundle |
PANELCHI_API_KEY | server env | client bundle، log |
KAVENEGAR_API_KEY | server env (legacy) | client bundle، log |
ZARINPAL_MERCHANT_ID | server env | client |
DATABASE_URL | server env | git |
CRON_SECRET | server env | git |
ARVAN_API_KEY | server env | git |
KUMA_USERNAME / KUMA_PASSWORD | server env | git |
OPS_BASIC_AUTH_* | /etc/caddy/ops.env | git |
قانون: هر متغیری که NEXT_PUBLIC_ ندارد → فقط server-side قابل دسترس است.
Production checklist
- [ ]
JWT_SECRET→ random 64+ char (openssl rand -base64 48) - [ ]
SMS_DEV_MODE=false - [ ]
PANELCHI_API_KEY+PANELCHI_SOURCE_NUMBERتنظیم (یا Kavenegar legacy) - [ ]
BLOCK_SEARCH_INDEXING=false(فقط prod — stage بایدtrueبماند) - [ ]
ZARINPAL_SANDBOX=false - [ ]
NEXT_PUBLIC_APP_URL→ دامنه نهایی - [ ]
ZARINPAL_CALLBACK_URL→ دامنه نهایی - [ ]
DATABASE_URL→ production DB با password قوی - [ ]
.env.localدر.gitignore - [ ] HTTPS روی دامنه (Caddy auto HTTPS)
تفاوت با نسخه قبلی (FastAPI)
| حذف شده | دلیل |
|---|---|
RABBITMQ_URL | بدون Celery/RabbitMQ |
CORS_ORIGINS | یک origin (Next.js) |
| Python-specific vars | یک زبان |