Skip to content

fix: stabilize self-hosted Docker restarts for api/deriver#483

Closed
DevNewbie1826 wants to merge 1 commit intoplastic-labs:mainfrom
DevNewbie1826:fix/docker-compose-restart-stability
Closed

fix: stabilize self-hosted Docker restarts for api/deriver#483
DevNewbie1826 wants to merge 1 commit intoplastic-labs:mainfrom
DevNewbie1826:fix/docker-compose-restart-stability

Conversation

@DevNewbie1826
Copy link
Copy Markdown

@DevNewbie1826 DevNewbie1826 commented Apr 3, 2026

Summary

  • remove the development bind mounts (.:/app and venv:/app/.venv) from the Docker compose example for api and deriver
  • replace the API entrypoint with an image-local command that runs DB migrations and then starts FastAPI
  • add a deriver-specific healthcheck instead of probing /openapi.json

Why

The previous compose example could fail after docker compose restart api deriver with errors like:

  • ModuleNotFoundError: No module named 'sqlalchemy'
  • deriver reporting unhealthy because it inherited an API-style web healthcheck

The root cause was the dev-oriented runtime mount structure overlaying /app and /app/.venv, which made dependency resolution unstable across restarts.

Verification

I verified all of the following locally:

  • docker compose up -d --build api deriver
  • docker compose restart api deriver
  • api becomes healthy and http://localhost:8000/openapi.json responds
  • deriver becomes healthy with the new healthcheck
  • hermes honcho status connects successfully after restart

Summary by CodeRabbit

  • Chores
    • Updated Docker Compose configuration to automatically provision the database on API startup.
    • Optimized Docker setup by streamlining volume and mount configurations.
    • Added health monitoring to the deriver service.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

Walkthrough

This change updates the Docker Compose configuration to inline the database provisioning command in the API service entrypoint, removing separate volume mounts for the project directory and venv, eliminating the named venv volume declaration, and adding a healthcheck to the deriver service.

Changes

Cohort / File(s) Summary
Docker Compose Configuration
docker-compose.yml.example
Modified api service entrypoint to execute database provisioning script before FastAPI startup; removed project directory and venv volume bind-mounts from both api and deriver services; removed named venv volume declaration; added healthcheck to deriver service with Python import verification (30s interval, 10s timeout, 5s start period, 3 retries).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • VVoruganti

Poem

🐰 A compose file hops with care,
Volumes gone, but venv still there,
Entrypoint scripts inline run free,
Database provisions, then FastAPI spree!
Deriver keeps watch with healthcheck eyes. 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: stabilizing Docker restarts for api/deriver services by fixing the docker-compose configuration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
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 (3)
docker-compose.yml.example (3)

27-27: Consider using explicit Python path for consistency.

The entrypoint uses /app/.venv/bin/python explicitly, but the healthcheck uses bare python. While this should work due to the ENV PATH set in the Dockerfile, using the explicit path would be more consistent and defensive.

