Skip to content

fix(gunicorn): parse DEBUG env var as a boolean#3589

Open
immanuwell wants to merge 1 commit into
bunkerity:masterfrom
immanuwell:fix-debug-env-bool
Open

fix(gunicorn): parse DEBUG env var as a boolean#3589
immanuwell wants to merge 1 commit into
bunkerity:masterfrom
immanuwell:fix-debug-env-bool

Conversation

@immanuwell
Copy link
Copy Markdown

Small fix, but pretty real.

DEBUG was read with raw getenv(...) in the API/UI Gunicorn configs. So DEBUG=false or DEBUG=0 still turned debug mode on, because Python treats non-empty strings as truthy. Kinda sneaky.

Repro:

  1. Set DEBUG=false
  2. Load src/ui/utils/tmp-gunicorn.conf.py
  3. Before this patch you get:
    • DEBUG == "false"
    • daemon == True
    • loglevel == "debug"
    • reload enabled

This path is actually live:

  • src/ui/entrypoint.sh starts utils/tmp-gunicorn.conf.py
  • src/ui/entrypoint.sh starts utils/gunicorn.conf.py
  • src/api/entrypoint.sh starts utils/gunicorn.conf.py

After this patch, false-ish values stay off and true-ish values still work, all good.

@immanuwell immanuwell requested a review from TheophileDiot as a code owner May 23, 2026 13:17
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1fe8118f-6b0f-4fea-9c99-58c9a3ea0675

📥 Commits

Reviewing files that changed from the base of the PR and between 0215f58 and a2a3d8e.

📒 Files selected for processing (4)
  • src/api/utils/gunicorn.conf.py
  • src/common/utils/common_utils.py
  • src/ui/utils/gunicorn.conf.py
  • src/ui/utils/tmp-gunicorn.conf.py
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: Python code must follow snake_case naming for modules and functions, PascalCase for classes, and be formatted with Black at 160 characters per line
Python linting with flake8 must ignore error codes: E266, E402, E501, E722, W503

**/*.py: Python code must use Black for formatting with 160 character line lengths
Python code must conform to Flake8 linting with ignores defined in .pre-commit-config.yaml
Python modules and functions must use snake_case naming convention
Python classes must use PascalCase naming convention

Files:

  • src/ui/utils/tmp-gunicorn.conf.py
  • src/common/utils/common_utils.py
  • src/ui/utils/gunicorn.conf.py
  • src/api/utils/gunicorn.conf.py

⚙️ CodeRabbit configuration file

**/*.py: Follow BunkerWeb's Python standards and security posture:

  • Use snake_case for functions and variables, PascalCase for classes, and provide concise, accurate docstrings for public classes, functions, and methods.
  • Respect Black formatting with a 160-character line limit and the existing pre-commit conventions. Do not insist on adding type annotations to previously untyped code, but accept them when added consistently.
  • Catch specific exceptions; never use bare except:. Catching Exception is acceptable only at explicit process boundaries (for example scheduler loops, outer job runners, worker entrypoints, or graceful-shutdown boundaries) when the code logs enough context and either re-raises, returns an error status, or terminates safely.
  • Never use os.system, subprocess.*(..., shell=True), eval, or exec. Pass subprocess arguments as a list and prefer explicit binary paths for privileged operations.
  • Do not use unsafe deserialisers (pickle, marshal, shelve, jsonpickle, dill) for untrusted data. Use yaml.safe_load() rather than unsafe YAML loading.
  • Open files with an explicit encoding (normally utf-8) and use with statements for files, sockets, database sessions, and temporary resources.
  • Use secrets for token generation and hmac.compare_digest for token, HMAC, or signature comparisons.
  • For HTTP clients (requests, httpx): always set an explicit timeout, validate destination URLs to block RFC1918/loopback/link-local ranges (SSRF), disable automatic redirects to internal hosts, and be careful with proxy settings.
  • For filesystem operations: resolve paths with Path.resolve() and verify they remain under the intended base directory before reading or writing (path traversal).
  • Use defusedxml rather than stdlib XML parsers for untrusted XML.
  • For SQLAlchemy, use bound parameters and safe query construction. Never call text() with f-strings or .format(), and flag .execute() calls built...

Files:

  • src/ui/utils/tmp-gunicorn.conf.py
  • src/common/utils/common_utils.py
  • src/ui/utils/gunicorn.conf.py
  • src/api/utils/gunicorn.conf.py
src/ui/**/*.py

⚙️ CodeRabbit configuration file

