-
-
Notifications
You must be signed in to change notification settings - Fork 361
feat: add worker mode support for horizontal scaling #3903
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implement container mode selection to enable separate queue worker containers, allowing horizontal scaling of background job processing independently from web servers. Changes: - Add LYCHEE_MODE environment variable detection to entrypoint.sh - web (default): Runs FrankenPHP/Octane web server - worker: Runs Laravel queue:work in auto-restart loop - Invalid values: Exit with error message - Implement auto-restart loop for worker mode - Configurable via QUEUE_NAMES (queue priority) - Configurable via WORKER_MAX_TIME (restart interval) - Automatic 5-second delay between restarts - Add lychee_worker service to docker-compose.yaml (commented out) - Security hardening matching web service - Resource limits and healthcheck - Shared volumes for photo processing - Add queue connection validation with warnings - Create comprehensive deployment guide (deploy-worker-mode.md) - Update knowledge map with worker mode architecture - Add Dockerfile comments documenting LYCHEE_MODE behavior - Create shell script unit tests for mode detection Completed tasks: - T-002-01: Shell script unit tests (6/6 passing) - T-002-02: LYCHEE_MODE detection implementation - T-002-06: Queue connection validation - T-002-07: QUEUE_CONNECTION=sync warning - T-002-08: Docker Compose worker service - T-002-23: Knowledge map updates - T-002-24: How-to deployment guide - T-002-25: Dockerfile documentation - T-002-26: Roadmap status update Pending (requires Docker): - Manual integration tests (T-002-03 to T-002-22) - Queue priority configuration verification - Worker healthcheck script implementation - SIGTERM graceful shutdown validation Spec impact: Feature 002 - Worker Mode Support - Spec: docs/specs/4-architecture/features/002-worker-mode/spec.md - Plan: docs/specs/4-architecture/features/002-worker-mode/plan.md - Tasks: docs/specs/4-architecture/features/002-worker-mode/tasks.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds a worker mode to container images: mode-aware entrypoint (LYCHEE_MODE=web|worker), a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks❌ Failed checks (1 warning)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (4)
docs/specs/2-how-to/deploy-worker-mode.md (1)
1-463: Add footer per coding guidelines.This deployment guide is comprehensive and well-structured. However, per the coding guidelines for Markdown documentation files, add an hr line followed by "Last updated: [date]" at the bottom.
📝 Add footer
Add this at the end of the file (after line 463):
+ +--- + +*Last updated: 2025-12-28*Based on coding guidelines: "At the bottom of documentation files, add an hr line followed by 'Last updated: [date of the update]'"
docs/specs/4-architecture/knowledge-map.md (1)
156-156: Update last-updated date to match PR completion.The knowledge map's last-updated date (December 22, 2025) predates the feature completion date (2025-12-28). Update to reflect the Worker Mode additions.
📝 Update date
-*Last updated: December 22, 2025* +*Last updated: December 28, 2025*docs/specs/4-architecture/features/002-worker-mode/tasks.md (1)
175-177: Consider standard notation for deferred task.The
[~]marker is non-standard for task checklists. While the deferral rationale is clear (FR-002-05 crash-loop detection deemed over-engineered for MVP), consider using a standard marker for tool compatibility.Options:
- Use
[ ](pending) with "DEFERRED" in the title (current approach is fine)- Move to "Notes / TODOs" section as a future enhancement
- Add a "## Deferred Tasks" section at the end
The current approach is acceptable given the clear explanation, but standardizing markers improves consistency with other task checklists.
docker-compose.yaml (1)
400-400: Consider simplifying healthcheck command.The
|| exit 1is redundant sincepgrepalready returns non-zero when no process matches. However, the explicit exit code improves readability and intent, so this is acceptable as-is.Alternative (equivalent) healthcheck
- test: ["CMD-SHELL", "pgrep -f 'queue:work' || exit 1"] + test: ["CMD-SHELL", "pgrep -f 'queue:work'"]
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
.env.exampleDockerfiledocker-compose.yamldocker/scripts/entrypoint.shdocs/specs/2-how-to/deploy-worker-mode.mddocs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/features/002-worker-mode/spec.mddocs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/knowledge-map.mddocs/specs/4-architecture/roadmap.mdtests/ImageProcessing/Import/ImportFromServerBrowseTest.phptests/docker/test-entrypoint-mode-detection.sh
🧰 Additional context used
📓 Path-based instructions (8)
**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.php: Any new PHP file should contain the license header and have a single blank line after the opening PHP tag
Variable names should be in snake_case in PHP
Apply the PSR-4 coding standard in PHP
Use in_array() with true as the third parameter in PHP
Only use booleans in if statements, not integers or strings
Use strict comparison (===) instead of loose comparison (==)
Avoid code duplication in both if and else statements
Do not use empty() in PHP
Use the moneyphp/money library for handling monetary values in PHP
Never use floats or doubles to represent monetary values; use integers representing the smallest currency unit (e.g., cents for USD)
**/*.php: Write or extend executable specifications (unit, behaviour, or scenario tests) ahead of implementation, confirm they fail, and then drive code to green before refactoring. List the expected success, validation, and failure branches and add thin failing tests for each path.
For PHP code, adhere to conventions: license headers in new files, strict comparison (===), no empty(), in_array() with third parameter true, snake_case variables, PSR-4 standard, test base classes (AbstractTestCase for Unit, BaseApiWithDataTest for Feature_v2).
Always run phpunit tests. If a test remains red, disable it with a TODO, note the reason, and capture the follow-up in the relevant plan.
Spotless now uses Palantir Java Format 2.78.0 with a 120-character wrap; configure IDE formatters to match before pushing code changes.
Keep each increment's control flow flat by delegating validation/normalisation into tiny pure helpers that return simple enums or result records, then compose them instead of introducing inline branching that inflates the branch count per change.
When introducing new helpers/utilities or editing files prone to style violations (records, DTOs, generated adapters), run the narrowest applicable lint target (for example phpstan) before the full pipeline. Note the command in the related plan/task.
For PHP changes, ru...
Files:
tests/ImageProcessing/Import/ImportFromServerBrowseTest.php
tests/**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
No need to mock the database in tests; use the in-memory SQLite database instead
Files:
tests/ImageProcessing/Import/ImportFromServerBrowseTest.php
**/*.md
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.md: Use Markdown format for documentation
At the bottom of documentation files, add an hr line followed by "Last updated: [date of the update]"
Files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/knowledge-map.mddocs/specs/2-how-to/deploy-worker-mode.mddocs/specs/4-architecture/roadmap.mddocs/specs/4-architecture/features/002-worker-mode/spec.md
docs/specs/4-architecture/features/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/specs/4-architecture/features/**/*.md: Author new specifications, feature plans, and task checklists using docs/specs/templates/feature-spec-template.md, docs/specs/templates/feature-plan-template.md, and docs/specs/templates/feature-tasks-template.md to keep structure, metadata, and verification notes uniform across features.
For any new UI feature or modification, include an ASCII mock-up in the specification (see docs/specs/4-architecture/spec-guidelines/ui-ascii-mockups.md).
When revising a specification, only document fallback or compatibility behaviour if the user explicitly asked for it; if instructions are unclear, pause and request confirmation instead of assuming a fallback.
For every task, refresh the relevant feature plan and note open questions; only move forward once the plan reflects the desired change. Update specs before code.
Update feature specs, feature plans, and tasks documents as progress is made and sync context to disk.
Capture prompt summaries, command sequences, and rationale in the active feature plan or an appendix referenced from it so downstream reviewers know how the change was produced (intent logging).
Track upcoming additions for contract tests, mutation analysis, and security/red-team prompt suites in the plans until automated jobs exist (quality gates).
Publish prompt and tool usage notes alongside the feature plan update so future agents understand how the iteration unfolded.
Files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/features/002-worker-mode/spec.md
docs/specs/4-architecture/features/**/{spec,plan,tasks}.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/specs/4-architecture/features/**/{spec,plan,tasks}.md: Start every feature by updating or creating its specification at docs/specs/4-architecture/features/-/spec.md, followed by plan and tasks documents after clarifications are resolved.
Generate or refresh the feature plan only after the specification is current and high-/medium-impact clarifications are resolved and recorded in the spec (plus ADRs where required).
Files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/features/002-worker-mode/spec.md
docs/specs/4-architecture/features/**/tasks.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/specs/4-architecture/features/**/tasks.md: Maintain a per-feature tasks checklist that mirrors the plan, orders tests before code, and keeps planned increments ≤90 minutes by preferring finer-grained entries and documenting sub-steps when something nears the limit.
Mark each task [x] in the feature's tasks.md as soon as it passes verification. Do not batch task completions—update the checklist after every individual task so progress is always visible.
Before committing, confirm every completed task in tasks.md is marked [x] and the roadmap status reflects current progress (validate task checklist).
Files:
docs/specs/4-architecture/features/002-worker-mode/tasks.md
docs/specs/4-architecture/knowledge-map.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/specs/4-architecture/knowledge-map.md: Skim docs/specs/4-architecture/knowledge-map.md and the up-to-date module snapshot in docs/specs/architecture-graph.json before planning so new work reinforces the architectural relationships already captured there.
Maintain the knowledge map by adding, adjusting, or pruning entries whenever new modules, dependencies, or contracts appear.
Files:
docs/specs/4-architecture/knowledge-map.md
docs/specs/4-architecture/roadmap.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/specs/4-architecture/roadmap.md: Update the roadmap regularly to reflect feature status and progress as work is made.
Keep high-level plans in docs/specs/4-architecture/roadmap.md, store each feature's spec/plan/tasks inside docs/specs/4-architecture/features/-/, and remove plans once work is complete.
Files:
docs/specs/4-architecture/roadmap.md
🧠 Learnings (21)
📚 Learning: 2025-12-28T18:12:55.752Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3901
File: app/Providers/AppServiceProvider.php:0-0
Timestamp: 2025-12-28T18:12:55.752Z
Learning: When using Laravel Octane's tick API, Octane::tick(...) returns an InvokeTickCallable that only has ->seconds(int) and ->immediate() methods. There is no ->every(N) method. Use the correct usage: Octane::tick('name', fn() => ...)->seconds(N) or Octane::tick('name', fn() => ..., N). Apply this guideline to PHP files across the project (not just AppServiceProvider.php).
Applied to files:
tests/ImageProcessing/Import/ImportFromServerBrowseTest.php
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/tasks.md : Maintain a per-feature tasks checklist that mirrors the plan, orders tests before code, and keeps planned increments ≤90 minutes by preferring finer-grained entries and documenting sub-steps when something nears the limit.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/tasks.md : Mark each task [x] in the feature's tasks.md as soon as it passes verification. Do not batch task completions—update the checklist after every individual task so progress is always visible.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/tasks.md : Before committing, confirm every completed task in tasks.md is marked [x] and the roadmap status reflects current progress (validate task checklist).
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/*.md : Update feature specs, feature plans, and tasks documents as progress is made and sync context to disk.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/*.md : For every task, refresh the relevant feature plan and note open questions; only move forward once the plan reflects the desired change. Update specs before code.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/*.md : Track upcoming additions for contract tests, mutation analysis, and security/red-team prompt suites in the plans until automated jobs exist (quality gates).
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/roadmap.mddocs/specs/4-architecture/features/002-worker-mode/spec.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/*.md : Publish prompt and tool usage notes alongside the feature plan update so future agents understand how the iteration unfolded.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/roadmap.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/*.md : Author new specifications, feature plans, and task checklists using docs/specs/templates/feature-spec-template.md, docs/specs/templates/feature-plan-template.md, and docs/specs/templates/feature-tasks-template.md to keep structure, metadata, and verification notes uniform across features.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/open-questions.md : Update or close entries in docs/specs/4-architecture/open-questions.md after completing work.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/roadmap.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/{spec,plan,tasks}.md : Generate or refresh the feature plan only after the specification is current and high-/medium-impact clarifications are resolved and recorded in the spec (plus ADRs where required).
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/tasks.mddocs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/*.md : Capture prompt summaries, command sequences, and rationale in the active feature plan or an appendix referenced from it so downstream reviewers know how the change was produced (intent logging).
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/roadmap.md : Keep high-level plans in docs/specs/4-architecture/roadmap.md, store each feature's spec/plan/tasks inside docs/specs/4-architecture/features/<NNN>-<feature-name>/, and remove plans once work is complete.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.mddocs/specs/4-architecture/roadmap.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/features/**/{spec,plan,tasks}.md : Start every feature by updating or creating its specification at docs/specs/4-architecture/features/<NNN>-<feature-name>/spec.md, followed by plan and tasks documents after clarifications are resolved.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/5-operations/analysis-gate-checklist.md : Run the analysis gate in docs/specs/5-operations/analysis-gate-checklist.md once spec, plan, and tasks agree; address findings before implementation.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Before hand-off, review your own changes, rerun checks, and ensure documentation/test coverage matches the behaviour (RCI self-review).
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Once an increment passes static analysis (phpstan), tests (phpunit) and formatting (php-cs-fixer), prepare the commit for the operator instead of executing it yourself. Stage the requested files, run ./scripts/codex-commit-review.sh to obtain a Conventional Commit message with a Spec impact: line whenever docs and code change together.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.md
📚 Learning: 2025-12-26T11:45:18.032Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3889
File: Dockerfile:8-23
Timestamp: 2025-12-26T11:45:18.032Z
Learning: In multi-stage Dockerfiles for the Lychee project, using `--ignore-platform-reqs` in the composer build stage is acceptable because it's only used to generate vendor files that are copied to the production stage. The platform requirements that matter are in the final production image, not the intermediate build stage.
Applied to files:
docs/specs/4-architecture/features/002-worker-mode/plan.mddocker-compose.yaml
📚 Learning: 2025-09-03T14:22:58.633Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3673
File: docs/add-oauth-provider.md:36-49
Timestamp: 2025-09-03T14:22:58.633Z
Learning: Lychee uses Laravel 12 but deliberately maintains the old infrastructure model without migrating to newer Laravel 11+ patterns. They continue using EventServiceProvider for event registration rather than the newer Event::listen approach in AppServiceProvider, so documentation should reflect the traditional EventServiceProvider pattern.
Applied to files:
docs/specs/4-architecture/knowledge-map.md
📚 Learning: 2025-12-26T11:45:18.032Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3889
File: Dockerfile:8-23
Timestamp: 2025-12-26T11:45:18.032Z
Learning: In multi-stage Dockerfiles (as used in Lychee), you may use --ignore-platform-reqs in the composer build stage when generating vendor files, because this stage only affects vendor generation and the final production image is what enforces platform requirements. Ensure: (1) this flag is confined to the build stage and does not affect the production runtime image, (2) the final stage uses the correct platform constraints and installed extensions, and (3) the produced vendor files are compatible with the production image’s PHP/runtime platform. This pattern should be applied to all Dockerfiles that contain a build stage with composer, not just a single file.
Applied to files:
Dockerfile
📚 Learning: 2025-12-22T14:12:18.082Z
Learnt from: CR
Repo: LycheeOrg/Lychee PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T14:12:18.082Z
Learning: Applies to docs/specs/4-architecture/roadmap.md : Update the roadmap regularly to reflect feature status and progress as work is made.
Applied to files:
docs/specs/4-architecture/roadmap.md
🪛 LanguageTool
docs/specs/4-architecture/features/002-worker-mode/tasks.md
[grammar] ~75-~75: Use a hyphen to join words.
Context: ...xtension - [x] T-002-08 – Extend docker compose.yaml with lychee_worker service ...
(QB_NEW_EN_HYPHEN)
[grammar] ~76-~76: Use a hyphen to join words.
Context: ...service configuration to existing docker compose.yaml with shared volumes and env...
(QB_NEW_EN_HYPHEN)
[grammar] ~122-~122: Use a hyphen to join words.
Context: ...nvironment variable documented in docker compose (lines 343-346) Notes: TestW...
(QB_NEW_EN_HYPHEN)
[grammar] ~125-~125: Use a hyphen to join words.
Context: ...ment QUEUE_NAMES configuration in docker compose.yaml comments. Intent: Opera...
(QB_NEW_EN_HYPHEN)
[grammar] ~128-~128: Use a hyphen to join words.
Context: ...erification commands:_ - Review docker compose.yaml worker service environment ...
(QB_NEW_EN_HYPHEN)
[style] ~129-~129: The words ‘explains’ and ‘explanation’ are quite similar. Consider replacing ‘explains’ with a different word.
Context: ...service environment section - Comment explains QUEUE_NAMES usage with example: "high,d...
(VERB_NOUN_SENT_LEVEL_REP)
[grammar] ~149-~149: Use a hyphen to join words.
Context: ... WORKER_MAX_TIME configuration in docker compose.yaml comments. Intent: Opera...
(QB_NEW_EN_HYPHEN)
[grammar] ~152-~152: Use a hyphen to join words.
Context: ...erification commands:_ - Review docker compose.yaml worker service environment ...
(QB_NEW_EN_HYPHEN)
[style] ~153-~153: The words ‘explains’ and ‘explanation’ are quite similar. Consider replacing ‘explains’ with a different word.
Context: ...service environment section - Comment explains WORKER_MAX_TIME purpose (memory leak mi...
(VERB_NOUN_SENT_LEVEL_REP)
[grammar] ~168-~168: Use a hyphen to join words.
Context: ...02-19 – Healthcheck documented in docker compose.yaml. Intent: Operator guida...
(QB_NEW_EN_HYPHEN)
[grammar] ~171-~171: Use a hyphen to join words.
Context: ...erification commands:_ - Review docker compose.yaml lines 397-404 - Comment e...
(QB_NEW_EN_HYPHEN)
[locale-violation] ~177-~177: The phrase ‘in future’ is British English. Did you mean: “in the future”?
Context: ... (pgrep) is adequate for MVP. If needed in future, can implement crash-loop detection as ...
(IN_FUTURE)
[grammar] ~190-~190: Use a hyphen to join words.
Context: ...ent graceful shutdown behavior in docker compose.yaml comments. Intent: Opera...
(QB_NEW_EN_HYPHEN)
[grammar] ~193-~193: Use a hyphen to join words.
Context: ...erification commands:_ - Review docker compose.yaml worker service environment ...
(QB_NEW_EN_HYPHEN)
docs/specs/4-architecture/features/002-worker-mode/plan.md
[grammar] ~262-~262: Use a hyphen to join words.
Context: ...nsion** Goal: Extend existing docker compose.yaml with optional worker servic...
(QB_NEW_EN_HYPHEN)
[grammar] ~269-~269: Use a hyphen to join words.
Context: ... 1. Research: Review existing docker compose.yaml structure (lychee_api, lych...
(QB_NEW_EN_HYPHEN)
[grammar] ~270-~270: Use a hyphen to join words.
Context: ...ement:** Add worker service to existing docker compose.yaml: ```yaml # Add this ...
(QB_NEW_EN_HYPHEN)
[grammar] ~631-~631: Use a hyphen to join words.
Context: ...rators can deploy worker mode via docker compose.yaml (lychee_worker service).
(QB_NEW_EN_HYPHEN)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: 3️⃣ Dockerfile Lint
- GitHub Check: 2️⃣ PHP dist / 8.5 - postgresql
- GitHub Check: 2️⃣ PHP dist / 8.5 - sqlite
- GitHub Check: 2️⃣ PHP dist / 8.4 - sqlite
- GitHub Check: 2️⃣ PHP dist / 8.5 - mariadb
- GitHub Check: 2️⃣ PHP dist / 8.4 - mariadb
- GitHub Check: 2️⃣ PHP dist / 8.4 - postgresql
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- ImageProcessing
🔇 Additional comments (10)
docs/specs/4-architecture/roadmap.md (1)
15-15: LGTM! Feature completion documented correctly.The Worker Mode Support feature is appropriately marked as completed with a clear completion date and concise summary of deliverables.
docs/specs/4-architecture/features/002-worker-mode/spec.md (1)
36-36: LGTM! Terminology standardized to Docker Compose v2.The updates correctly use
docker compose(the v2 CLI command) instead ofdocker-compose. This aligns with current Docker Compose best practices and matches the terminology used throughout the PR.Also applies to: 46-46, 63-63, 100-100, 126-126, 182-182
docs/specs/4-architecture/features/002-worker-mode/plan.md (1)
629-631: LGTM! Plan status correctly updated to Complete.The plan appropriately reflects the feature's production-ready status with completion date and clear next steps for deployment.
docs/specs/4-architecture/knowledge-map.md (1)
28-34: LGTM! Worker Mode architecture documented clearly.The Infrastructure Layer section now includes comprehensive Worker Mode documentation covering mode selection, auto-restart behavior, configuration, and deployment guidance.
docs/specs/4-architecture/features/002-worker-mode/tasks.md (1)
15-196: LGTM! Tasks comprehensively documented with verification steps.The task checklist is thorough with clear intent statements, verification commands, and implementation notes for each task. The progression from tests-first to implementation reflects good practices.
Dockerfile (1)
143-147: LGTM! Clear documentation of container mode behavior.The added comments effectively document the LYCHEE_MODE environment variable's impact on container behavior and reference the deployment guide for operator guidance.
tests/ImageProcessing/Import/ImportFromServerBrowseTest.php (1)
41-41: LGTM: Test updated to include new 'docker' directory.The addition of 'docker' to the expected directory list is correct and properly positioned in the alphabetically sorted array.
docker-compose.yaml (1)
289-413: Well-structured worker service configuration.The lychee_worker service is comprehensively configured with:
- Appropriate security hardening matching the API service
- Resource limits suitable for background job processing
- Shared volumes for photo processing access
- Environment variables aligned with worker mode requirements
One observation: Line 336 hardcodes
LYCHEE_MODE: workerrather than using${LYCHEE_MODE:-worker}. This prevents override from .env, which may be intentional for operational clarity (ensuring worker containers always run in worker mode), but consider whether environment-level override would be useful for testing scenarios.tests/docker/test-entrypoint-mode-detection.sh (1)
1-137: Excellent test coverage for mode detection logic.This shell script test suite demonstrates good testing practices:
- Proper use of portable sh syntax (not bash-specific features)
- Comprehensive coverage of success and failure paths (web, worker, unset, invalid modes)
- Clean helper function design with pattern matching and exit code verification
- Proper cleanup of temporary test artifacts
- Clear color-coded output for test results
The test structure aligns well with the entrypoint.sh behavior it validates.
docker/scripts/entrypoint.sh (1)
80-143: Well-designed worker mode implementation.The mode detection and worker loop structure is solid:
- Clean case-based mode switching with appropriate defaults
- Auto-restart loop properly handles both clean exits and failures (after fixing EXIT_CODE bug)
- Environment-driven configuration (QUEUE_NAMES, WORKER_MAX_TIME, QUEUE_CONNECTION)
- Helpful warning for QUEUE_CONNECTION=sync
- Reasonable 5-second restart delay prevents thrashing
- Error handling for invalid LYCHEE_MODE values
The infinite loop design is appropriate for a long-running worker process with memory leak mitigation (--max-time) and crash recovery.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
docker/scripts/entrypoint.sh (1)
117-127: Consider making--timeoutconfigurable.The job timeout is hardcoded to 3600 seconds (1 hour). If users have legitimate long-running jobs (e.g., large video processing), they cannot override this without modifying the script.
🔧 Optional: Add WORKER_TIMEOUT environment variable
QUEUE_NAMES=${QUEUE_NAMES:-default} WORKER_MAX_TIME=${WORKER_MAX_TIME:-3600} + WORKER_TIMEOUT=${WORKER_TIMEOUT:-3600} QUEUE_CONNECTION=${QUEUE_CONNECTION:-sync} echo "📋 Queue names: $QUEUE_NAMES" echo "⏱️ Max time: ${WORKER_MAX_TIME}s" + echo "⏱️ Job timeout: ${WORKER_TIMEOUT}s" echo "📡 Queue connection: $QUEUE_CONNECTION"php artisan queue:work \ --queue="$QUEUE_NAMES" \ --tries=3 \ - --timeout=3600 \ + --timeout="$WORKER_TIMEOUT" \ --sleep=3 \ --max-time="$WORKER_MAX_TIME" || EXIT_CODE=$?
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.env.exampledocker/scripts/entrypoint.sh
🚧 Files skipped from review as they are similar to previous changes (1)
- .env.example
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 2️⃣ PHP dist / 8.5 - mariadb
- GitHub Check: 2️⃣ PHP dist / 8.4 - postgresql
- GitHub Check: 2️⃣ PHP dist / 8.4 - sqlite
- GitHub Check: 2️⃣ PHP dist / 8.4 - mariadb
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Install
- GitHub Check: 1️⃣ PHP tests / 8.4 - postgresql -- Install
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Install
- GitHub Check: 1️⃣ PHP tests / 8.4 - mariadb -- Install
🔇 Additional comments (3)
docker/scripts/entrypoint.sh (3)
80-88: LGTM on web mode implementation.Clean and straightforward mode detection with sensible default. The
exec "$@"properly replaces the shell with the CMD from Dockerfile, preserving signal handling for the web server.
114-115: Good fix for the EXIT_CODE reset issue.Initializing
EXIT_CODE=0before each command execution correctly addresses the previous review concern. Now each iteration properly reflects its own exit status rather than carrying over from previous failures.
139-142: Good error handling for invalid mode.Clear error message with guidance on valid values, and proper exit code 1 for failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
docker/scripts/entrypoint.sh (2)
93-107: Consider documenting the intentional "sync" default.The code defaults
QUEUE_CONNECTIONto "sync" (line 96) but warns this is not recommended (lines 103-107). While this is a safe fallback strategy (works synchronously without configuration), the intent may not be immediately clear to maintainers.Consider adding a brief comment explaining this is an intentional safe-default-with-warning pattern.
💡 Optional: Add clarifying comment
# Get queue configuration from environment QUEUE_NAMES=${QUEUE_NAMES:-default} WORKER_MAX_TIME=${WORKER_MAX_TIME:-3600} + # Default to 'sync' as a safe fallback, but warn user to configure async queue QUEUE_CONNECTION=${QUEUE_CONNECTION:-sync}
109-113: Minor: Misplaced comment on line 113.The trailing comment on line 113 ("Auto-restart loop...") describes the
whileloop that starts on line 116, not thetrapstatement. Consider moving it to line 115 for clarity.💡 Optional: Improve comment placement
# Track if we should keep running KEEP_RUNNING=true # Handle graceful shutdown - trap 'echo "🛑 Received shutdown signal, stopping..."; KEEP_RUNNING=false' TERM INT # Auto-restart loop: if queue:work exits, restart it - - # This handles memory leak mitigation (max-time) and crash recovery + trap 'echo "🛑 Received shutdown signal, stopping..."; KEEP_RUNNING=false' TERM INT + + # Auto-restart loop: if queue:work exits, restart it + # This handles memory leak mitigation (max-time) and crash recovery while $KEEP_RUNNING; do
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
docker/scripts/entrypoint.sh
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 2️⃣ PHP dist / 8.5 - mariadb
- GitHub Check: 2️⃣ PHP dist / 8.4 - postgresql
- GitHub Check: 2️⃣ PHP dist / 8.5 - postgresql
- GitHub Check: 2️⃣ PHP dist / 8.4 - sqlite
- GitHub Check: 2️⃣ PHP dist / 8.4 - mariadb
- GitHub Check: 2️⃣ PHP dist / 8.5 - sqlite
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Webshop
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.4 - mariadb -- Install
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Install
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- ImageProcessing
- GitHub Check: 1️⃣ PHP tests / 8.5 - sqlite -- Unit
- GitHub Check: 1️⃣ PHP tests / 8.5 - postgresql -- Feature_v2
- GitHub Check: 1️⃣ PHP tests / 8.5 - mariadb -- Unit
🔇 Additional comments (3)
docker/scripts/entrypoint.sh (3)
80-88: LGTM! Clean mode detection and web mode implementation.The default to "web" mode ensures backward compatibility, and using
exec "$@"properly replaces the shell process with the Dockerfile CMD, ensuring signal propagation works correctly.
150-153: LGTM! Proper error handling for invalid mode.The default case provides a clear error message and exits with an appropriate non-zero code, preventing silent failures from misconfiguration.
115-148: Worker loop implementation looks solid.The auto-restart logic correctly:
- Resets
EXIT_CODEto 0 before each iteration (line 120) ✓- Captures exit codes from failed commands (line 132) ✓
- Checks the shutdown flag before restarting (lines 140-144) ✓
- Uses appropriate delays to prevent rapid restart loops (line 147) ✓
Laravel's
queue:workcommand handles SIGTERM/SIGINT gracefully — it finishes the current job before exiting, ensuring jobs aren't killed mid-run. The signal-handling flow in this script correctly relies on that behavior: SIGTERM triggers the worker to exit cleanly, the loop condition prevents restart, and the script exits with the appropriate exit code.
Implement container mode selection to enable separate queue worker containers, allowing horizontal scaling of background job processing independently from web servers.
Changes:
Completed tasks:
Pending (requires Docker):
Spec impact: Feature 002 - Worker Mode Support
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Configuration Changes
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.