mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-27 20:01:35 +00:00
357 lines
15 KiB
JSON
357 lines
15 KiB
JSON
{
|
|
// Comprehensive template — every key the OSS backend or shipped (non-prod)
|
|
// extensions read. Copy to `config.json` and trim what you don't need;
|
|
// unset keys fall back to documented defaults. See
|
|
// `src/backend/types.ts` for the per-field source of truth.
|
|
//
|
|
// Each setting lives at exactly one canonical key — there are no fallback
|
|
// aliases. Values shown are illustrative, not production secrets.
|
|
//
|
|
// Keys consumed only by closed-source / hosted-prod extensions (clickhouse,
|
|
// cacheUpdateHandler, pages, prodMeteringAndBilling, …) are intentionally
|
|
// omitted.
|
|
|
|
// ── Environment / identity ──────────────────────────────────────────
|
|
"config_name": "template",
|
|
// `dev` opens a browser on boot, skips blocked-email checks, and runs the
|
|
// dev-time webpack watcher; `prod` serves pre-built bundles.
|
|
"env": "dev",
|
|
"version": "0.0.0",
|
|
// Stable identity for this server node — used by pager alerts and
|
|
// graceful-shutdown coordination.
|
|
"serverId": "node-1",
|
|
|
|
// ── Networking / URLs ───────────────────────────────────────────────
|
|
// Port Puter listens on internally.
|
|
"port": 4100,
|
|
// Externally-visible port (set this when behind a reverse proxy on 80/443).
|
|
"pub_port": 4100,
|
|
"protocol": "http",
|
|
"domain": "puter.localhost",
|
|
// Fully-qualified externally-visible URL. Computed from protocol/domain/
|
|
// pub_port if unset.
|
|
"origin": "http://puter.localhost:4100",
|
|
// Public base URL for the API subdomain (used to build signed URLs and
|
|
// surfaced to the client by the `installedApps` and `whoami` extensions).
|
|
"api_base_url": "http://api.puter.localhost:4100",
|
|
// Subdomains Puter routes on. Wildcard DNS (`*.<domain>`) must point at
|
|
// this server for site/app hosting to work.
|
|
"static_hosting_domain": "site.puter.localhost",
|
|
"static_hosting_domain_alt": "host.puter.localhost",
|
|
"private_app_hosting_domain": "app.puter.localhost",
|
|
"private_app_hosting_domain_alt": "dev.puter.localhost",
|
|
// Host-header / domain handling. Defaults below are the dev-friendly
|
|
// settings; tighten for any public install.
|
|
"allow_all_host_values": true,
|
|
"allow_no_host_header": true,
|
|
"allow_nipio_domains": false,
|
|
"custom_domains_enabled": false,
|
|
"enable_ip_validation": false,
|
|
// Express `trust proxy` setting — set to the number of reverse-proxy
|
|
// hops in front of the server (1 = nginx/Cloudflare, 2 = CF→ALB→app),
|
|
// or to a CIDR / IP / list. `false` (safe default) makes `req.ip` the
|
|
// direct socket peer. NEVER set to `true` in prod — it trusts every hop
|
|
// and makes X-Forwarded-For forgeable.
|
|
"trust_proxy": false,
|
|
"no_browser_launch": false,
|
|
|
|
// ── Dev watcher (devWatcher extension) ──────────────────────────────
|
|
// Rebuilds GUI + puter.js on file changes when running from source.
|
|
// Ignored when `env: "prod"` unless `devwatch.enabled: true`.
|
|
"no_devwatch": false,
|
|
"devwatch": {
|
|
// Delay after watcher startup before boot continues. Lets webpack
|
|
// emit its first build so the homepage doesn't 404 on bundle.min.js.
|
|
"ready_delay_ms": 5000
|
|
},
|
|
|
|
// ── Auth / session ──────────────────────────────────────────────────
|
|
// ALWAYS replace these for any public install — `openssl rand -hex 64`.
|
|
// `jwt_secret` is legacy verify-only; new tokens sign with `jwt_secret_v2`.
|
|
"jwt_secret": "change-me",
|
|
"jwt_secret_v2": "change-me",
|
|
// Set false to retire v1 tokens entirely (ROLLOUT-1).
|
|
"allow_v1_tokens": true,
|
|
"url_signature_secret": "change-me",
|
|
"cookie_name": "puter_auth_token",
|
|
"min_pass_length": 6,
|
|
"allow_system_login": false,
|
|
"strict_email_verification_required": false,
|
|
"captcha": {
|
|
"enabled": false,
|
|
"difficulty": "medium"
|
|
},
|
|
"oidc": {
|
|
"providers": {
|
|
// Google uses OIDC discovery — only ids are required.
|
|
"google": {
|
|
"client_id": "",
|
|
"client_secret": "",
|
|
"scopes": "openid email profile"
|
|
},
|
|
// Custom OIDC providers must also supply the three endpoints.
|
|
"custom-oidc": {
|
|
"client_id": "",
|
|
"client_secret": "",
|
|
"authorization_endpoint": "",
|
|
"token_endpoint": "",
|
|
"userinfo_endpoint": "",
|
|
"scopes": "openid email profile"
|
|
}
|
|
}
|
|
},
|
|
|
|
// ── Groups / provisioning ───────────────────────────────────────────
|
|
// UIDs of the persistent groups new users are auto-enrolled in.
|
|
"default_user_group": "78b1b1dd-c959-44d2-b02c-8735671f9997",
|
|
"default_temp_group": "b7220104-7905-4985-b996-649fdcdb3c8f",
|
|
// When true, ACL grants read/list on `/<user>/Public` to any actor.
|
|
"enable_public_folders": true,
|
|
|
|
// ── Storage / S3 ────────────────────────────────────────────────────
|
|
"s3": {
|
|
// Local fauxqs (in-process S3-compatible) — used in dev and the
|
|
// bundled-defaults Docker mode. Files land under `dataDir`.
|
|
"localConfig": {
|
|
"inMemory": false,
|
|
"host": "127.0.0.1",
|
|
"port": 4566,
|
|
"dataDir": "volatile/runtime/fauxqs-data",
|
|
"s3StorageDir": "volatile/runtime/fauxqs-s3-data"
|
|
},
|
|
// For real / external S3, replace `localConfig` above with `s3Config`.
|
|
"_remote_example": {
|
|
"s3Config": {
|
|
"useCredentialChain": false,
|
|
"endpoint": "https://s3.example.com",
|
|
// Endpoint used in presigned URLs handed to the browser. Set
|
|
// this when the server-side endpoint isn't reachable from the
|
|
// browser (e.g. docker-internal `http://s3:9000`).
|
|
"publicEndpoint": "",
|
|
"accessKeyId": "",
|
|
"secretAccessKey": "",
|
|
"region": "us-west-2",
|
|
// Set true for RustFS / MinIO / fauxqs (path-style URLs).
|
|
// Real AWS S3 wants virtual-hosted — leave unset / false.
|
|
"forcePathStyle": false
|
|
}
|
|
}
|
|
},
|
|
"s3_bucket": "puter-local",
|
|
"s3_region": "us-west-2",
|
|
"region": "us-west-2",
|
|
// Default per-user storage cap (bytes). 100 MB.
|
|
"storage_capacity": 104857600,
|
|
"is_storage_limited": false,
|
|
"available_device_storage": 0,
|
|
// ── Thumbnails (thumbnails extension) ───────────────────────────────
|
|
// Optional dedicated S3-compatible bucket for generated thumbnails.
|
|
// When unset (or `endpoint` empty), the extension falls back to the
|
|
// main S3 client / bucket above.
|
|
"thumbnailStore": {
|
|
"name": "puter-local",
|
|
"endpoint": "",
|
|
"credentials": {
|
|
"accessKeyId": "",
|
|
"secretAccessKey": ""
|
|
}
|
|
},
|
|
|
|
// ── Database ────────────────────────────────────────────────────────
|
|
"database": {
|
|
// `sqlite` for single-node / dev; `mysql` for self-host with MariaDB.
|
|
"engine": "sqlite",
|
|
// sqlite — file path on disk
|
|
"path": "volatile/runtime/puter-database.sqlite",
|
|
"targetVersion": 0,
|
|
// mysql — connection details
|
|
"host": "",
|
|
"port": 3306,
|
|
"user": "",
|
|
"password": "",
|
|
"database": "",
|
|
// Optional read-replica pool. Reads route here when populated.
|
|
"replica": {
|
|
"host": "",
|
|
"port": 3306,
|
|
"user": "",
|
|
"password": "",
|
|
"database": ""
|
|
}
|
|
// mysql self-host bootstrap: set `migrationPaths` to apply the bundled
|
|
// schema on first boot. Idempotent — safe to leave on.
|
|
// "migrationPaths": ["./src/backend/clients/database/migrations/mysql"]
|
|
},
|
|
|
|
// ── DynamoDB (KV store) ─────────────────────────────────────────────
|
|
"dynamo": {
|
|
// Local emulator (dynamodb-local) endpoint. Drop this field for real
|
|
// AWS DynamoDB.
|
|
"endpoint": "http://localhost:8000",
|
|
// Set true when pointing at a local emulator so Puter creates the KV
|
|
// table on boot. NEVER set against real AWS — provision via IaC.
|
|
// "bootstrapTables": true,
|
|
"path": "",
|
|
// Credentials. NOTE: snake_case here, unlike `s3.s3Config` below.
|
|
// For dynamodb-local, any non-empty values work.
|
|
"aws": {
|
|
"access_key": "",
|
|
"secret_key": "",
|
|
"region": "us-west-2"
|
|
}
|
|
},
|
|
|
|
// ── Redis / Valkey (cache + cross-node rate limit) ──────────────────
|
|
"redis": {
|
|
// True → in-process redis-mock (dev / single-node).
|
|
"useMock": true,
|
|
// Cluster nodes for ioredis. For a single Valkey/Redis container,
|
|
// run it in cluster mode (one node, all slots).
|
|
"startupNodes": [
|
|
{
|
|
"host": "127.0.0.1",
|
|
"port": 7000
|
|
}
|
|
]
|
|
// Defaults to true (matches prod ElastiCache). Set false for plain-TCP
|
|
// self-host Valkey/Redis.
|
|
// "tls": false
|
|
},
|
|
|
|
// ── Email (transactional) ───────────────────────────────────────────
|
|
// Nodemailer transport — used for password resets, email confirmation, etc.
|
|
"email": {
|
|
"from": "\"Puter\" <no-reply@puter.com>",
|
|
"host": "smtp.example.com",
|
|
"port": 587,
|
|
"secure": false,
|
|
"service": "",
|
|
"auth": {
|
|
"user": "",
|
|
"pass": ""
|
|
}
|
|
},
|
|
|
|
// ── Rate limiting ───────────────────────────────────────────────────
|
|
// `memory` for single-node, `redis` for multi-node (default), `kv` for
|
|
// dynamo-backed counters.
|
|
"rate_limit": {
|
|
"backend": "redis"
|
|
},
|
|
|
|
// ── AI / integration providers ──────────────────────────────────────
|
|
// All AI drivers (chat, image, video, TTS, OCR, STT) read from here.
|
|
// Provider id == driver-side identifier. Leave empty / omit to disable.
|
|
"providers": {
|
|
// ─ Chat / completion ─
|
|
"claude": { "apiKey": "" },
|
|
"openai-completion": { "apiKey": "" },
|
|
"gemini": { "apiKey": "" },
|
|
"groq": { "apiKey": "" },
|
|
"deepseek": { "apiKey": "" },
|
|
"mistral": { "apiKey": "" },
|
|
"xai": { "apiKey": "" },
|
|
"moonshot": { "apiKey": "" },
|
|
"openrouter": {
|
|
"apiKey": "",
|
|
"apiBaseUrl": "https://openrouter.ai/api/v1"
|
|
},
|
|
"together-ai": { "apiKey": "" },
|
|
// Local Ollama. `enabled: false` skips the auto-probe at startup
|
|
// (otherwise Puter logs ECONNREFUSED on every boot when no Ollama
|
|
// is running).
|
|
"ollama": {
|
|
"enabled": false,
|
|
"apiBaseUrl": "http://localhost:11434"
|
|
},
|
|
|
|
// ─ Image generation ─
|
|
"openai-image-generation": { "apiKey": "" },
|
|
"gemini-image-generation": { "apiKey": "" },
|
|
"together-image-generation": { "apiKey": "" },
|
|
"cloudflare-image-generation": {
|
|
"apiToken": "",
|
|
"accountId": "",
|
|
"apiBaseUrl": "https://api.cloudflare.com/client/v4"
|
|
},
|
|
"xai-image-generation": { "apiKey": "" },
|
|
|
|
// ─ Video generation ─
|
|
"openai-video-generation": { "apiKey": "" },
|
|
"together-video-generation": { "apiKey": "" },
|
|
"gemini-video-generation": { "apiKey": "" },
|
|
|
|
// ─ Speech / OCR ─
|
|
"openai": { "apiKey": "" },
|
|
"elevenlabs": {
|
|
"apiKey": "",
|
|
"apiBaseUrl": "https://api.elevenlabs.io",
|
|
"defaultVoiceId": "",
|
|
"speechToSpeechModelId": ""
|
|
},
|
|
"aws-polly": {
|
|
"access_key": "",
|
|
"secret_key": "",
|
|
"region": "us-west-2"
|
|
},
|
|
"aws-textract": {
|
|
"access_key": "",
|
|
"secret_key": "",
|
|
"region": "us-west-2"
|
|
},
|
|
"mistral-ocr": { "apiKey": "" }
|
|
},
|
|
|
|
// ── GUI / static mounts ─────────────────────────────────────────────
|
|
"gui_assets_root": "./src/gui",
|
|
"gui_profile": "development",
|
|
"builtin_apps": {
|
|
"dev-center": "./src/dev-center"
|
|
},
|
|
// Force the bundled GUI even in dev — set true when running from a
|
|
// pre-built tree without webpack-dev-server.
|
|
"use_bundled_gui": false,
|
|
"gui_bundle": "/dist/bundle.min.js",
|
|
"gui_css": "/dist/bundle.min.css",
|
|
"gui_puterjs_bundle": "https://js.puter.com/v2/",
|
|
"gui_params": {
|
|
"title": "Puter",
|
|
"short_description": "Your personal cloud computer",
|
|
"social_media_image": ""
|
|
},
|
|
// Optional roots for native app bundles and custom puter.js builds.
|
|
"native_apps_root": "",
|
|
"client_libs_root": "",
|
|
"puterjs_root": "./src/puter-js/dist",
|
|
|
|
// ── Feature flags (whoami extension) ────────────────────────────────
|
|
// Flat `{ flag_name: boolean }` bag. Server-only by default — flags are
|
|
// only surfaced to the client if their key is on the allowlist in
|
|
// `extensions/whoami.ts` (CLIENT_VISIBLE_FEATURE_FLAGS).
|
|
"feature_flags": {
|
|
"example_flag": false
|
|
},
|
|
|
|
// ── Misc / safety ───────────────────────────────────────────────────
|
|
// TLDs / domains rejected at signup (prod only).
|
|
"blockedEmailDomains": [],
|
|
"support_email": "support@puter.com",
|
|
// Worker / subdomain names users can't claim.
|
|
"reserved_words": [],
|
|
"max_subdomains_per_user": 10,
|
|
"server_health": {
|
|
"db_liveness_latency_fail_ms": 1500,
|
|
"stale_health_loop_fail_ms": 0
|
|
},
|
|
|
|
// ── Extensions ──────────────────────────────────────────────────────
|
|
// Directories scanned for extension entrypoints (`*.ts` / subdirs).
|
|
"extensions": [
|
|
"./extensions"
|
|
],
|
|
|
|
// ── Metering ────────────────────────────────────────────────────────
|
|
// When true, all metering checks pass — no per-actor limits enforced.
|
|
"unlimitedMetering": false
|
|
}
|