src/ui/**/*.py: src/ui/ is the admin UI and related backend:

  • State-changing routes must enforce CSRF protection where browser sessions are used.
  • Session, remember-me, and auth-cookie changes must preserve Secure, HttpOnly, and appropriate SameSite behaviour.
  • Redirect targets such as next parameters must be validated against an allowlist or local-path policy.
  • For templates and forms, escape user-controlled data, validate uploads by type and size, and keep files outside the web root unless there is a deliberate reviewed exception.
  • BunkerWeb uses bcrypt; flag any move towards weak password hashing or plaintext credential handling.

Files:

  • src/ui/utils/tmp-gunicorn.conf.py
  • src/ui/utils/gunicorn.conf.py
src/api/**/*.py

⚙️ CodeRabbit configuration file

src/api/**/*.py: src/api/ is the FastAPI service:

  • Avoid blocking I/O in async endpoints and background tasks.
  • Validate request models strictly and return precise HTTP status codes.
  • Authentication, authorisation, CORS, and rate-limiting changes must preserve secure defaults.
  • Propagate bounded timeouts to any outbound calls and avoid retry loops without caps, jitter, and logging.
  • Be careful with streaming responses, file downloads, and proxy-like behaviour: validate content types, filenames, and upstream destinations.

Files:

  • src/api/utils/gunicorn.conf.py
🔇 Additional comments (4)
src/common/utils/common_utils.py (1)

18-19: ⚡ Quick win

Add a docstring to the new public helper.

getenv_bool is public but has no docstring. Add a short contract (accepted truthy values and default behaviour) so call-sites stay unambiguous. Line 18.

[সহgest_essential_refactor]

As per coding guidelines, “provide concise, accurate docstrings for public classes, functions, and methods.”

src/api/utils/gunicorn.conf.py (1)

19-19: LGTM!

Also applies to: 123-123

src/ui/utils/gunicorn.conf.py (1)

21-21: LGTM!

Also applies to: 123-123

src/ui/utils/tmp-gunicorn.conf.py (1)

10-10: LGTM!

Also applies to: 32-32


Components affected

src/common – Added getenv_bool(name: str, default: str = "no") -> bool utility function to common_utils.py. Returns True only for values in ("1", "true", "yes", "on") after normalisation; otherwise returns False.

src/api – Updated utils/gunicorn.conf.py to parse DEBUG environment variable as boolean using getenv_bool() instead of raw string comparison.

src/ui – Updated utils/gunicorn.conf.py and utils/tmp-gunicorn.conf.py to parse DEBUG environment variable as boolean using getenv_bool() instead of raw string comparison.

User-visible behaviour changes

Fixes a bug where setting DEBUG=false or DEBUG=0 was incorrectly treated as truthy (non-empty string), leaving debug mode enabled (daemon=True, loglevel="debug", reload enabled). With this fix, only explicit truthy values ("1", "true", "yes", "on") enable debug mode; all other values (including "false" and "0") now correctly disable it.

Configuration changes

The DEBUG environment variable parsing now follows a strict boolean convention across all Gunicorn configurations (API and UI components), making behaviour consistent and predictable.

Testing and documentation

No tests were added or updated. No documentation updates were made to reflect the change.

Walkthrough

A centralised boolean environment variable parser is introduced to common_utils.py and then integrated into three Gunicorn configuration files (API, UI, and temporary UI), replacing direct getenv("DEBUG", False) calls with a standardised getenv_bool("DEBUG") approach for consistent DEBUG flag parsing.

Changes

Boolean Environment Variable Parsing

Layer / File(s) Summary
Boolean utility function
src/common/utils/common_utils.py
New getenv_bool(name: str, default: str = "no") -> bool function parses environment variables as booleans, treating normalised values "1", "true", "yes", "on" as truthy, with "no" as the default when unset.
Gunicorn configuration updates
src/api/utils/gunicorn.conf.py, src/ui/utils/gunicorn.conf.py, src/ui/utils/tmp-gunicorn.conf.py
Three Gunicorn configuration files import getenv_bool and replace getenv("DEBUG", False) with getenv_bool("DEBUG") on lines 123 (API), 123 (UI), and 32 (temporary UI) respectively, standardising DEBUG flag parsing across environments.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A boolean's born in common ground,
Through three config files it's found—
No more string confusion, just true or no,
Debug flags now consistently flow. 🎯

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main fix: introducing proper boolean parsing for the DEBUG environment variable in Gunicorn configs, addressing the exact issue addressed in the changeset.
Description check ✅ Passed The description is directly related to the changeset, providing a clear problem statement, reproduction steps, affected files, and the solution rationale.

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


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.

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.

1 participant