Skip to main content

Environment Variables

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.

Unified Environment File

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.

NameDefaultDescription
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​

NameDefaultDescription
EC2_PUBLIC_IP(auto-patched)Public IP or hostname. Auto-patched by install.sh from SERVER_HOST in install.conf.

Domains (Caddy Reverse Proxy)​

NameDefaultDescription
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 Development

Local *.localhost domains get automatic HTTPS via Caddy's internal CA. For production with DNS, set real domain values and ACME_EMAIL.

NextAuth​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
ZYNEXA_PORT3000Zynexa web app port

Application Settings​

NameDefaultDescription
NODE_ENVproductionEnvironment mode (development, production)
PORT3000Application port
APP_VERSION1.0.0Application version
NEXT_TELEMETRY_DISABLED1Disable Next.js telemetry

Database​

NameDefaultDescription
DATABASE_URL—PostgreSQL connection string with SSL

API Configuration​

NameDefaultDescription
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      # Server-side (container internal)
NEXT_PUBLIC_API_CLIENT_URL=https://zynexa.localhost/api/v1 # Client-side (browser)

Supabase (Authentication)​

NameDefaultDescription
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)​

NameDefaultDescription
FRAPPE_API_TOKEN—Frappe API authentication token (key:secret format)
FRAPPE_BASE_URL—Frappe Cloud site URL

Clinical Trials​

NameDefaultDescription
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.

NameDefaultDescription
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​

NameDefaultDescription
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)​

NameDefaultDescription
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​

NameDefaultDescription
FIREBASE_SERVER_KEY—Firebase Cloud Messaging server key

The Nuxt-based mobile companion app for patient/subject engagement.

Service Port​

NameDefaultDescription
SUBLINK_PORT3001Sublink web server port

App Branding​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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.

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
CUBEJS_CACHE_AND_QUEUE_DRIVERmemoryCache driver (memory, redis)
CUBEJS_REDIS_URL—Redis connection URL (for production)
CUBEJS_REDIS_TLStrueEnable Redis TLS

Security​

NameDefaultDescription
CUBEJS_PLAYGROUND_AUTH_SECRET—Playground authentication secret
CUBEJS_CORS_ORIGIN—Allowed CORS origins (comma-separated)

Logging​

NameDefaultDescription
DEBUG_LOGtrueEnable debug logging

MCP Server​

Model Context Protocol server for AI assistant integration.

OpenAI​

NameDefaultDescription
OPENAI_API_KEY—OpenAI API key
OPENAI_MODELgpt-4o-miniOpenAI model to use

Agent Service​

NameDefaultDescription
AGENT_HOST127.0.0.1Agent service host
AGENT_PORT8006Agent service port

Cube.dev Integration​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
DB_HOSTlocalhostDatabase host
DB_PORT5432Database port
DB_USER—Database username
DB_PASSWORD—Database password
DB_NAMEctmsDatabase name
DB_SSLMODEdisableSSL mode

API Settings​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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.

NameDefaultDescription
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​

NameDefaultDescription
DB_HOSTlocalhostPostgreSQL host
DB_PORT5432PostgreSQL port
DB_USER—PostgreSQL username
DB_PASSWORD—PostgreSQL password
DB_NAMEctmsPostgreSQL database name

Staging Database​

NameDefaultDescription
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)​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
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
Shared PostgreSQL

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.

NameDefaultDescription
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
}
FieldTypeDefaultDescription
enableOpenlineagebooleanServer defaultOverride ENABLE_OPENLINEAGE for this run
enableElementarybooleanServer defaultOverride 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.

Security

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.


Chat Widget​

Embeddable AI chat widget for the platform.

API Configuration​

NameDefaultDescription
VITE_API_ENDPOINThttp://127.0.0.1:8006MCP server endpoint
VITE_STREAM_PATH/chat/streamStreaming chat path
VITE_UPLOAD_PATH/uploadFile upload path

Appearance​

NameDefaultDescription
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​

NameDefaultDescription
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​

NameDefaultDescription
VITE_ENABLE_FILE_UPLOADtrueEnable file uploads
VITE_ENABLE_HTML_RENDERINGtrueEnable HTML in responses