Skip to content

[CHORE] Consolidate env config into single common.env with zero duplication#1842

Open
mathumathi-zipstack wants to merge 8 commits intomainfrom
temp/common-env-config
Open

[CHORE] Consolidate env config into single common.env with zero duplication#1842
mathumathi-zipstack wants to merge 8 commits intomainfrom
temp/common-env-config

Conversation

@mathumathi-zipstack
Copy link

@mathumathi-zipstack mathumathi-zipstack commented Mar 10, 2026

What

  • Consolidate all scattered env configurations into a single docker/sample.env file with zero credential duplication
  • Add backward-compatible fallbacks for renamed env vars to support rolling deployments

Why

  • Previously, env vars were duplicated across sample.essentials.env, per-service sample.env files, and within the env file itself (e.g., POSTGRES_USER and DB_USER both set to the same value)
  • Changing a single credential (like DB password) required editing multiple files and multiple lines
  • This was error-prone and confusing for OSS users setting up Unstract

How

Env consolidation

  • Merged docker/sample.essentials.env and old docker/sample.env (compose/worker config) into a single docker/sample.env -- consistent naming with other service folders
  • Eliminated credential duplication using Docker Compose environment: mappings that derive infra-specific vars from app vars at compose time:
    • POSTGRES_USER: ${DB_USER} -- Postgres container gets its required var from the single DB_USER
    • RABBITMQ_DEFAULT_USER: ${CELERY_BROKER_USER} -- RabbitMQ gets its var from CELERY_BROKER_USER
    • FLIPT_DB_URL -- composed from DB_USER, DB_PASSWORD, DB_NAME in the compose file
  • Renamed env file target from common.env to .env so Docker Compose auto-reads it for variable substitution
  • Standardized DB env var names across services: PG_BE_* to DB_*, DB_USERNAME to DB_USER, REDIS_USERNAME to REDIS_USER
  • Stripped shared vars from per-service sample.env files

Cleanup of unused/misplaced vars

  • Removed QDRANT_USER/PASS/DB -- not read by any Python code (Qdrant adapter uses URL + API key from settings, not env vars)
  • Removed ADAPTER_LLMW_STATUS_RETRIES -- defined in env files but unused in code
  • Moved ADAPTER_LLMW_POLL_INTERVAL and ADAPTER_LLMW_MAX_POLLS to backend/sample.env and workers/sample.env (only services that use them via workflow-execution)

Rolling deployment safety

  • Added backward-compatible fallbacks for all renamed env vars so new code works with both old and new env var names:
    • platform-service: DB_HOST falls back to PG_BE_HOST, REDIS_USER falls back to REDIS_USERNAME, etc.
    • prompt-service: DB_HOST falls back to PG_BE_HOST, etc.
    • x2text-service: DB_USER falls back to DB_USERNAME
  • This allows rolling deployments where old and new containers coexist

Can this PR break any existing features

  • Backward-compatible: New code falls back to old env var names (PG_BE_*, DB_USERNAME, REDIS_USERNAME), so existing env files continue to work without changes.
  • Breaking for existing deployments: Users should regenerate their env files from the new docker/sample.env. The old essentials.env and common.env file names are no longer referenced.
  • No functional behavior changes -- same services, same connections, same defaults.

Database Migrations

  • None

Env Config

  • docker/sample.env -- Single source of truth (merged from old sample.essentials.env + old sample.env)
  • docker/sample.essentials.env -- DELETED
  • docker/sample.common.env -- DELETED (was intermediate, merged into sample.env)
  • Per-service sample.env files -- stripped of vars now in docker/sample.env
  • Docker Compose files -- env_file changed to ./.env
  • Standardized env var names (with backward-compatible fallbacks):
    • PG_BE_HOST to DB_HOST, PG_BE_PORT to DB_PORT, PG_BE_USERNAME to DB_USER, PG_BE_PASSWORD to DB_PASSWORD, PG_BE_DATABASE to DB_NAME
    • DB_USERNAME to DB_USER, REDIS_USERNAME to REDIS_USER

Notes on Testing

  • Validated docker compose config resolves all env vars correctly for both compose files
  • Verified Postgres container receives POSTGRES_USER=unstract_dev derived from DB_USER
  • Verified RabbitMQ container receives RABBITMQ_DEFAULT_USER=admin derived from CELERY_BROKER_USER
  • Verified Flipt receives correct FLIPT_DB_URL composed from DB_* vars
  • Started infra containers, confirmed successful DB connection
  • Verified Python env loading works with both new names (DB_HOST) and legacy fallbacks (PG_BE_HOST)

