This document provides a comprehensive reference for all environment variables used across the Zynomi CTMS platform. Configure these variables in your .env file for each component.
The ctms-data-pipeline-ai-analytics monorepo includes a unified .env.production file that consolidates all data pipeline and AI analytics variables in one place.
Global Settings
Top-level variables that apply across all services.
Name Default Description APP_NAMEzynomi-life-sciencesApplication name identifier APP_DESCRIPTIONClinical Trials Management System - Healthcare PlatformApplication description API_VERSION1.0.1API version string MOBILE_APP_VERSION1.0.0Mobile app version NODE_ENVproductionEnvironment mode (development, production)
Server & Domain Configuration
Server host, domain names, and reverse proxy settings.
Server Host
Name Default Description EC2_PUBLIC_IP(auto-patched) Public IP or hostname. Auto-patched by install.sh from SERVER_HOST in install.conf.
Domains (Caddy Reverse Proxy)
Name Default Description DOMAINlocalhostBase domain. For production DNS, set to your real domain (e.g., zynomi.com). API_DOMAINapi.localhostAPI gateway domain ZYNEXA_DOMAINzynexa.localhostZynexa web app domain SUBLINK_DOMAINsublink.localhostSublink mobile companion domain ACME_EMAILadmin@example.comLet's Encrypt email for production HTTPS
Local *.localhost domains get automatic HTTPS via Caddy's internal CA. For production with DNS, set real domain values and ACME_EMAIL.
NextAuth
Name Default Description NEXTAUTH_URLhttp://<EC2_PUBLIC_IP>:3000Must match how users reach Zynexa in their browser. Auto-patched by install.sh. NEXTAUTH_SECRET— Random secret string for session encryption. Change from default!
KrakenD API Gateway
Name Default Description KRAKEND_PORT8080Gateway listen port KRAKEND_METRICS_PORT8090Metrics/health endpoint port KRAKEND_REVOKER_PORT1234Token revoker port KRAKEND_TIMEOUT30sRequest timeout KRAKEND_CACHE_TTL3600sResponse cache TTL KRAKEND_LOG_LEVELDEBUGLog level
CTMS Web Application
The main Next.js web application for clinical trial management.
Service Ports
Name Default Description ZYNEXA_PORT3000Zynexa web app port
Application Settings
Name Default Description NODE_ENVproductionEnvironment mode (development, production) PORT3000Application port APP_VERSION1.0.0Application version NEXT_TELEMETRY_DISABLED1Disable Next.js telemetry
Database
Name Default Description DATABASE_URL— PostgreSQL connection string with SSL
API Configuration
Name Default Description NEXT_PUBLIC_API_BASE_URL— Server-side API URL. In Docker, use the container's own address: http://localhost:3000/api/v1 NEXT_PUBLIC_API_CLIENT_URL— Client-side API URL for browser JavaScript. Must match the domain you browse at (e.g., https://zynexa.localhost/api/v1) NEXT_PUBLIC_PUBLIC_ROUTES/login,/signup,...Routes accessible without authentication
Server vs Client API URLs
In Docker deployments, the server (Next.js) and browser need different API URLs:
NEXT_PUBLIC_API_BASE_URL (server-side): Used by Node.js for login, SSR, and server-side Frappe calls. Must be resolvable from inside the container . Recommended: http://localhost:3000/api/v1 (self-referencing).
NEXT_PUBLIC_API_CLIENT_URL (client-side): Used by browser JavaScript for RBAC, permissions, and dynamic data. Must match the domain you're browsing at .
These values are injected at runtime via RUNTIME_API_BASE_URL and RUNTIME_API_CLIENT_URL environment variables in docker-compose.yml, which take precedence over the build-time NEXT_PUBLIC_* values.
Common mistake: Setting the server-side URL to an external hostname (e.g., https://ctms.example.com/api/v1) that the container cannot resolve via DNS. This causes login failures with "User profile not found in Frappe".
Local Development with zynexa.localhost
When browsing at https://zynexa.localhost, set:
NEXT_PUBLIC_API_BASE_URL = http://localhost:3000/api/v1 NEXT_PUBLIC_API_CLIENT_URL = https://zynexa.localhost/api/v1
Supabase (Authentication)
Name Default Description SUPABASE_URL— Supabase project URL (self-hosted: http://supabase-kong:8000) SUPABASE_ANON_KEY— Supabase anonymous key for client-side operations SUPABASE_SERVICE_ROLE_KEY— Supabase service role key for server-side operations (auto-extracted from supabase/.env.sample by install.sh Step 4b) SUPABASE_AUTH_URL— Supabase Auth service URL (self-hosted: http://supabase-auth:9999)
Frappe (Backend ERP)
Name Default Description FRAPPE_API_TOKEN— Frappe API authentication token (key:secret format) FRAPPE_BASE_URL— Frappe Cloud site URL
Clinical Trials
Name Default Description NEXT_PUBLIC_DEFAULT_PRACTITIONER_ID— Default practitioner ID (auto-generated by Stage 5, e.g., HLC-PRAC-2026-00001) PRACTITIONER_NAME— Default practitioner display name (e.g., "Mary Williams") NEXT_PUBLIC_STUDY_PARTICIPATION_CONCENT— Study participation consent text NEXT_PUBLIC_STUDY_PERSONNEL_ROLESStudy Coordinator,Principal InvestigatorComma-separated list of roles that can be added as study personnel NEXT_PUBLIC_USER_ROLES— Available roles for user management (comma-separated)
Frappe Provisioning (ctms-init)
These variables control the 5-stage Frappe provisioning process.
Name Default Description CTMS_INIT_STAGES1,2,3,4,5Comma-separated list of provisioning stages to run CTMS_INIT_DRY_RUNfalsePreview changes without applying them PRACTITIONER_FIRST_NAMEMaryFirst name for the default Healthcare Practitioner (Stage 5) PRACTITIONER_LAST_NAMEWilliamsLast name for the default Healthcare Practitioner (Stage 5)
Branding & UI
Name Default Description NEXT_PUBLIC_LOGO_PREFIX/i/hb/logo-hbLogo path prefix (without extension) NEXT_PUBLIC_LOGO_EXTpngLogo file extension NEXT_PUBLIC_BRAND_NAME— Client brand name (leave blank for unbranded) NEXT_PUBLIC_SITE_URL— Site URL for SEO NEXT_PUBLIC_SITE_DESCRIPTION— Site description for SEO NEXT_PUBLIC_OG_IMAGE/og-image.pngOpenGraph image path
MCP Chat (Embedded AI Assistant)
Name Default Description NEXT_PUBLIC_MCP_CHAT_TITLECTMS AI AssistantChat widget title NEXT_PUBLIC_MCP_CHAT_SUBTITLEClinical Trials DataChat widget subtitle NEXT_PUBLIC_MCP_CHAT_ENABLEDtrueEnable/disable the embedded chat widget NEXT_PUBLIC_MCP_CHAT_THEMEdiscordChat widget theme
Push Notifications
Name Default Description FIREBASE_SERVER_KEY— Firebase Cloud Messaging server key
Sublink Mobile Companion
The Nuxt-based mobile companion app for patient/subject engagement.
Service Port
Name Default Description SUBLINK_PORT3001Sublink web server port
App Branding
Name Default Description NUXT_PUBLIC_APP_NAMESublinkApplication name NUXT_PUBLIC_APP_VERSION1.0.0Application version NUXT_PUBLIC_APP_BUILD_NUMBER1Build number NUXT_PUBLIC_APP_TAGLINEYour Health, ConnectedApp tagline NUXT_PUBLIC_APP_DESCRIPTION(long) App description for app stores
Logos
Name Default Description NUXT_PUBLIC_LOGO_WEBsublink-logo.svgWeb logo filename NUXT_PUBLIC_LOGO_MOBILEsublink-logo.svgMobile logo filename NUXT_PUBLIC_LOGO_MARKzynomi-logo-mark.svgLogo mark NUXT_PUBLIC_LOGO_MARK_DARKsublink-logo-mark-dark.svgDark mode logo mark
Theme & Onboarding
Name Default Description NUXT_PUBLIC_THEMEslackUI theme NUXT_PUBLIC_ONBOARDING_MODERNfalseUse modern onboarding flow NUXT_PUBLIC_ONBOARDING_CARDSwelcome,epro,studies,...Comma-separated onboarding card sequence NUXT_PUBLIC_ONBOARDING_SKIP_IF_COMPLETEDtrueSkip onboarding for returning users
API Gateway
Name Default Description API_GATEWAY_BASE_URLhttp://api-gateway:8080/api/v1Internal API gateway URL (Docker network)
Observability (OpenObserve & OTEL)
Log aggregation and distributed tracing via OpenObserve and OpenTelemetry.
OpenObserve
Name Default Description OPENOBSERVE_ROOT_EMAILadmin@ctms.localAdmin login email OPENOBSERVE_ROOT_PASSWORDAdmin@123Admin login password OPENOBSERVE_ORGdefaultOrganization name OPENOBSERVE_AUTH(base64) Base64-encoded email:password for OTEL collector auth
OTEL Collector
Name Default Description DEPLOYMENT_ENVproductionDeployment environment label for traces/metrics OTEL_GRPC_PORT4317OTEL gRPC receiver port OTEL_HTTP_PORT4318OTEL HTTP receiver port OTEL_METRICS_PORT8888OTEL collector metrics port
Grafana
Self-service dashboarding with DuckDB and Infinity plugins.
Name Default Description GRAFANA_ADMIN_USERadmin@ctms.localAdmin login email GRAFANA_ADMIN_PASSWORDAdmin@123Admin login password
Cube.dev Semantic Layer
Analytics semantic layer providing metrics and dimensions for dashboards.
Database Connection
Name Default Description CUBEJS_DB_TYPEpostgresDatabase type CUBEJS_DB_HOST— Database host CUBEJS_DB_PORT5432Database port CUBEJS_DB_NAME— Database name CUBEJS_DB_USER— Database username CUBEJS_DB_PASS— Database password CUBEJS_DB_SSLtrueEnable SSL connection
Server Configuration
Name Default Description PORT4000Cube.dev server port CUBEJS_DEV_MODEtrueEnable development mode CUBEJS_API_SECRET— API secret key for authentication CUBEJS_WEB_SOCKETStrueEnable WebSocket support CUBEJS_SCHEMA_PATHmodelPath to schema files
Caching
Name Default Description CUBEJS_CACHE_AND_QUEUE_DRIVERmemoryCache driver (memory, redis) CUBEJS_REDIS_URL— Redis connection URL (for production) CUBEJS_REDIS_TLStrueEnable Redis TLS
Security
Name Default Description CUBEJS_PLAYGROUND_AUTH_SECRET— Playground authentication secret CUBEJS_CORS_ORIGIN— Allowed CORS origins (comma-separated)
Logging
Name Default Description DEBUG_LOGtrueEnable debug logging
MCP Server
Model Context Protocol server for AI assistant integration.
OpenAI
Name Default Description OPENAI_API_KEY— OpenAI API key OPENAI_MODELgpt-4o-miniOpenAI model to use
Agent Service
Name Default Description AGENT_HOST127.0.0.1Agent service host AGENT_PORT8006Agent service port
Cube.dev Integration
Name Default Description CUBE_API_URLhttp://localhost:4000/cubejs-api/v1Cube.dev API endpoint CUBE_API_SECRET— Cube.dev API secret (must match CUBEJS_API_SECRET)
Data Ingestion (DLT Hub)
Data pipeline for ingesting clinical trial data from Frappe to the data warehouse.
Pipeline Configuration
Name Default Description DLT_PIPELINE_NAMEhbct_clinical_trial_pipelinePipeline name DLT_DESTINATIONpostgresDestination type DLT_DATASET_NAMEbronzeTarget dataset/schema PROCESSING_METHODasyncProcessing method FRAPPE_BASE_URL— Frappe API base URL
Database Connection
Name Default Description DB_HOSTlocalhostDatabase host DB_PORT5432Database port DB_USER— Database username DB_PASSWORD— Database password DB_NAMEctmsDatabase name DB_SSLMODEdisableSSL mode
API Settings
Name Default Description TABLE_PREFIXtbl_mst_Table name prefix PAGE_SIZE100Records per page REQUEST_TIMEOUT30API timeout in seconds MAX_RETRIES3Maximum retry attempts RETRY_BACKOFF_SECONDS2Retry backoff delay CLEANUP_SCHEMASraw,bronze,...Schemas to clean up
Data Endpoints
Name Default Description DATALAKE_APIS— JSON array of clinical data endpoints DATALAKE_APIS_MASTER— JSON array of master data endpoints DATALAKE_APIS_CRF— JSON array of CRF data endpoints
Data Pipeline — Image Versions
Name Default Description INGESTER_IMAGEzynomi/ctms-ingester:latestDocker image for the DLT ingester DBT_IMAGEzynomi/ctms-dbt:latestDocker image for dbt transformations
Data Pipeline — Lakehouse Database
Dedicated PostgreSQL instance for the bronze/silver/gold data warehouse.
Name Default Description TARGET_DB_USERctms_userLakehouse PostgreSQL username TARGET_DB_PASSWORDctms_pwdLakehouse PostgreSQL password TARGET_DB_NAMEctms_dlhLakehouse database name LAKEHOUSE_INSTANCEproductionInstance name (used for env file selection: .env.${LAKEHOUSE_INSTANCE}) LAKEHOUSE_DB_PORT5433Exposed port for lakehouse-db (avoids conflict with Supabase on 5432)
DBT Pipeline
Data transformation pipeline using dbt for the data warehouse.
Development Database
Name Default Description DB_HOSTlocalhostPostgreSQL host DB_PORT5432PostgreSQL port DB_USER— PostgreSQL username DB_PASSWORD— PostgreSQL password DB_NAMEctmsPostgreSQL database name
Staging Database
Name Default Description STAGING_DB_HOST— Staging database host STAGING_DB_USER— Staging database username STAGING_DB_PASSWORD— Staging database password STAGING_DB_NAME— Staging database name
Snowflake (Production)
Name Default Description SNOWFLAKE_ACCOUNT— Snowflake account identifier SNOWFLAKE_USER— Snowflake username SNOWFLAKE_PASSWORD— Snowflake password SNOWFLAKE_ROLETRANSFORMSnowflake role SNOWFLAKE_WAREHOUSECOMPUTE_WHSnowflake warehouse SNOWFLAKE_DATABASECLINICAL_TRIALSSnowflake database
DBT Settings
Name Default Description DBT_PROFILES_DIR.Profiles directory DBT_TARGETdevTarget environment
OpenLineage & Marquez (Data Lineage)
Environment variables for data lineage tracking via OpenLineage and the Marquez metadata service. These are used by the lakehouse-dbt and marquez-api services in the lakehouse profile.
OpenLineage
Name Default Description OPENLINEAGE_URLhttp://marquez-api:5000Marquez API endpoint for OpenLineage events OPENLINEAGE_NAMESPACEctms-lakehouseNamespace grouping for lineage events ENABLE_OPENLINEAGEtrue (when OPENLINEAGE_URL is set)Enable/disable dbt-ol lineage emission. When false, plain dbt is used. ENABLE_ELEMENTARYtrueEnable/disable Elementary report generation after dbt builds
Marquez API
Name Default Description MARQUEZ_PORT5000Marquez API port MARQUEZ_ADMIN_PORT5001Marquez admin/health check port MARQUEZ_WEB_PORT3300Marquez Web UI port MARQUEZ_DBmarquezMarquez PostgreSQL database name (separate from ctms_dlh) MARQUEZ_USERmarquezMarquez PostgreSQL user MARQUEZ_PASSWORDmarquezMarquez PostgreSQL password
Marquez reuses the existing lakehouse-db PostgreSQL instance with a separate marquez database. No additional database container is needed. The database is created automatically via an init script on first startup.
Pipeline Orchestration (Zynexa)
Environment variables that control the pipeline trigger API in the Zynexa web application. When enabled, Zynexa can trigger ingester and dbt runs via Docker Compose commands.
Name Default Description PIPELINE_ENABLEDfalseEnable pipeline trigger API from Zynexa UI. Requires Docker socket mount. DOCKER_SOCK_GID994GID of the docker group on the host. Run: stat -c '%g' /var/run/docker.sock DOCKER_COMPOSE_PROJECT_DIR/opt/ctms-devopsPath to Docker Compose project inside the Zynexa container PIPELINE_ENV_FILE.env.productionEnvironment file used for pipeline commands PIPELINE_PROFILElakehouseDocker Compose profile for pipeline services ENABLE_OPENLINEAGEtrueEnable dbt-ol lineage emission to Marquez. When false, plain dbt runs instead. ENABLE_ELEMENTARYtrueEnable Elementary report generation after dbt builds
Pipeline Trigger Toggles
When triggering dbt pipelines through the Zynexa REST API, you can pass feature toggles:
POST /api/data-analytics/pipeline/trigger { "type" : "dbt" , "command" : "daily" , "enableOpenlineage" : false , "enableElementary" : true }
Field Type Default Description enableOpenlineagebooleanServer default Override ENABLE_OPENLINEAGE for this run enableElementarybooleanServer default Override ENABLE_ELEMENTARY for this run
When provided, these values are passed as -e ENABLE_OPENLINEAGE=... and -e ENABLE_ELEMENTARY=... flags to the docker compose run command, overriding the server-level defaults for that specific run.
Enabling PIPELINE_ENABLED=true requires the Docker socket to be mounted into the Zynexa container. This grants the container access to the Docker Engine. For production deployments, consider using a Docker socket proxy for added security.
Embeddable AI chat widget for the platform.
API Configuration
Name Default Description VITE_API_ENDPOINThttp://127.0.0.1:8006MCP server endpoint VITE_STREAM_PATH/chat/streamStreaming chat path VITE_UPLOAD_PATH/uploadFile upload path
Appearance
Name Default Description VITE_CHAT_TITLEAI AssistantChat widget title VITE_CHAT_SUBTITLEOnlineChat widget subtitle VITE_CHAT_PLACEHOLDERType your message...Input placeholder text VITE_CHAT_POSITIONbottom-rightWidget position
Theme
Name Default Description VITE_HEADER_COLOR#4A154BHeader background color VITE_ACCENT_COLOR#611f69Accent color VITE_USER_BUBBLE_COLOR— User message bubble color VITE_BOT_ICONmdi:robot-happyBot icon (lucide/mdi or URL) VITE_THEMElightTheme mode (light, dark) VITE_BORDER_RADIUSroundedBorder radius style
Features
Name Default Description VITE_ENABLE_FILE_UPLOADtrueEnable file uploads VITE_ENABLE_HTML_RENDERINGtrueEnable HTML in responses