Local Solr with DDEV
Overview
DDEV can run a local Solr service for Search API development and testing. This is useful for testing search functionality without relying on a remote-hosted Solr service.
Installation
Add Solr Service
ddev get ddev/ddev-solr
ddev restartThis creates:
.ddev/docker-compose.solr.yaml- Solr service configuration.ddev/solr/- Solr configuration directory.ddev/commands/host/solr-admin- Command to open Solr admin UI
Configuration Files Created
.ddev/
├── docker-compose.solr.yaml # Solr service definition
├── solr/
│ ├── configsets/ # Solr core configurations
│ ├── lib/ # Custom Solr libraries
│ └── security.json # Basic auth config
└── commands/
├── host/solr-admin # Open Solr admin UI
└── solr/ # Solr commands inside containerAccess Points
| Service | URL | Credentials |
|---|---|---|
| Solr Admin UI | https://sitename.ddev.site:8943/solr |
solr / SolrRocks |
| Internal (from Drupal) | http://solr:8983/solr |
solr / SolrRocks |
Note: External port is 8943 (HTTPS), internal port is 8983 (HTTP).
Drupal Configuration
Override Search API Server in settings.ddev.php
CRITICAL: Use settings.ddev.php for DDEV-specific overrides, NOT settings.local.php.
// Override the remote Solr server to use local DDEV Solr
$config['search_api.server.my_search_server']['backend_config']['connector'] = 'standard';
$config['search_api.server.my_search_server']['backend_config']['connector_config'] = [
'scheme' => 'http',
'host' => 'solr', // DDEV container hostname
'port' => '8983', // Internal port
'path' => '/',
'core' => 'drupal', // Core name from configset
'timeout' => 5,
'index_timeout' => 5,
'optimize_timeout' => 10,
'finalize_timeout' => 30,
'solr_version' => '9',
'http_method' => 'AUTO',
'commit_within' => 1000,
'username' => 'solr',
'password' => 'SolrRocks',
];Why settings.ddev.php?
✅ DO: Put DDEV overrides in settings.ddev.php
- Only loads when
IS_DDEV_PROJECT=true - Never loads in the remote/production environment
- DDEV-managed file
❌ DON'T: Put DDEV overrides in settings.local.php
- May be tracked in git
- May be deployed to production
- Can break production if it contains DDEV-specific config
Common Workflows
Verify Solr is Running
# Check service status
ddev describe
# Should show:
# solr OK https://sitename.ddev.site:8943Index Content
# Clear and reindex
ddev drush search-api:clear
ddev drush search-api:index
# Check status
ddev drush search-api:statusTest Search Queries
# Search via Drush
ddev drush search-api:search mixed_entities "test query"
# Or via Solr admin UI
ddev solr-adminView Solr Logs
# Recent logs
ddev logs -s solr | tail -50
# Follow logs
ddev logs -s solr -fAccess Solr Admin UI
# Open in browser
ddev solr-admin
# Or manually visit
# https://sitename.ddev.site:8943/solr
# Username: solr
# Password: SolrRocksTroubleshooting
Connection Refused
Problem: Drupal can't connect to Solr
Solution:
# Verify Solr is running
ddev describe | grep solr
# Restart if needed
ddev restart
# Check Drupal can reach Solr
ddev exec curl http://solr:8983/solr/admin/pingWrong Connector in Production
Problem: Production shows Could not resolve host: solr
Cause: DDEV Solr config deployed to the remote/production environment
Solution:
- Move config from
settings.local.php→settings.ddev.php - Ensure
settings.local.phpis in.gitignore - Never commit DDEV-specific settings to git if they override remote services
Core Not Found
Problem: Solr core 'drupal' doesn't exist
Solution:
# Check cores
ddev solr-admin
# Navigate to Core Admin
# If missing, recreate configset
ddev restartIndexing Fails
Problem: Search API indexing times out or fails
Solution:
# Check Solr logs for errors
ddev logs -s solr
# Verify core is healthy
curl -u solr:SolrRocks "https://sitename.ddev.site:8943/solr/drupal/admin/ping"
# Clear and retry
ddev drush search-api:clear
ddev drush search-api:indexConfiguration Best Practices
1. Settings File Hierarchy
// settings.php - Shared settings
// include your hosting target's auto-config include here, if any
// settings.ddev.php - DDEV-only (only loads if IS_DDEV_PROJECT=true)
$config['search_api.server.my_search_server']['backend_config']['connector'] = 'standard';
// settings.local.php - Developer-specific (gitignored)
// Use for personal overrides only, never DDEV service config2. Connector Selection
| Environment | Connector | Config |
|---|---|---|
| Remote/production | hosting-specific | Auto-configured by the hosting platform |
| DDEV Local | standard |
Override in settings.ddev.php |
| Other Local | standard |
Override in settings.local.php |
3. .gitignore
Ensure these are ignored:
web/sites/default/settings.local.php
web/sites/default/settings.ddev.php # DDEV manages thisIntegration with a Remote/Production Environment
Syncing Data
# Pull database from the remote/production environment
# (mechanism depends on hosting target — e.g. terminus for Pantheon)
# Import locally
ddev import-db --file=backup.sql.gz
# Reindex with local Solr
ddev drush search-api:clear
ddev drush search-api:indexTesting Before Deploy
# Test search functionality locally
ddev drush search-api:status
# Run searches
ddev drush search-api:search mixed_entities "test query"
# Verify via UI
ddev launch /searchDeploy Checklist
- Verify no DDEV Solr config in
settings.local.php - Ensure
settings.local.phpis in.gitignore - DDEV overrides only in
settings.ddev.php - Test that the production connector works after config import
- Clear cache after deployment
Advanced: Custom Solr Configuration
Add Custom Configset
# Create custom configset
mkdir -p .ddev/solr/configsets/mycore
# Copy base config
cp -r .ddev/solr/configsets/drupal/* .ddev/solr/configsets/mycore/
# Edit schema
vim .ddev/solr/configsets/mycore/conf/managed-schema.xml
# Restart to apply
ddev restartUse Different Solr Version
# .ddev/docker-compose.solr.yaml
services:
solr:
image: solr:8 # Change versionRelated Documentation
Lessons Learned
Settings File Isolation Incident
What Happened:
- Added Solr config to
settings.local.php - File was tracked in git and deployed to the remote/production environment
- Overwrote the production Solr connector with DDEV hostname
solr:8983 - Production search failed with "Could not resolve host: solr"
Root Cause:
// settings.local.php (WRONG - deployed to production)
$config['search_api.server.my_search_server']['backend_config']['connector'] = 'standard';
$config['search_api.server.my_search_server']['backend_config']['connector_config']['host'] = 'solr';Fix:
- Moved config to
settings.ddev.php(only loads in DDEV) - Removed
settings.local.phpfrom git - Added
settings.local.phpto.gitignore
Prevention:
- ✅ Always use
settings.ddev.phpfor DDEV service overrides - ✅ Keep
settings.local.phpgitignored and developer-specific - ✅ Test configuration sync:
ddev drush config:status - ✅ Verify settings load order in
settings.php
Key Principle
DDEV settings should ONLY exist in files that are environment-aware:
// settings.php - Check before loading
if (getenv('IS_DDEV_PROJECT') == 'true' && is_readable($ddev_settings)) {
require $ddev_settings; // ✅ Only loads in DDEV
}
if (!getenv('IS_DDEV_PROJECT') && file_exists($local_settings)) {
include $local_settings; // ✅ Only loads outside DDEV, adjust per hosting target
}This prevents DDEV configuration from breaking production environments.