Checklist

I have read and understood the Contribution Guidelines.

Generated with Claude Code

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Consolidated infrastructure env vars into docker/sample.common.env, switched many services to load a local ./.env, removed numerous per-service infra/feature-flag variables, and renamed PG_BE_* → DB_* and REDIS_USERNAMEREDIS_USER across compose files and service code.

Changes

Cohort / File(s) Summary
Shared common env
docker/sample.common.env
Added a new shared env file consolidating Postgres, Redis, RabbitMQ/Celery, MinIO, Flipt, Qdrant, storage credentials (JSON), and inter-service defaults for local development.
Docker compose & docs
docker/docker-compose.yaml, docker/docker-compose-dev-essentials.yaml, docker/README.md, docker/scripts/db-setup/README.md, run-platform.sh
Switched many services to load ./.env via env_file, added explicit Postgres/RabbitMQ/Flipt env mappings, introduced a default fallback for TOOL_REGISTRY_CONFIG_SRC_PATH, and updated README/setup instructions to use sample.common.env./.env.
Pruned per-service samples
backend/sample.env, platform-service/sample.env, prompt-service/sample.env, runner/sample.env, workers/sample.env, x2text-service/sample.env
Removed many infra/DB/Redis/Celery/feature-flag/remote-storage/LLMW variables; retained minimal overrides and added notes pointing to shared sample.common.env.
Service env renames & code updates
platform-service/src/unstract/platform_service/env.py, platform-service/src/unstract/platform_service/config.py, platform-service/src/unstract/platform_service/extensions.py, prompt-service/src/unstract/prompt_service/extensions.py
Replaced PG_BE_* env keys with DB_* variants and switched Redis username key to REDIS_USER; updated DB/Redis initialization calls to use the new names.
x2text DB user rename
x2text-service/app/env.py, x2text-service/app/models.py
Renamed DB_USERNAMEDB_USER in Env and updated PostgresqlDatabase initialization to use Env.DB_USER.
Worker messaging/help text
workers/shared/infrastructure/config/worker_config.py
Updated validation/error messages to reference docker/sample.common.env for shared vars and workers/sample.env for worker-specific overrides.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective: consolidating scattered env configurations into a single common.env file while eliminating duplication.
Description check ✅ Passed PR description provides comprehensive coverage of all required template sections with clear explanations of changes, rationale, implementation approach, backward compatibility, testing, and breaking changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch temp/common-env-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@CLAassistant
Copy link

CLAassistant commented Mar 10, 2026

CLA assistant check
All committers have signed the CLA.

…cation

- Create docker/sample.common.env as single source of truth for all shared
  env vars (DB, Redis, RabbitMQ, MinIO, Flipt, service URLs, timeouts)
- Remove docker/sample.essentials.env (merged into common.env)
- Eliminate credential duplication by using Docker Compose environment
  mappings to derive infra vars from app vars (e.g. POSTGRES_USER from
  DB_USER, RABBITMQ_DEFAULT_USER from CELERY_BROKER_USER)
- Standardize DB env var names across services: PG_BE_* -> DB_*,
  DB_USERNAME -> DB_USER, REDIS_USERNAME -> REDIS_USER
- Strip shared vars from per-service sample.env files (backend, workers,
  prompt-service, runner, platform-service, x2text-service)
- Update docker-compose files to use .env (auto-read by Docker Compose
  for variable substitution)
- Update docker/README.md with simplified setup instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
docker/sample.common.env (1)

54-63: Consider templating MinIO credentials to reduce duplication.

The MinIO credentials are defined in MINIO_ROOT_USER/MINIO_ROOT_PASSWORD but must be manually duplicated in the JSON storage credential blocks. While the comment on line 55 instructs users to update both, this creates a maintenance burden and risk of inconsistency.

