Domain Configuration: .orb.local Setup
Domain Configuration: .orb.local Setup
Project: llm-platform Created: 2025-11-24 Status: Production
Overview
This guide documents the .orb.local domain configuration for local development using DDEV and OrbStack. The .orb.local TLD provides automatic DNS resolution without modifying /etc/hosts, simplifying multi-domain local development.
Architecture
OrbStack DNS
(*.orb.local Container IP)
DDEV Router (Traefik)
Routes requests to correct container
Web DB MailPit
:80 :3306 :8025
:443
Configuration Sources
Environment Variables
All domain and service configuration is managed through environment variables:
Primary Config: $PROJECT_ROOT/.env or .env.local
# Domain configuration - NEVER hardcode these! DDEV_HOSTNAME=llm-platform.ddev.site DDEV_PRIMARY_URL=https://llm-platform.ddev.site ORBSTACK_BASE_DOMAIN=orb.local # Service URLs - Read from Drupal config API_BASE_URL=api.${ORBSTACK_BASE_DOMAIN} MODELS_BASE_URL=models.${ORBSTACK_BASE_DOMAIN} MCP_BASE_URL=mcp.${ORBSTACK_BASE_DOMAIN} KAGENT_BASE_URL=kagent.${ORBSTACK_BASE_DOMAIN} # Ports are environment-specific HTTP_PORT=80 HTTPS_PORT=443
Drupal Configuration
DO NOT hardcode paths or domains! All service URLs and paths are configurable in Drupal admin:
-
Kagent Configuration:
/admin/config/ai/agents-kagent- Dashboard URL (editable)
- API endpoints (editable)
- Service ports (configurable)
-
MCP Configuration:
/admin/config/ai/mcp- Tool server URLs (editable)
- Port configuration (configurable)
-
API Configuration:
/admin/config/services/api-normalizer- Gateway endpoints (editable)
- Service discovery (dynamic)
DDEV Config Files
Location: $PROJECT_ROOT/.ddev/config.yaml
Active hostnames are read from DDEV config - check the actual file for current values:
additional_hostnames: # List is dynamic - check actual file # DO NOT hardcode domain list here
Location: $PROJECT_ROOT/.ddev/docker-compose.orbstack.yaml
OrbStack domain labels are managed per environment:
services: web: labels: # Domain list is environment-specific # Check actual file for current configuration dev.orbstack.domains: ${ORBSTACK_DOMAIN_LIST}
Adding a New Domain
Step 1: Define in Environment Variables
Edit $PROJECT_ROOT/.env.local:
# Add your service URL to environment config YOUR_SERVICE_BASE_URL=your-service.${ORBSTACK_BASE_DOMAIN} YOUR_SERVICE_PORT=${HTTP_PORT} # Use env var, don't hardcode
Step 2: Add to DDEV Config
Edit $PROJECT_ROOT/.ddev/config.yaml:
additional_hostnames: # Reference from your .env or use variable - your-service # Without domain suffix
Step 3: Add to OrbStack Domains (if using OrbStack)
Edit $PROJECT_ROOT/.ddev/docker-compose.orbstack.yaml:
services: web: labels: # NEVER hardcode - read from environment or use variable substitution dev.orbstack.domains: ${ORBSTACK_DOMAIN_LIST}
Step 4: Configure in Drupal Admin (for Drupal services)
- Go to Drupal admin configuration
- Find your service config page (e.g.,
/admin/config/services/your-service) - Set service URL using the configuration form
- DO NOT hardcode URLs in code - use Drupal config entities
Step 5: Restart DDEV
cd $LLM_ROOT/llm-platform ddev restart
Step 6: Verify Resolution
# Read domain from environment source $PROJECT_ROOT/.env.local # Test DNS resolution (using env var) ping -c 1 ${YOUR_SERVICE_BASE_URL} # Test HTTP connectivity (using env var) curl -I http://${YOUR_SERVICE_BASE_URL} # Test HTTPS connectivity (using env var) curl -I https://${YOUR_SERVICE_BASE_URL}
Port Configuration
Environment Variables
NEVER hardcode ports! All ports are defined in environment variables:
# In .env or .env.local HTTP_PORT=80 HTTPS_PORT=443 MAILPIT_HTTP_PORT=8025 MAILPIT_HTTPS_PORT=8026 XHGUI_HTTPS_PORT=8142 XHGUI_HTTP_PORT=8143 # Use in your code/config SERVICE_URL=http://${SERVICE_DOMAIN}:${HTTP_PORT}
Drupal Service Configuration
All service ports should be configurable in Drupal admin:
-
Service Base Config:
/admin/config/services- Each service should have its own config form
- Port fields should be editable (not hardcoded)
- URLs should be built from config, not constants
-
Using Config in Code:
// CORRECT - Read from config $config = \Drupal::config('your_module.settings'); $port = $config->get('service_port'); $domain = $config->get('service_domain'); $url = "https://{$domain}:{$port}"; // WRONG - Never do this! $url = "https://kagent.orb.local:443"; // HARDCODED!
Port Discovery
Ports should be discovered dynamically:
- Read from
.envfiles - Query Drupal config entities
- Use service discovery when available
- Check DDEV environment variables (
$DDEV_ROUTER_HTTP_PORT, etc.)
Troubleshooting
Domain Not Resolving
Symptom: curl: (6) Could not resolve host: yourdomain.orb.local
Solutions:
- Verify OrbStack is running:
docker ps - Check OrbStack DNS is active:
ping -c 1 llm.orb.local - Restart OrbStack networking:
ddev restart
Wrong Service Responding
Symptom: Domain shows MailPit instead of expected service
Check:
- Verify port in URL (should be port 80/443 for web, not 8025)
- Clear browser cache (Cmd+Shift+R)
- Check Developer Tools Network tab for redirects
- Verify OrbStack label configuration:
docker inspect ddev-llm-platform-web --format '{{json .Config.Labels}}' | jq -r '."dev.orbstack.domains"'
HTTPS Certificate Warnings
Symptom: Browser shows "Your connection is not private"
Solution: This is expected for self-signed DDEV certificates. Click "Advanced" "Proceed to site" (Chrome) or "Accept the Risk and Continue" (Firefox).
One-time fix:
# Import DDEV CA certificate ddev trustca
500 Internal Server Error
Symptom: Domain resolves but shows Drupal error
Not a domain issue - This indicates Drupal module/configuration errors. Check:
- Drupal logs:
ddev drush watchdog-show - PHP error logs:
ddev logs - Module status:
ddev drush pm:list --status=enabled
Technical Details
How OrbStack DNS Works
- OrbStack provides automatic DNS resolution for
*.orb.local - All
.orb.localdomains resolve to the OrbStack bridge network IP (typically192.168.138.x) - The
dev.orbstack.domainslabel tells OrbStack which domains map to which container ports - No
/etc/hostsmodification needed
Comparison: OrbStack vs DDEV Domains
| Feature | .orb.local (OrbStack) | .ddev.site (DDEV Router) |
|---|---|---|
| DNS Resolution | Automatic via OrbStack | DNS lookup via wildcard |
| Port Support | 80, 443 only | All DDEV service ports |
| Configuration | Docker labels | DDEV config + Traefik |
| MailPit Access | Not supported | Via :8025/:8026 |
| Speed | Slightly faster | Minimal difference |
Example: kagent.orb.local Setup
Changes Made (2025-11-24)
File: .ddev/config.yaml:18
- mlflow + - kagent
File: .ddev/docker-compose.orbstack.yaml:4
- dev.orbstack.domains: llm.orb.local:80,api.orb.local:80,models.orb.local:80,mcp.orb.local:80 + dev.orbstack.domains: llm.orb.local:80,api.orb.local:80,models.orb.local:80,mcp.orb.local:80,kagent.orb.local:80
Verification
# NEVER hardcode domains - use environment variables source $PROJECT_ROOT/.env.local # DNS resolution (using env var) $ ping -c 1 ${KAGENT_BASE_URL} # HTTP connectivity (using env var) $ curl -I https://${KAGENT_BASE_URL}
Kagent Routes Configuration
All routes are defined in Drupal routing config, not hardcoded:
File: web/modules/custom/ai_agents_kagent/ai_agents_kagent.routing.yml
Routes are discovered from:
- Drupal routing system (
.routing.ymlfiles) - Drupal config entities (
/admin/config/ai/agents-kagent) - Never hardcoded in documentation!
To view available routes:
ddev drush route:list | grep kagent
Related Documentation
- DDEV Documentation: https://docs.ddev.com/
- OrbStack Domains: https://docs.orbstack.dev/docker/domains
- Traefik Configuration:
$LLM_ROOT/llm-platform/.ddev/traefik/config/llm-platform.yaml - Project Structure: See Project Structure Standard
- Drupal Development: See Drupal Development
Maintenance
Monthly Tasks
- Review active domains and remove unused entries
- Update this documentation when domains change
- Verify all domains resolve correctly
When Adding New Services
- Add domain following steps above
- Update this wiki page with new domain
- Document service-specific routes
- Add to monitoring/health checks if applicable
Last Updated: 2025-11-24 Maintained By: DevOps / Infrastructure Team Questions?: https://gitlab.com/blueflyio/documentation/-/issues