Quick Start#

Bring up a minimal working environment first, then move database, cache, storage, and file-processing services to the level required by real usage. For the first deployment, start with the lightweight profile; for long-term multi-user usage, prefer PostgreSQL + Redis.

Before You Start#

DEEIX Chat deployment starts by clarifying three things: where the service runs, which public URLs browsers should use, and where data and files are persisted. Avoid maintaining the same value in multiple places. If environment variables override config.yaml, record the override source so later debugging stays clear.

ItemRequirementNotes
RuntimeDocker and Docker ComposeRecommended for first deployment, lightweight install, standard deployment, and full deployment
Config fileRoot-level config.yamlMounted to /app/config.yaml inside Docker deployments
Public URLsAPI, Web, and CORS must alignEspecially important for separated frontend/backend deployments
Security secretsMust be replaced in productionDo not use example values for jwt_secret or data_encryption_key
PersistenceDatabase, cache, and file volumesSQLite and local storage still need persistent mounts

terminal

Choose a Deployment Path#

The five paths cover trials, production-like single-node deployment, full local dependencies, separated frontend/backend hosting, and source development. Choose the path first, then copy the matching template. Mixing fields from different templates is not recommended.

PathBest forConfig templateStartup methodDependency model
Lightweight installTrials, demos, personal deployments, small single-node setupsconfig.sqlite.example.yamldocker-compose.sqlite.ymlApp + SQLite + sqlite-vec + memory cache
Standard deploymentExisting PostgreSQL and Redisconfig.example.yamldocker-compose.ymlApp only, database and cache external
Full deploymentOne machine running app, database, and cacheconfig.full.example.yamldocker-compose.full.ymlApp + PostgreSQL + Redis
Separated deploymentFrontend and API use different public domainsTarget environment configCustom build and static hostingStatic frontend assets and backend API hosted separately
Local developmentSource changes and frontend/backend debuggingconfig.example.yaml + frontend/.env.localBackend make run, frontend pnpm devLocal PostgreSQL, Redis, and dev servers

1. Lightweight Install#

The lightweight install starts only the app container. Data is stored in SQLite, vector indexes use sqlite-vec, and cache uses in-process memory. This is the fastest way to evaluate the product, run demos, or host a small single-node setup. For long-term multi-user usage, migrate to PostgreSQL + Redis.

Prepare Configuration#

terminal

Before any public deployment, replace at least security.jwt_secret, security.data_encryption_key, server.public_api_base_url, server.public_web_base_url, and server.cors_allow_origin. You can generate secrets in the configuration guide.

Start the App#

terminal

The default image is ghcr.io/deeix-ai/deeix-chat:latest. To use a local image or test a source build, override the image name.

terminal

Open the Service#

ServiceURLPurpose
Web apphttp://localhost:8080User chat and admin entry point
Health checkhttp://localhost:8080/healthzVerify that the service started
Swaggerhttp://localhost:8080/swagger/index.htmlInspect backend APIs

2. Standard Deployment#

The standard deployment starts only the application container. Use it when PostgreSQL, Redis, object storage, or platform infrastructure already exists. Database and Redis addresses must be resolvable and reachable from inside the container. If they run on the Docker host, host.docker.internal is usually the right hostname.

Prepare Configuration#

terminal

Check Connection Settings#

SettingDescription
database.postgres.dsnPostgreSQL connection string; verify container-network reachability
cache.redis.addrRedis address; production should prefer Redis over memory cache
cache.redis.passwordRedis password; if empty, verify the network boundary is trusted
server.public_api_base_urlPublic API URL used by browsers, callbacks, and external systems
server.public_web_base_urlWeb URL used for shares, redirects, and notifications
server.cors_allow_originFrontend origin allowed for separated or cross-origin deployments

Start the App#

terminal

The default docker-compose.yml does not start PostgreSQL or Redis. Keep matching Compose environment variables empty unless you intentionally want them to override config.yaml; otherwise the effective config source becomes hard to audit.

3. Full Deployment#

The full deployment starts App, PostgreSQL, and Redis on one machine. It is closer to the production dependency model than the lightweight profile, works better for long-running single-node usage, and is easier to migrate toward external database, Redis, or managed cloud services later.

Prepare Configuration#

terminal

Before public deployment, replace security secrets, public URLs, CORS, trusted proxies, PostgreSQL password, Redis password, and storage settings.