For a future improvement, consider using environment variable substitution within the JSON strings if your application supports it, or document this coupling more prominently.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker/sample.common.env` around lines 54 - 63, The JSON credential blocks
duplicate MINIO_ROOT_USER and MINIO_ROOT_PASSWORD; update
WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS, API_FILE_STORAGE_CREDENTIALS,
PERMANENT_REMOTE_STORAGE, and TEMPORARY_REMOTE_STORAGE to reference the single
source-of-truth variables MINIO_ROOT_USER and MINIO_ROOT_PASSWORD (e.g., via
environment variable substitution or your template syntax) so changes to
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD automatically propagate and eliminate
duplication/inconsistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/sample.env`:
- Around line 2-5: Update the header of backend/sample.env to explicitly state
this file is incomplete without docker/sample.common.env and must be combined
with it (do not treat it as standalone); call out the required shared keys that
must be copied from docker/sample.common.env — at minimum
CELERY_BROKER_BASE_URL, CELERY_BROKER_USER, CELERY_BROKER_PASS plus DB, REDIS,
RABBITMQ, FLIPT, MINIO and timeout vars — and add a short warning that failing
to include these will cause startup failures or silent fallbacks (see
backend/backend/settings/base.py and backend/utils/cache_service.py where those
defaults are used).

In `@docker/README.md`:
- Around line 20-31: The env-file copy commands are inconsistent with the
compose commands: update the paths so they use the same working-directory
convention as the rest of the README (which references docker-compose.yaml and
sample.compose.override.yaml at repo root). Either change the cp lines
(sample.common.env, backend/sample.env, platform-service/sample.env, etc.) to be
repo-root relative (remove the leading "docker/" from cp targets) or make the
compose commands docker/-relative; pick one convention and update all
occurrences (sample.common.env -> docker/.env, backend/sample.env ->
docker/backend/.env, or vice versa) to ensure the copy commands run from the
same directory as the docker-compose commands.

In `@platform-service/src/unstract/platform_service/env.py`:
- Around line 15-19: Replace the optional os.environ.get() calls for DB_HOST,
DB_USER, DB_PASSWORD, and DB_NAME with EnvManager.get_required_setting() so
these variables raise a clear error if missing; keep DB_PORT as-is (or if you
want it required too, wrap EnvManager.get_required_setting("DB_PORT") with
int()) and ensure any returned values are cast to the correct types where
needed; update the assignments for the symbols DB_HOST, DB_USER, DB_PASSWORD,
DB_NAME to call
EnvManager.get_required_setting("DB_HOST"/"DB_USER"/"DB_PASSWORD"/"DB_NAME") to
match how REDIS_HOST/REDIS_PORT are handled.

In `@workers/sample.env`:
- Around line 4-9: The runtime validation message (referencing CELERY_BROKER_URL
and CELERY_RESULT_BACKEND in worker_config.py) points users to
workers/sample.env but that file no longer contains the DB_* / CELERY_BROKER_*
examples; update the project so the guidance is consistent by either restoring a
small commented block of required shared vars (e.g., DB_*, CELERY_BROKER_*,
CELERY_RESULT_BACKEND, CELERY_BROKER_URL) into workers/sample.env, or change the
validation text in the code that builds/validates CELERY_BROKER_URL and
CELERY_RESULT_BACKEND to point to docker/sample.common.env instead; edit the
unique symbols CELERY_BROKER_URL, CELERY_RESULT_BACKEND and the validation
message in worker_config.py to match whichever option you choose.

---

Nitpick comments:
In `@docker/sample.common.env`:
- Around line 54-63: The JSON credential blocks duplicate MINIO_ROOT_USER and
MINIO_ROOT_PASSWORD; update WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS,
API_FILE_STORAGE_CREDENTIALS, PERMANENT_REMOTE_STORAGE, and
TEMPORARY_REMOTE_STORAGE to reference the single source-of-truth variables
MINIO_ROOT_USER and MINIO_ROOT_PASSWORD (e.g., via environment variable
substitution or your template syntax) so changes to
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD automatically propagate and eliminate
duplication/inconsistency.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 14ff15a1-7def-44d6-a6f3-1dcbab713447

📥 Commits

Reviewing files that changed from the base of the PR and between d645846 and 6f52884.

📒 Files selected for processing (17)
  • backend/sample.env
  • docker/README.md
  • docker/docker-compose-dev-essentials.yaml
  • docker/docker-compose.yaml
  • docker/sample.common.env
  • docker/sample.essentials.env
  • platform-service/sample.env
  • platform-service/src/unstract/platform_service/config.py
  • platform-service/src/unstract/platform_service/env.py
  • platform-service/src/unstract/platform_service/extensions.py
  • prompt-service/sample.env
  • prompt-service/src/unstract/prompt_service/extensions.py
  • runner/sample.env
  • workers/sample.env
  • x2text-service/app/env.py
  • x2text-service/app/models.py
  • x2text-service/sample.env
