Notty Configuration Model
Техническое руководство из исходного проекта Notty. Примеры, параметры и эксплуатационные ограничения.
Overview
Notty uses a 3-tier configuration model with clear priority rules.
Priority (highest → lowest):
1. Environment variables (always wins)
2. notty.config.ts (project config file)
3. Database (notty_config) (admin UI changes)
4. Schema defaults (built-in fallbacks)
Configuration Tiers
Tier 1: Infrastructure
Settings that define the deployment topology. Not editable through admin UI.
| Setting | Env Variable | Config File | Default |
|---|---|---|---|
| Database URL | DATABASE_URL |
database.url |
— (required) |
| Server port | PORT |
server.port |
2102 |
| Server host | HOST |
server.host |
localhost |
| Storage type | STORAGE_TYPE |
storage.type |
local |
| Upload directory | STORAGE_UPLOAD_DIR |
storage.uploadDir |
uploads |
| Upload base URL | STORAGE_BASE_URL |
storage.baseUrl |
/api/uploads |
| API prefix | NOTTY_API_PREFIX |
— | /api |
| Schemas directory | NOTTY_SCHEMAS_DIR |
schemasDir |
./schemas |
| Data directory | NOTTY_DATA_DIR |
dataDir |
./data |
Tier 2: Secrets
Sensitive values that must NEVER be stored in the database or shown in UI. In production, missing secrets cause a fatal startup error.
| Setting | Env Variable | Config File | Notes |
|---|---|---|---|
| JWT secret | JWT_SECRET |
jwt.secret |
Required in production |
| JWT expiry | JWT_EXPIRES_IN |
jwt.expiresIn |
Default: 7d |
| Google OAuth ID | GOOGLE_CLIENT_ID |
oauth.google.clientId |
Optional |
| Google OAuth secret | GOOGLE_CLIENT_SECRET |
oauth.google.clientSecret |
Required if ID is set |
| GitHub OAuth ID | GITHUB_CLIENT_ID |
oauth.github.clientId |
Optional |
| GitHub OAuth secret | GITHUB_CLIENT_SECRET |
oauth.github.clientSecret |
Required if ID is set |
| Facebook App ID | FACEBOOK_APP_ID |
oauth.facebook.appId |
Optional |
| Facebook App secret | FACEBOOK_APP_SECRET |
oauth.facebook.appSecret |
Required if ID is set |
| VK App ID | VK_APP_ID |
oauth.vk.appId |
Optional |
| VK App secret | VK_APP_SECRET |
oauth.vk.appSecret |
Required if ID is set |
| SMTP password | NOTTY_SMTP_PASSWORD |
— | Env-only |
| Password reset secret | PASSWORD_RESET_SECRET |
— | Auto-derived from JWT_SECRET |
Tier 3: Runtime
Operational settings editable through admin panel, config file, or env vars. If an env var is set for a runtime setting, it becomes locked in admin UI.
Categories:
- Site (
site.*): name, description, URL, admin email - Localization (
localization.*): locale, timezone, date/time formats - Security (
security.*): JWT expiry, password rules, login limits - Media (
media.*): upload limits, MIME types, thumbnails - API (
api.cors.*,api.rateLimit.*): CORS, rate limiting - Email (
email.*): provider, SMTP host/port/user, sender - Advanced (
advanced.*): debug mode, log level, caching
Runtime settings env convention: NOTTY_ + key in SCREAMING_SNAKE_CASE.
Example: site.name → NOTTY_SITE_NAME
Explicit runtime env overrides are read-only in admin UI and are not persisted back into the notty_config table.
Configuration Sources
1. notty.config.ts (project file)
import { defineConfig } from '@notty/core';
export default defineConfig({
database: {
url: 'sqlite://./data/notty.db',
},
jwt: {
secret: process.env.JWT_SECRET || 'dev-secret',
expiresIn: '7d',
},
server: {
port: 2102,
host: 'localhost',
},
storage: {
type: 'local',
uploadDir: 'uploads',
},
});
2. Environment Variables (.env)
DATABASE_URL=postgresql://user:pass@localhost:5432/notty
JWT_SECRET=a-strong-random-secret-here
PORT=2102
3. Admin Panel (database)
Settings changed through /admin → Settings are stored in the notty_config table.
They persist across restarts but can be overridden by env vars.
Only runtime settings are stored here. Secret and infrastructure values are never written to the database.
Environment-Specific Configuration
Development
NODE_ENV=development
DATABASE_URL=sqlite://./data/notty.db
# JWT_SECRET not required — uses default with a warning
Behavior:
- Warning about insecure JWT_SECRET (not fatal)
- Debug-friendly error messages
- Relaxed CORS defaults
Test
NODE_ENV=test
DATABASE_URL=sqlite://:memory:
JWT_SECRET=test-secret-minimum-16-chars
Behavior:
- Same validation as development
- In-memory database for speed
Production
NODE_ENV=production
DATABASE_URL=postgresql://user:pass@db-host:5432/notty
JWT_SECRET=$(openssl rand -base64 32)
PORT=2102
HOST=0.0.0.0
Behavior:
- Fatal error if
JWT_SECRETis missing or insecure - Fatal error if
DATABASE_URLis missing or invalid - Env-locked settings shown as read-only in admin UI
Fail-Fast Validation
On every server startup, the following checks run before database connection:
| Check | Development | Production |
|---|---|---|
DATABASE_URL missing |
Fatal | Fatal |
DATABASE_URL invalid format |
Fatal | Fatal |
JWT_SECRET missing/insecure |
Warning | Fatal |
JWT_SECRET < 16 chars |
— | Warning |
PORT out of range |
Fatal | Fatal |
| OAuth ID without secret | Warning | Warning |
Locking Behavior
When a runtime setting has a corresponding env var set, the setting becomes locked:
- The env var value takes priority over any database value
- The admin UI shows a lock icon
- Attempting to update via API returns an error
- To unlock: remove the env var and restart the server
Settings with tier secret are omitted from admin UI entirely.
Settings with tier infrastructure are read-only in admin UI regardless of env vars.
API Endpoints
GET /api/admin/config — All settings grouped by category
PUT /api/admin/config — Bulk update (respects locks)
GET /api/admin/config/schema — Settings schema for UI rendering
GET /api/admin/config/export — Export settings to JSON
POST /api/admin/config/import — Import settings from JSON
POST /api/admin/config/reload — Reload from database to cache
Security Checklist for Production
-
NODE_ENV=productionis set -
JWT_SECRETis a strong random string (32+ chars) -
DATABASE_URLuses a production database (not SQLite) - Database credentials are not hardcoded in config file
- OAuth secrets are in env vars, not config file
- CORS origins are restricted (not
["*"]) - Rate limiting is enabled
- SMTP password is in env var only
-
.envfile is in.gitignore
Источник: docs/config-model.md. Снимок документации исходного проекта. Технический справочник сохраняет язык оригинала.