Start the Full Stack#

terminal

docker-compose.full.yml injects POSTGRES_DSN, REDIS_ADDR, and REDIS_PASSWORD through environment variables. Environment variables have higher priority than config.yaml, so these values override database and Redis settings in the config file. This is intentional so the app container connects to the Compose-managed services.

Check Dependencies#

terminal

If the app fails to start, check whether PostgreSQL finished initialization, whether the Redis password matches, whether config.yaml is mounted, and whether Compose environment variables override the expected fields.

4. Separated Deployment#

Use separated deployment when frontend and backend are exposed through different public origins. For example, the web app runs at https://chat.example.com and the API runs at https://api.example.com. This path requires build variables, CORS, public URLs, and CDN route fallback to align. Read the configuration guide before production release.

Align Public URLs#

SettingExampleDescription
NEXT_PUBLIC_API_BASE_URLhttps://api.example.comInjected at frontend build time; browsers use it for API requests
server.public_api_base_urlhttps://api.example.comPublic backend API URL for callbacks, links, and external systems
server.public_web_base_urlhttps://chat.example.comPublic web URL used when the backend generates web links
server.cors_allow_originhttps://chat.example.comFrontend origin allowed to call the API cross-origin

Build the Frontend#

terminal

When publishing frontend/out, the CDN or static server must support route fallback, for example /chat to /chat/index.html. API, health check, and Swagger paths should bypass CDN cache and forward complete headers, request bodies, and response statuses.

Verify After Deployment#

terminal

If the page loads but API calls fail, the usual causes are NEXT_PUBLIC_API_BASE_URL, cors_allow_origin, or reverse-proxy routes not matching. Frontend build variables are embedded into static assets, so changes require rebuilding the frontend.

5. Local Development#

Local development is for source changes, frontend/backend debugging, and UI interaction checks. It is not the shortest trial path. The default config connects to local PostgreSQL and Redis, so make sure those dependencies are running first.

Backend#

terminal

The backend listens on http://localhost:8080 by default, and Swagger is available at http://localhost:8080/swagger/index.html.

Frontend#

terminal

The local frontend usually points to the backend development service.

.env.local

Startup Checks#

After startup, verify health, container status, config mount, and logs. The commands below use the lightweight profile. For the standard profile, omit -f docker-compose.sqlite.yml; for the full profile, replace it with -f docker-compose.full.yml.

terminal

CheckExpected resultInspect first when abnormal
Health checkService health responseConfig parsing, database connection, port conflicts
Container statusapp is runningImage pull, startup command, dependency status
Config mount/app/config.yaml existsStartup directory, volume path, file permissions
Startup logsNo migration or initialization errorsDatabase version, secret length, environment overrides

First Login#

If the database does not contain a superadmin account, the backend creates the initial administrator on first startup and prints the initial password only once. Do not store the initial password in the config file, and do not keep using initial credentials for real operation.

ItemDescription
Initial usernameadmin
Initial passwordInspect startup logs, search for bootstrap superadmin created, and read the password field
First loginThe system requires changing the username and password
Later changesUse the account flow or admin console; credentials are not changed through config.yaml

Optional File Processing Services#

The base deployment does not require document parsing or OCR services. Start these optional services only when the matching capability is enabled in the admin console or configuration. They are usually related to file extraction, OCR, and RAG indexing, so bring up the base application first and add them gradually.

terminal

These services join deeix-chat-network. Start one root deployment first, or create the network manually.

terminal

ServiceDefault URLPurpose
Tikahttp://127.0.0.1:9998Document text extraction
Tesseract OCRhttp://127.0.0.1:8004/ocrOCR service
Doclinghttp://127.0.0.1:8005/ocrDocument and OCR extraction

Next Steps#

After login, finish runtime business configuration before opening the service to real users. Models, upstreams, routes, pricing, file policies, RAG, and MCP tools belong in the admin console rather than hard-coded deployment config.

AreaSuggested action
Upstreams and modelsAdd upstream channels, platform models, and route bindings
Files and RAGConfirm storage, extraction, OCR, embedding, and retrieval strategy
Auth and securityReplace secrets, check CORS, trusted proxies, signup policy, and 2FA
Billing and usageConfigure model pricing, subscriptions, top-ups, payments, and webhooks
Operations and auditCheck logs, audit events, backups, GeoIP, and OpenTelemetry