💤 Files with no reviewable changes (1)
  • docker/sample.essentials.env

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
platform-service/sample.env (1)

21-23: ⚠️ Potential issue | 🟡 Minor

Rename REMOTE_MODEL_PRICES_FILE_PATH to MODEL_PRICES_FILE_PATH in sample.env.

The environment variable in sample.env uses the wrong name. The code expects MODEL_PRICES_FILE_PATH (defined in platform-service/src/unstract/platform_service/env.py line 25 and consumed in cost_calculation.py line 19), but sample.env defines REMOTE_MODEL_PRICES_FILE_PATH, which is never used anywhere in the codebase.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platform-service/sample.env` around lines 21 - 23, The sample.env contains
REMOTE_MODEL_PRICES_FILE_PATH but the code reads MODEL_PRICES_FILE_PATH
(referenced in env.py and consumed in cost_calculation.py), so update sample.env
by renaming REMOTE_MODEL_PRICES_FILE_PATH to MODEL_PRICES_FILE_PATH (preserve
the current value "unstract/cost/model_prices.json" and quoting style) so the
runtime loads the correct environment variable.
🧹 Nitpick comments (2)
workers/sample.env (1)

54-65: Clarify the relationship between REDIS_ and CACHE_REDIS_ variables.**

The file defines both REDIS_DB=0 (line 55) and a separate CACHE_REDIS_* block (lines 58-65). Per worker_config.py, the CACHE_REDIS_* variables are used for the worker's Redis cache connection, while REDIS_HOST/REDIS_PORT from docker/sample.common.env may be used elsewhere. Consider adding a brief comment clarifying that CACHE_REDIS_HOST defaults to unstract-redis to match the common config, and when to use each set.

💡 Suggested clarification
+# Cache-Specific Redis Configuration
+# These override the base REDIS_* vars from common.env for worker cache operations.
+# For Docker: use unstract-redis. For local dev: use localhost.
 CACHE_REDIS_ENABLED=true
 CACHE_REDIS_HOST=unstract-redis
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workers/sample.env` around lines 54 - 65, Add a short comment above the
REDIS_DB and CACHE_REDIS_* block clarifying that REDIS_* variables (e.g.,
REDIS_DB) are the general/shared Redis settings used elsewhere (from
docker/sample.common.env), while CACHE_REDIS_* (CACHE_REDIS_HOST,
CACHE_REDIS_PORT, CACHE_REDIS_DB, etc.) are the worker-specific cache settings
consumed by worker_config.py; note that CACHE_REDIS_HOST defaults to
"unstract-redis" to match the common config and that if CACHE_REDIS_* are unset
the worker will fall back to the shared REDIS_* values.
docker/sample.common.env (1)

57-63: Ensure JSON credential blocks stay in sync with MinIO root credentials.

The hardcoded "key": "minio", "secret": "minio123" in the JSON blocks must match MINIO_ROOT_USER and MINIO_ROOT_PASSWORD. Consider adding a comment reminding users to update all four JSON blocks if they change the MinIO credentials.

💡 Suggested comment addition
 # MinIO (Object Storage)
 # MINIO_ROOT_USER/PASSWORD are used by the MinIO container on init.
-# Update the JSON blocks below if you change these credentials.
+# IMPORTANT: Update ALL FOUR JSON blocks below if you change these credentials.
+# The "key" and "secret" values must match MINIO_ROOT_USER and MINIO_ROOT_PASSWORD.
 # =============================================================================
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker/sample.common.env` around lines 57 - 63, The JSON credential blocks
(WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS, API_FILE_STORAGE_CREDENTIALS,
PERMANENT_REMOTE_STORAGE, TEMPORARY_REMOTE_STORAGE) hardcode "key" and "secret"
which must match MINIO_ROOT_USER and MINIO_ROOT_PASSWORD; add a clear
single-line comment above these entries reminding maintainers to keep the JSON
blocks in sync with MINIO_ROOT_USER and MINIO_ROOT_PASSWORD (or update all four
JSON envs) when changing the MinIO credentials; reference MINIO_ROOT_USER,
MINIO_ROOT_PASSWORD, and the four JSON env var names in that comment so it’s
obvious which values must be updated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@platform-service/sample.env`:
- Around line 21-23: The sample.env contains REMOTE_MODEL_PRICES_FILE_PATH but
the code reads MODEL_PRICES_FILE_PATH (referenced in env.py and consumed in
cost_calculation.py), so update sample.env by renaming
REMOTE_MODEL_PRICES_FILE_PATH to MODEL_PRICES_FILE_PATH (preserve the current
value "unstract/cost/model_prices.json" and quoting style) so the runtime loads
the correct environment variable.