Suggested fix
-      test: ["CMD-SHELL", "python -c 'import src.deriver' || exit 1"]
+      test: ["CMD-SHELL", "/app/.venv/bin/python -c 'import src.deriver'"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker-compose.yml.example` at line 27, Update the healthcheck command to use
the same explicit Python interpreter path as the container entrypoint instead of
bare "python": replace the test command that runs "python -c 'import
src.deriver' || exit 1" so it invokes "/app/.venv/bin/python -c 'import
src.deriver' || exit 1" (reference the existing healthcheck test entry and the
entrypoint's /app/.venv/bin/python usage to locate where to change).

7-7: The -l flag is unnecessary.

The login shell flag (-l) causes the shell to source profile files (e.g., /etc/profile, ~/.profile), which is unnecessary overhead here. The Dockerfile already sets ENV PATH="/app/.venv/bin:$PATH", so the PATH is available without needing a login shell.

Suggested simplification
-    entrypoint: ["sh", "-lc", "/app/.venv/bin/python scripts/provision_db.py && exec /app/.venv/bin/fastapi run --host 0.0.0.0 src/main.py"]
+    entrypoint: ["sh", "-c", "/app/.venv/bin/python scripts/provision_db.py && exec /app/.venv/bin/fastapi run --host 0.0.0.0 src/main.py"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker-compose.yml.example` at line 7, Remove the unnecessary login-shell
flag from the Docker entrypoint: change the entrypoint array that currently uses
["sh", "-lc", "/app/.venv/bin/python scripts/provision_db.py && exec
/app/.venv/bin/fastapi run --host 0.0.0.0 src/main.py"] to use only the "-c"
flag (i.e., ["sh", "-c", ...]) so the shell does not source login profile files;
keep the existing commands (provision_db.py and exec fastapi run) unchanged.

26-31: Healthcheck only verifies import capability, not process liveness.

The current healthcheck (import src.deriver) only confirms the module can be imported—it doesn't verify the actual deriver process is running and responsive. If the running process hangs or crashes while the Python environment remains intact, this check would still pass.

Consider a healthcheck that verifies the process is actually operational. For example, if the deriver exposes any metrics endpoint or has a status mechanism, use that. Alternatively, check if the specific process is running:

Option: Check process is running
     healthcheck:
-      test: ["CMD-SHELL", "python -c 'import src.deriver' || exit 1"]
+      test: ["CMD-SHELL", "pgrep -f 'python -m src.deriver' || exit 1"]
       interval: 30s
       timeout: 10s
       start_period: 5s
       retries: 3

Minor: The || exit 1 is redundant since CMD-SHELL already uses the command's exit code.

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

In `@docker-compose.yml.example` around lines 26 - 31, The healthcheck currently
only runs "import src.deriver" which verifies importability but not the running
deriver process; replace the test under healthcheck to probe the actual service
(e.g., curl the deriver's health/metrics HTTP endpoint or run a lightweight
process check like pgrep for the deriver process) and remove the redundant "||
exit 1" from the CMD-SHELL invocation; update the healthcheck block (symbols:
healthcheck, test, CMD-SHELL, import src.deriver) to use the chosen liveliness
check and appropriate interval/timeout values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docker-compose.yml.example`:
- Line 27: Update the healthcheck command to use the same explicit Python
interpreter path as the container entrypoint instead of bare "python": replace
the test command that runs "python -c 'import src.deriver' || exit 1" so it
invokes "/app/.venv/bin/python -c 'import src.deriver' || exit 1" (reference the
existing healthcheck test entry and the entrypoint's /app/.venv/bin/python usage
to locate where to change).
- Line 7: Remove the unnecessary login-shell flag from the Docker entrypoint:
change the entrypoint array that currently uses ["sh", "-lc",
"/app/.venv/bin/python scripts/provision_db.py && exec /app/.venv/bin/fastapi
run --host 0.0.0.0 src/main.py"] to use only the "-c" flag (i.e., ["sh", "-c",
...]) so the shell does not source login profile files; keep the existing
commands (provision_db.py and exec fastapi run) unchanged.
- Around line 26-31: The healthcheck currently only runs "import src.deriver"
which verifies importability but not the running deriver process; replace the
test under healthcheck to probe the actual service (e.g., curl the deriver's
health/metrics HTTP endpoint or run a lightweight process check like pgrep for
the deriver process) and remove the redundant "|| exit 1" from the CMD-SHELL
invocation; update the healthcheck block (symbols: healthcheck, test, CMD-SHELL,
import src.deriver) to use the chosen liveliness check and appropriate
interval/timeout values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf638cdd-af8d-46cf-ba24-96d9a78a25dc

📥 Commits

Reviewing files that changed from the base of the PR and between 29ff465 and abffea6.

📒 Files selected for processing (1)
  • docker-compose.yml.example

@ajspig
Copy link
Copy Markdown
Contributor

ajspig commented Apr 7, 2026

Thanks @DevNewbie1826!
You correctly identified the bind mount issue — those dev-oriented .:/app and venv:/app/.venv mounts were definitely causing restart instability. PR #510 (self-hosting docs overhaul) addresses both of your main fixes: it comments out the bind mounts as optional dev-only configuration and binds all ports to 127.0.0.1.

The deriver healthcheck is a nice touch — if you'd like to contribute that as a small focused PR after #510 merges, we'd welcome it. Closing as covered.

@ajspig ajspig closed this Apr 7, 2026
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.

2 participants