Skip to content

[#3307] Recreated the Solr core from the image config-set on every start so config-set changes reach existing cores. - #3308

Open
AlexSkrypnyk wants to merge 8 commits into
mainfrom
feature/3307-solr-recreate-core
Open

AlexSkrypnyk wants to merge 8 commits into
mainfrom
feature/3307-solr-recreate-core

Conversation

@AlexSkrypnyk

@AlexSkrypnyk AlexSkrypnyk commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Closes #3307

Summary

The solr container now starts with solr-recreate drupal /solr-conf && exec solr-foreground. On every start, the drupal core directory on the volume is deleted and rebuilt from the config-set baked into the image, and then Solr starts. The index is kept, because the dataDir rewrite in .docker/solr.dockerfile puts it in /var/solr/drupal, outside the deleted directory.

Before this change, solr-precreate copied /solr-conf into /var/solr/data/drupal only when that directory didn't exist yet. On Lagoon, /var/solr is a persistent volume, so a core got its config at its first deploy and never again. Any later change to .docker/config/solr/config-set/ was silently ignored. A core created by uselagoon/solr-8 and then moved to uselagoon/solr-9-drupal kept its Solr 8 solrconfig.xml. It then failed to load with Error loading class 'solr.XSLTResponseWriter', and the site had no search. Local and CI volumes start empty, so this never showed up there.

After merge, a config-set change takes effect on the next deployment, and a Solr 8 core on a Solr 9 image loads again. The RUN step also fails the build when the dataDir rewrite stops matching a future jump-start config-set. Without that rewrite, the index would sit inside the recreated directory and be wiped on every start. The Drupal side, docker-compose.yml and the Solr image tag are unchanged.

Before / After

BEFORE: solr-precreate                      AFTER: solr-recreate + exec solr-foreground

 container start                             container start
       │                                           │
       ▼                                           ▼
 /var/solr/data/drupal exists?               rm -rf /var/solr/data/drupal
   ├─ no  ─▶ copy /solr-conf ─┐                    │
   └─ yes ─▶ keep old conf ───┤                    ▼
                              ▼              copy /solr-conf (image config-set)
                         start Solr                │
                              │                    ▼
                              ▼              exec solr-foreground (Java is tini's child)
 core loads the config from the FIRST              │
 deploy - Solr 8 conf on Solr 9 fails              ▼
 with 'solr.XSLTResponseWriter'              core loads the CURRENT config-set

 index: /var/solr/drupal (kept)              index: /var/solr/drupal (kept)

Changes

Solr image

  • .docker/solr.dockerfile: CMD runs solr-recreate and then exec solr-foreground, both shipped in the base image. With exec, Solr replaces sh, so the Java process is a direct child of tini and gets SIGTERM on a rollout. solr-foreground still runs the /docker-entrypoint-initdb.d scripts that solr-precreate ran.
  • .docker/solr.dockerfile: a grep -q after the dataDir sed fails the build when the index can't be moved out of the core directory.

Tests

  • .vortex/tests/phpunit/Functional/DockerComposeSolrTest.php (new, group p5) starts only the solr service on a fresh SUT and keeps the volume across container replacements. Each test was first run against solr-precreate to confirm it fails for the expected reason:
    • testSolrCoreConfigUpdate changes solr.mlt.timeAllowed in the SUT config-set, rebuilds and force-recreates the container. It then reads the value back from the running core's Config API (2000 before, 2345 after). It also checks that the indexed document survives and that Java's parent PID is 1. Before the fix: '2345' expected, '2000' returned.
    • testSolrCoreIncompatibleConfigReplaced writes solr.XSLTResponseWriter into the core's solrconfig.xml on the volume and replaces the container with the same image. This is the Solr 8 leftover from the issue, and also a rollout with no config change. The test asserts that there's no initFailures entry and the indexed document is still there. Before the fix: Error loading class 'solr.XSLTResponseWriter'.
    • testSolrBuildFailsWhenDataDirUnmatched changes the config-set's dataDir so the rewrite no longer matches, and asserts that docker compose build solr fails. Before the fix, the build succeeded.
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/solr.dockerfile: regenerated snapshot.

Documentation

  • .vortex/docs/content/development/environment/docker.mdx: the solr service description says the core is recreated on every start, where the index lives, when the build fails, and how to reindex after a schema change.

Upgrade note for consumer projects

The first deployment with this change replaces each existing core's config with the project's current config-set. A core that held a Solr 8 config gets a working core back. Reindex it with drush search-api:rebuild-tracker and drush search-api:index to repopulate it.

Screenshots

N/A

Summary by CodeRabbit

  • Bug Fixes

    • Solr now refreshes its core configuration from the image at startup while preserving the existing index, including when using a persistent data volume.
    • Docker builds now fail if the Solr data-directory setting is incompatible with the expected configuration.
  • Documentation

    • Added guidance on Solr configuration updates, index persistence, and rebuilding trackers and indexes after schema changes.

@AlexSkrypnyk AlexSkrypnyk added the A1 Board worker 1 label Nov 11, 2026
@github-project-automation github-project-automation Bot moved this to BACKLOG in Vortex 1.x Nov 11, 2026
@AlexSkrypnyk AlexSkrypnyk added this to the 1.43.0 milestone Nov 11, 2026
@coderabbitai

coderabbitai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The Solr image now checks the configured index path during build and recreates the drupal core from the image config-set at startup. Functional tests and documentation cover configuration refresh and index persistence.

Changes: Solr Core Refresh

Layer / File(s) Summary
Validate and refresh the Solr core
.docker/solr.dockerfile, .vortex/tests/phpunit/Functional/DockerComposeSolrTest.php, .vortex/docs/content/development/environment/docker.mdx
The image build checks for the expected dataDir replacement. Startup recreates the drupal core before starting Solr. Functional tests verify configuration refresh, index persistence, and build failure when the replacement is missing. The documentation describes core recreation and reindexing after schema changes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Severity of issue fixed: Medium

Merge Risk: Minimal · up to e769b

The Solr container now refreshes its core configuration from the image on each start while keeping the index in its separate data directory. No concrete merge-blocking risk was identified in the change.

Pre-merge checks: Passed 4

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and specifically describes the main change: recreating the Solr core from the image config-set on every container start so configuration changes reach existing cores.
Linked Issues check Passed Issue #3307 requires refresh of existing Solr core configuration, replacement of incompatible Solr 8 configuration, preservation of the index, a build check for the dataDir rewrite, tests, and documen…
Out of Scope Changes check Passed The changes stay within issue #3307. The Dockerfile change implements core refresh and signal handling. The functional tests verify refresh, recovery, index persistence, process behavior, and the buil…
Full details: Linked Issues check

Explanation

Issue #3307 requires refresh of existing Solr core configuration, replacement of incompatible Solr 8 configuration, preservation of the index, a build check for the dataDir rewrite, tests, and documentation. The reviewed changes run solr-recreate drupal /solr-conf before exec solr-foreground, keep the index at /var/solr/drupal, fail the build when the rewrite is absent, add functional coverage, regenerate the installer fixture, and document the behavior and reindex commands. The current PR evidence supports all coding requirements.

Full details: Out of Scope Changes check

Explanation

The changes stay within issue #3307. The Dockerfile change implements core refresh and signal handling. The functional tests verify refresh, recovery, index persistence, process behavior, and the build guard. The documentation and fixture update support the same behavior. No unrelated change is shown.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between e4933f5 and e769bc5.

Files ignored due to path filters: 1

  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/solr.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
Files selected for processing: 3

  • .docker/solr.dockerfile
  • .vortex/docs/content/development/environment/docker.mdx
  • .vortex/tests/phpunit/Functional/DockerComposeSolrTest.php

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

@github-actions

Copy link
Copy Markdown

📖 Documentation preview for this pull request has been deployed to Netlify:

https://6af42782b9013a21238473d1--vortex-docs.netlify.app

This preview is rebuilt on every commit and is not the production documentation site.

@github-actions

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

1 similar comment
@AlexSkrypnyk

This comment has been minimized.

@github-actions

This comment has been minimized.

@AlexSkrypnyk

Copy link
Copy Markdown
Member Author

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   100.00% (233/233)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@github-actions

Copy link
Copy Markdown

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   100.00% (233/233)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@codecov

codecov Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.50%. Comparing base (e4933f5) to head (e769bc5).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3308   +/-   ##
=======================================
  Coverage   92.50%   92.50%           
=======================================
  Files         116      116           
  Lines        5240     5240           
  Branches       49       49           
=======================================
  Hits         4847     4847           
  Misses        393      393           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Nov 11, 2026

This branch has not been deployed

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

Labels

A1 Board worker 1 Needs review Pull request needs a review from assigned developers

Projects

Status: BACKLOG

Development

Successfully merging this pull request may close these issues.

Solr config-set changes never reach an existing core on Lagoon, so Solr 8 cores fail to load on Solr 9

1 participant