---

Nitpick comments:
In `@docker/sample.common.env`:
- Around line 57-63: The JSON credential blocks
(WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS, API_FILE_STORAGE_CREDENTIALS,
PERMANENT_REMOTE_STORAGE, TEMPORARY_REMOTE_STORAGE) hardcode "key" and "secret"
which must match MINIO_ROOT_USER and MINIO_ROOT_PASSWORD; add a clear
single-line comment above these entries reminding maintainers to keep the JSON
blocks in sync with MINIO_ROOT_USER and MINIO_ROOT_PASSWORD (or update all four
JSON envs) when changing the MinIO credentials; reference MINIO_ROOT_USER,
MINIO_ROOT_PASSWORD, and the four JSON env var names in that comment so it’s
obvious which values must be updated.

In `@workers/sample.env`:
- Around line 54-65: Add a short comment above the REDIS_DB and CACHE_REDIS_*
block clarifying that REDIS_* variables (e.g., REDIS_DB) are the general/shared
Redis settings used elsewhere (from docker/sample.common.env), while
CACHE_REDIS_* (CACHE_REDIS_HOST, CACHE_REDIS_PORT, CACHE_REDIS_DB, etc.) are the
worker-specific cache settings consumed by worker_config.py; note that
CACHE_REDIS_HOST defaults to "unstract-redis" to match the common config and
that if CACHE_REDIS_* are unset the worker will fall back to the shared REDIS_*
values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b695fecd-37f1-4f3c-8f91-4c4bd6fd8cd0

📥 Commits

Reviewing files that changed from the base of the PR and between 6f52884 and 4b8051a.

📒 Files selected for processing (17)
  • backend/sample.env
  • docker/README.md
  • docker/docker-compose-dev-essentials.yaml
  • docker/docker-compose.yaml
  • docker/sample.common.env
  • docker/sample.essentials.env
  • platform-service/sample.env
  • platform-service/src/unstract/platform_service/config.py
  • platform-service/src/unstract/platform_service/env.py
  • platform-service/src/unstract/platform_service/extensions.py
  • prompt-service/sample.env
  • prompt-service/src/unstract/prompt_service/extensions.py
  • runner/sample.env
  • workers/sample.env
  • x2text-service/app/env.py
  • x2text-service/app/models.py
  • x2text-service/sample.env
💤 Files with no reviewable changes (1)
  • docker/sample.essentials.env
🚧 Files skipped from review as they are similar to previous changes (8)
  • x2text-service/app/models.py
  • docker/README.md
  • platform-service/src/unstract/platform_service/config.py
  • runner/sample.env
  • docker/docker-compose-dev-essentials.yaml
  • prompt-service/src/unstract/prompt_service/extensions.py
  • platform-service/src/unstract/platform_service/extensions.py
  • platform-service/src/unstract/platform_service/env.py

- Make backend/sample.env and workers/sample.env headers explicit about
  dependency on docker/sample.common.env
- Fix docker/README.md copy commands to be docker/-relative
- Make DB_* vars required in platform-service env.py (use
  EnvManager.get_required_setting instead of os.environ.get)
- Remove unused os import from platform-service env.py
- Update worker_config.py validation messages to reference
  docker/sample.common.env for shared vars
- Remove unused REMOTE_MODEL_PRICES_FILE_PATH from platform-service sample.env
- Improve MinIO credential sync warning in sample.common.env
- Add clarifying comments for REDIS_* vs CACHE_REDIS_* in workers sample.env

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
platform-service/src/unstract/platform_service/env.py (1)

1-12: ⚠️ Potential issue | 🔴 Critical

Missing os import causes NameError.

Lines 11-12 use os.environ.get() but the os module is not imported. This will cause a NameError at runtime when the Env class is loaded.

