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_SECRETRandom 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_URLPostgreSQL connection string with SSL

API Configuration

NameDefaultDescription
NEXT_PUBLIC_API_BASE_URLServer-side API URL. In Docker, use the container's own address: http://localhost:3000/api/v1
NEXT_PUBLIC_API_CLIENT_URLClient-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_URLSupabase project URL (self-hosted: http://supabase-kong:8000)
SUPABASE_ANON_KEYSupabase anonymous key for client-side operations
SUPABASE_SERVICE_ROLE_KEYSupabase service role key for server-side operations (auto-extracted from supabase/.env.sample by install.sh Step 4b)
SUPABASE_AUTH_URLSupabase Auth service URL (self-hosted: http://supabase-auth:9999)

Frappe (Backend ERP)

NameDefaultDescription
FRAPPE_API_TOKENFrappe API authentication token (key:secret format)
FRAPPE_BASE_URLFrappe Cloud site URL

Clinical Trials

NameDefaultDescription
NEXT_PUBLIC_DEFAULT_PRACTITIONER_IDDefault practitioner ID (auto-generated by Stage 5, e.g., HLC-PRAC-2026-00001)
PRACTITIONER_NAMEDefault practitioner display name (e.g., "Mary Williams")
NEXT_PUBLIC_STUDY_PARTICIPATION_CONCENTStudy 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_ROLESAvailable 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_NAMEClient brand name (leave blank for unbranded)
NEXT_PUBLIC_SITE_URLSite URL for SEO
NEXT_PUBLIC_SITE_DESCRIPTIONSite 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_KEYFirebase 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_HOSTDatabase host
CUBEJS_DB_PORT5432Database port
CUBEJS_DB_NAMEDatabase name
CUBEJS_DB_USERDatabase username
CUBEJS_DB_PASSDatabase password
CUBEJS_DB_SSLtrueEnable SSL connection

Server Configuration

NameDefaultDescription
PORT4000Cube.dev server port
CUBEJS_DEV_MODEtrueEnable development mode
CUBEJS_API_SECRETAPI 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_URLRedis connection URL (for production)
CUBEJS_REDIS_TLStrueEnable Redis TLS

Security

NameDefaultDescription
CUBEJS_PLAYGROUND_AUTH_SECRETPlayground authentication secret
CUBEJS_CORS_ORIGINAllowed CORS origins (comma-separated)

Logging

NameDefaultDescription
DEBUG_LOGtrueEnable debug logging

MCP Server

Model Context Protocol server for AI assistant integration.

OpenAI

NameDefaultDescription
OPENAI_API_KEYOpenAI 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_SECRETCube.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_URLFrappe API base URL

Database Connection

NameDefaultDescription
DB_HOSTlocalhostDatabase host
DB_PORT5432Database port
DB_USERDatabase username
DB_PASSWORDDatabase 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_APISJSON array of clinical data endpoints
DATALAKE_APIS_MASTERJSON array of master data endpoints
DATALAKE_APIS_CRFJSON 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_USERPostgreSQL username
DB_PASSWORDPostgreSQL password
DB_NAMEctmsPostgreSQL database name

Staging Database

NameDefaultDescription
STAGING_DB_HOSTStaging database host
STAGING_DB_USERStaging database username
STAGING_DB_PASSWORDStaging database password
STAGING_DB_NAMEStaging database name

Snowflake (Production)

NameDefaultDescription
SNOWFLAKE_ACCOUNTSnowflake account identifier
SNOWFLAKE_USERSnowflake username
SNOWFLAKE_PASSWORDSnowflake 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_COLORUser 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