🐛 Proposed fix
+import os
+
 from unstract.platform_service.constants import LogLevel
 from unstract.platform_service.utils import EnvManager
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platform-service/src/unstract/platform_service/env.py` around lines 1 - 12,
The module references os.environ in the Env class (REDIS_USER and
REDIS_PASSWORD) but never imports os; add an import for the os module near the
top with the other imports so REDIS_USER = os.environ.get("REDIS_USER") and
REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD") do not raise a NameError when
the Env class is loaded.
🧹 Nitpick comments (2)
platform-service/sample.env (1)

1-6: Consider making the header warning more explicit.

The header says "LOCAL DEVELOPMENT NOTE" but doesn't explicitly warn that this file is incomplete without docker/sample.common.env. Compare with backend/sample.env which uses "WARNING: This file is NOT runnable by itself."

For consistency and to prevent setup issues, consider aligning the header style:

💡 Suggested header alignment
 # -----------------------------------------------------------------------------
-# LOCAL DEVELOPMENT NOTE:
-# Shared env vars (DB, Redis, RabbitMQ, Flipt, service URLs, MinIO, timeouts)
-# live in docker/sample.common.env. When running outside Docker, copy those vars
-# here and replace container hostnames with localhost (see common.env header).
+# WARNING: This file is NOT runnable by itself.
+# It must be combined with docker/sample.common.env (copied as docker/.env),
+# which provides required shared vars: DB_*, REDIS_*, CELERY_BROKER_*,
+# and other infrastructure settings. Missing these will cause startup failures.
+#
+# For local dev outside Docker, copy shared vars here and replace
+# container hostnames with localhost (see docker/sample.common.env header).
 # -----------------------------------------------------------------------------
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platform-service/sample.env` around lines 1 - 6, Update the header in
platform-service/sample.env to be an explicit warning that the file is
incomplete and not runnable by itself: replace or augment the "LOCAL DEVELOPMENT
NOTE" heading with wording similar to "WARNING: This file is NOT runnable by
itself — it requires docker/sample.common.env" and clearly instruct developers
to copy vars from docker/sample.common.env and swap container hostnames for
localhost; reference the existing phrasing in backend/sample.env as a model and
ensure the header mentions docker/sample.common.env and the non-runnable status.
docker/sample.common.env (1)

54-65: MinIO credentials duplication is fragile but acceptable with warning.

The warning on lines 55-56 about keeping credentials in sync across the JSON blocks is good. However, the manual synchronization of key/secret values in four separate JSON strings (lines 61-64) with MINIO_ROOT_USER/MINIO_ROOT_PASSWORD (lines 58-59) is error-prone.

Consider documenting a pattern or script for users to validate that these values match, or note that Docker Compose environment variable substitution doesn't work inside JSON strings within env files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker/sample.common.env` around lines 54 - 65, The env file duplicates MinIO
credentials across MINIO_ROOT_USER / MINIO_ROOT_PASSWORD and four JSON env
values (WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS,
API_FILE_STORAGE_CREDENTIALS, PERMANENT_REMOTE_STORAGE,
TEMPORARY_REMOTE_STORAGE), which is fragile; update the file to: 1) add a clear
comment near MINIO_ROOT_USER/MINIO_ROOT_PASSWORD stating that Docker .env
variable substitution does not work inside JSON strings and so those JSON blocks
must be kept in sync manually, and 2) include or reference a small validation
step (e.g., a script name like validate-minio-credentials or a one-liner
command) that checks the JSON "key"/"secret" values match
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD before starting services, mentioning the
exact env names (MINIO_ROOT_USER, MINIO_ROOT_PASSWORD,
WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS, API_FILE_STORAGE_CREDENTIALS,
PERMANENT_REMOTE_STORAGE, TEMPORARY_REMOTE_STORAGE) so users can locate and fix
mismatches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@platform-service/src/unstract/platform_service/env.py`:
- Around line 1-12: The module references os.environ in the Env class
(REDIS_USER and REDIS_PASSWORD) but never imports os; add an import for the os
module near the top with the other imports so REDIS_USER =
os.environ.get("REDIS_USER") and REDIS_PASSWORD =
os.environ.get("REDIS_PASSWORD") do not raise a NameError when the Env class is
loaded.

---

Nitpick comments:
In `@docker/sample.common.env`:
- Around line 54-65: The env file duplicates MinIO credentials across
MINIO_ROOT_USER / MINIO_ROOT_PASSWORD and four JSON env values
(WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS, API_FILE_STORAGE_CREDENTIALS,
PERMANENT_REMOTE_STORAGE, TEMPORARY_REMOTE_STORAGE), which is fragile; update
the file to: 1) add a clear comment near MINIO_ROOT_USER/MINIO_ROOT_PASSWORD
stating that Docker .env variable substitution does not work inside JSON strings
and so those JSON blocks must be kept in sync manually, and 2) include or
reference a small validation step (e.g., a script name like
validate-minio-credentials or a one-liner command) that checks the JSON
"key"/"secret" values match MINIO_ROOT_USER/MINIO_ROOT_PASSWORD before starting
services, mentioning the exact env names (MINIO_ROOT_USER, MINIO_ROOT_PASSWORD,
WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS, API_FILE_STORAGE_CREDENTIALS,
PERMANENT_REMOTE_STORAGE, TEMPORARY_REMOTE_STORAGE) so users can locate and fix
mismatches.

In `@platform-service/sample.env`:
- Around line 1-6: Update the header in platform-service/sample.env to be an
explicit warning that the file is incomplete and not runnable by itself: replace
or augment the "LOCAL DEVELOPMENT NOTE" heading with wording similar to
"WARNING: This file is NOT runnable by itself — it requires
docker/sample.common.env" and clearly instruct developers to copy vars from
docker/sample.common.env and swap container hostnames for localhost; reference
the existing phrasing in backend/sample.env as a model and ensure the header
mentions docker/sample.common.env and the non-runnable status.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 44be609f-dbde-4c18-a427-091728103bc3

📥 Commits

Reviewing files that changed from the base of the PR and between 4b8051a and 60e86e3.

📒 Files selected for processing (7)
  • backend/sample.env
  • docker/README.md
  • docker/sample.common.env
  • platform-service/sample.env
  • platform-service/src/unstract/platform_service/env.py
  • workers/sample.env
  • workers/shared/infrastructure/config/worker_config.py

- Replace sample.essentials.env reference with sample.common.env in
  run-platform.sh (fixes CI build failure)
- Keep sample.env merge for compose-level vars (worker settings, etc.)
- Update db-setup README to reference common.env and explain env mappings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docker/scripts/db-setup/README.md`:
- Line 9: The sentence uses "setup" incorrectly as a verb; change "helps setup
the DB user and creates a new schema as well." to use the phrasal verb "set up"
(e.g., "helps set up the DB user and creates a new schema as well.") and scan
the same README text for any other occurrences of "setup" used as a verb and
replace them with "set up" while keeping "setup" for the noun form where
appropriate.
- Around line 5-7: Docs omit the POSTGRES_PASSWORD mapping; add an entry to the
environment mappings list showing POSTGRES_PASSWORD (mapped from DB_PASSWORD) so
the README matches the docker-compose env mappings; update the same list where
POSTGRES_USER, POSTGRES_DB and POSTGRES_SCHEMA are listed (ensure the new
POSTGRES_PASSWORD line sits with those and uses the same phrasing).

In `@run-platform.sh`:
- Around line 241-242: The current sequence calling copy_or_merge_envs for
"sample.common.env" and "sample.env" writes sample.common.env into docker/.env
on first run and then skips merging sample.env because copy_or_merge_envs only
merges when opt_only_env or opt_update are set; update copy_or_merge_envs so
that if the destination file already exists it performs a merge unconditionally
(regardless of opt_only_env/opt_update), ensuring that the second call
copy_or_merge_envs "$script_dir/docker/sample.env" "$script_dir/docker/.env"
"docker compose" will merge its values into docker/.env on first-setup, and keep
existing flag logic only for the case when the destination does not yet exist.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4436a53c-2a4f-48dc-9d07-3c14dc13bc5c

📥 Commits

Reviewing files that changed from the base of the PR and between 60e86e3 and f1fd9b5.

📒 Files selected for processing (2)
  • docker/scripts/db-setup/README.md
  • run-platform.sh

…vice env.py

These optional vars use os.environ.get() (not EnvManager) since they can
be empty/unset. The import was accidentally removed in the previous commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
platform-service/src/unstract/platform_service/env.py (1)

13-14: Consider keeping a temporary REDIS_USERNAME fallback.

This rename is fine for the new config, but platform-service now ignores the legacy key entirely while other Redis env readers in the repo still accept both names. That makes mixed-rollout/manual deployments easier to break than necessary.

Suggested compatibility shim
-    REDIS_USER = os.environ.get("REDIS_USER")
+    REDIS_USER = os.environ.get("REDIS_USER") or os.environ.get("REDIS_USERNAME")
     REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platform-service/src/unstract/platform_service/env.py` around lines 13 - 14,
Update the Redis env var handling in env.py to accept the legacy name as a
fallback: keep the new REDIS_USER variable but if os.environ.get("REDIS_USER")
is None, read from "REDIS_USERNAME" instead so mixed rollouts don't break;
adjust the REDIS_USER assignment (and leave REDIS_PASSWORD unchanged) so callers
still use REDIS_USER while the code tolerates the older REDIS_USERNAME key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@platform-service/src/unstract/platform_service/env.py`:
- Around line 13-14: Update the Redis env var handling in env.py to accept the
legacy name as a fallback: keep the new REDIS_USER variable but if
os.environ.get("REDIS_USER") is None, read from "REDIS_USERNAME" instead so
mixed rollouts don't break; adjust the REDIS_USER assignment (and leave
REDIS_PASSWORD unchanged) so callers still use REDIS_USER while the code
tolerates the older REDIS_USERNAME key.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0ed35965-9dc7-4fe5-a2e0-251ece1bc8ae

📥 Commits

Reviewing files that changed from the base of the PR and between f1fd9b5 and 6dd73c1.

📒 Files selected for processing (1)
  • platform-service/src/unstract/platform_service/env.py

- Add missing POSTGRES_PASSWORD mapping to db-setup README
- Fix grammar: "helps setup" → "helps set up"
- Fix copy_or_merge_envs to always merge when dest exists, ensuring
  sample.env gets merged into .env on first setup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines +61 to +69
WORKFLOW_EXECUTION_FILE_STORAGE_CREDENTIALS='{"provider": "minio", "credentials": {"endpoint_url": "http://unstract-minio:9000", "key": "minio", "secret": "minio123"}}'
API_FILE_STORAGE_CREDENTIALS='{"provider": "minio", "credentials": {"endpoint_url": "http://unstract-minio:9000", "key": "minio", "secret": "minio123"}}'
PERMANENT_REMOTE_STORAGE='{"provider": "minio", "credentials": {"endpoint_url": "http://unstract-minio:9000", "key": "minio", "secret": "minio123"}}'
TEMPORARY_REMOTE_STORAGE='{"provider": "minio", "credentials": {"endpoint_url": "http://unstract-minio:9000", "key": "minio", "secret": "minio123"}}'
REMOTE_PROMPT_STUDIO_FILE_PATH="unstract/prompt-studio-data"

# File execution directory prefixes
WORKFLOW_EXECUTION_DIR_PREFIX="unstract/execution"
API_EXECUTION_DIR_PREFIX="unstract/api"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if these envs are needed everywhere. It's explicitly needed for backend and prompt-service (maybe workers too) but its not needed for others I believe. Can you recheck the necessity for this to be common?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are used by backend, workers, runner, and prompt-service (4 out of 6 services). Moving them to per-service files would duplicate the same MinIO credentials across 4 sample.env files — which is what this PR is trying to eliminate. Extra unused vars in platform-service/x2text-service containers are harmless since they just don't read them. Will move them out if you'd prefer though.

mathumathi-zipstack and others added 2 commits March 11, 2026 07:46
…allbacks

Address PR review comments:
- Merge docker/sample.common.env + docker/sample.env into single
  docker/sample.env for naming consistency with other folders
- Remove unused Qdrant env vars (not read by any Python code)
- Remove unused ADAPTER_LLMW_STATUS_RETRIES
- Move LLMWhisperer vars to backend and workers sample.env (only
  services that use them via workflow-execution)
- Add backward-compatible fallbacks for renamed env vars
  (PG_BE_* -> DB_*, DB_USERNAME -> DB_USER, REDIS_USERNAME -> REDIS_USER)
  to support rolling deployments
- Simplify run-platform.sh to single copy_or_merge_envs call
- Update all references across READMEs, sample.env headers, and
  worker_config.py validation messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

Test Results

Summary
  • Runner Tests: 11 passed, 0 failed (11 total)

Runner Tests - Full Report
filepath function $$\textcolor{#23d18b}{\tt{passed}}$$ SUBTOTAL
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_logs}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_cleanup}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_cleanup\_skip}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_client\_init}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image\_exists}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config\_without\_mount}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_run\_container}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image\_for\_sidecar}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_sidecar\_container}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{TOTAL}}$$ $$\textcolor{#23d18b}{\tt{11}}$$ $$\textcolor{#23d18b}{\tt{11}}$$

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants