Docker
Overview
Section titled “Overview”The recommended way to install Lychee is via Docker using the official image at ghcr.io/lycheeorg/lychee. The Docker image provides a complete, production-ready deployment with all dependencies included.
As of Version 7, the default Docker image uses FrankenPHP with Laravel Octane instead of the traditional nginx + PHP-FPM stack. This modern architecture delivers dramatic performance improvements:
- Boot time reduced from 40-60ms to 4-6ms per request
- 3-4x better throughput
- Significantly reduced latency
- Framework components kept in memory and reused across requests
Available Tags
Section titled “Available Tags”The following tags are available:
latest: Latest stable Lychee release using FrankenPHPv[NUMBER]: Specific stable version (e.g.,v7.0.0) using FrankenPHPedge: Current development/bleeding edge builds using FrankenPHPlegacy: Latest release using nginx + PHP-FPM (deprecated)v[NUMBER]-legacy: Specific stable version using nginx + PHP-FPM (deprecated)
Recommendation: Use latest or specific version tags for production deployments.
Quick Start
Section titled “Quick Start”Docker Compose (Recommended)
Section titled “Docker Compose (Recommended)”The recommended way to deploy Lychee is with Docker Compose. Use the official template as a starting point:
https://github.com/LycheeOrg/Lychee/blob/master/docker-compose.yaml
Start the services:
docker-compose up -dVolume Mounts
Section titled “Volume Mounts”Version 7+ (FrankenPHP)
Section titled “Version 7+ (FrankenPHP)”The current volume structure for Version 7 and later:
volumes: - ./lychee/uploads:/app/public/uploads # Photo storage - ./lychee/storage/app:/app/storage/app # Application storage - ./lychee/logs:/app/storage/logs # Log files - ./lychee/tmp:/app/storage/tmp # Temporary files - ./conf/user.css:/app/public/dist/user.css # Optional: Custom CSS - ./conf/custom.js:/app/public/dist/custom.js # Optional: Custom JavaScriptLegacy (nginx + PHP-FPM)
Section titled “Legacy (nginx + PHP-FPM)”If using the legacy image:
volumes: - ./lychee/conf:/conf # Configuration - ./lychee/uploads:/uploads # Photo storage - ./lychee/sym:/sym # Symbolic links - ./lychee/logs:/logs # Log files - ./lychee/tmp:/lychee-tmp # Temporary filesImportant: If you’re upgrading from Version 6 to Version 7, you must update your volume mounts. See the upgrade documentation for migration steps.
Environment Variables
Section titled “Environment Variables”Database Configuration
Section titled “Database Configuration”Configure your database connection:
environment: - DB_CONNECTION=mysql # mysql, pgsql, or sqlite - DB_HOST=lychee_db # Database hostname - DB_PORT=3306 # Database port - DB_DATABASE=lychee # Database name - DB_USERNAME=lychee # Database username - DB_PASSWORD=lychee # Database passwordBasic Configuration
Section titled “Basic Configuration”Common environment variables:
environment: - APP_URL=http://localhost:8000 # Your public URL - APP_DEBUG=false # Enable debug mode (development only) - APP_KEY=base64:YOUR_APP_KEY_HERE # Application encryption key (generate with `php artisan key:generate --show` or use `openssl rand -base64 32`) - TIMEZONE=UTC # Server timezone - LOG_CHANNEL=stack # Logging channelAccess Rights Configuration
Section titled “Access Rights Configuration”environment: - PUID=1000 # User ID for file permissions - PGID=1000 # Group ID for file permissions - PHP_TZ=UTC # PHP timezone #- RUN_AS_ROOT=yes # Run PHP processes as root (yes/no), disabled by default for securityAdvanced Features
Section titled “Advanced Features”Worker Mode for Horizontal Scaling (Recommended)
Section titled “Worker Mode for Horizontal Scaling (Recommended)”Version 7 introduces worker mode for processing background jobs independently. This enables horizontal scaling for improved performance with large photo uploads and processing tasks.
Basic Setup (Without Workers)
Section titled “Basic Setup (Without Workers)”The basic single-service setup handles both web requests and background jobs. However, the requests are limited to 30s by default, which may not be sufficient for large uploads or processing.
services: lychee: image: ghcr.io/lycheeorg/lychee:latest # ... volumes, environment, etc.Advanced Setup (With Workers)
Section titled “Advanced Setup (With Workers)”For better performance, run dedicated worker services:
services: lychee_api: image: ghcr.io/lycheeorg/lychee:latest container_name: lychee ports: - "8000:8000" volumes: - ./lychee/uploads:/app/public/uploads - ./lychee/storage/app:/app/storage/app - ./lychee/logs:/app/storage/logs - ./lychee/tmp:/app/storage/tmp - ./lychee/conf/.env:/app/.env:ro environment: - DB_CONNECTION=mysql - DB_HOST=lychee_db - QUEUE_CONNECTION=database # CRITICAL: Enable queue processing # ... other environment variables depends_on: - lychee_db networks: - lychee
lychee_worker: image: ghcr.io/lycheeorg/lychee:latest container_name: lychee_worker volumes: - ./lychee/uploads:/app/public/uploads - ./lychee/storage/app:/app/storage/app - ./lychee/logs:/app/storage/logs - ./lychee/tmp:/app/storage/tmp - ./lychee/conf/.env:/app/.env:ro environment: - LYCHEE_MODE=worker # CRITICAL: Run in worker mode - DB_CONNECTION=mysql - DB_HOST=lychee_db - DB_PORT=3306 - DB_DATABASE=lychee - DB_USERNAME=lychee - DB_PASSWORD=lychee - QUEUE_CONNECTION=database # CRITICAL: Must match API service # ... other environment variables depends_on: - lychee_db - lychee_api networks: - lycheeCritical Requirements for Worker Mode:
- Set
QUEUE_CONNECTION=database(orredis) in both API and worker services - Set
LYCHEE_MODE=workerin worker service only - Ensure both services share the same database and volume mounts
Scaling Workers
Section titled “Scaling Workers”Run multiple worker instances for parallel processing:
Option 1: Using replicas (Docker Swarm/Compose v3)
lychee_worker: image: ghcr.io/lycheeorg/lychee:latest deploy: replicas: 3 # Run 3 worker instances # ... rest of configurationOption 2: Multiple named services
lychee_worker_1: image: ghcr.io/lycheeorg/lychee:latest container_name: lychee_worker_1 environment: - LYCHEE_MODE=worker # ... rest of configuration
lychee_worker_2: image: ghcr.io/lycheeorg/lychee:latest container_name: lychee_worker_2 environment: - LYCHEE_MODE=worker # ... rest of configurationDocker Secrets
Section titled “Docker Secrets”For sensitive information, use Docker secrets instead of environment variables:
services: lychee: image: ghcr.io/lycheeorg/lychee:latest environment: - DB_PASSWORD_FILE=/run/secrets/db_password - APP_KEY_FILE=/run/secrets/app_key # - REDIS_PASSWORD_FILE=/run/secrets/redis_password # - MAIL_PASSWORD_FILE=/run/secrets/mail_password - ADMIN_PASSWORD_FILE=/run/secrets/admin_password secrets: - db_password - app_key # - redis_password # - mail_password - admin_password
secrets: app_key: file: ./secrets/app_key.txt db_password: file: ./secrets/db_password.txt # redis_password: # file: ./secrets/redis_password.txt # mail_password: # file: ./secrets/mail_password.txt admin_password: file: ./secrets/admin_password.txtSupported _FILE variables:
APP_KEY_FILEDB_PASSWORD_FILE
ADMIN_PASSWORD_FILE
Configuration Management
Section titled “Configuration Management”Environment File (.env)
Section titled “Environment File (.env)”Important: Due to the FrankenPHP architecture, the .env file is read once at container startup and kept in memory. Any changes to the .env file require a container restart to take effect:
docker-compose restart lycheeConfiguration Priority
Section titled “Configuration Priority”Configuration values are applied in this order (highest to lowest priority):
- Environment variables passed via
docker-compose.ymlordocker run - Values in mounted
.envfile - Default values from
.env.example
Note: When restarting containers, environment variables from docker-compose will override values in the mounted .env file. Modify configuration in your docker-compose file rather than editing files inside the container.
Upgrading
Section titled “Upgrading”From Version 6 to Version 7
Section titled “From Version 6 to Version 7”Version 7 introduces breaking changes to the Docker setup. You must update your docker-compose configuration when upgrading from v6 to v7. Simply changing the image tag will not work.
See the detailed upgrade documentation for complete migration instructions, including:
- Volume mount changes
- Service architecture updates
- Environment variable changes
- Worker mode configuration
General Upgrade Process
Section titled “General Upgrade Process”For routine updates:
Backup your data:
Terminal window # Backup databasedocker exec lychee_db mysqldump -u lychee -p lychee > lychee_backup.sql# Backup uploadscp -r ./lychee ./lychee_backupPull the latest image:
Terminal window docker-compose pullRestart services:
Terminal window docker-compose downdocker-compose up -dRun migrations:
Terminal window docker exec lychee php artisan migrate
Troubleshooting
Section titled “Troubleshooting”Check Service Status
Section titled “Check Service Status”docker-compose psView Logs
Section titled “View Logs”# All servicesdocker-compose logs -f
# Specific servicedocker-compose logs -f lychee
# Worker logsdocker-compose logs -f lychee_workerCommon Issues
Section titled “Common Issues”Workers not processing jobs:
- Verify
QUEUE_CONNECTION=databaseis set in both API and worker services - Verify
LYCHEE_MODE=workeris set in worker service - Check worker logs:
docker-compose logs -f lychee_worker
Upload issues:
- Verify volume mounts point to correct paths
- Check file permissions on host directories
- Ensure uploads directory exists and is writable
Performance issues:
- Consider adding worker services for background processing
- Verify FrankenPHP is running (check logs for FrankenPHP, not nginx)
- Ensure
QUEUE_CONNECTIONis set for async job processing
Database connection errors:
- Ensure database service name matches
DB_HOSTvalue - Verify database credentials are correct
- Check database service is healthy:
docker-compose ps lychee_db
Configuration changes not applying:
- Remember to restart container after
.envchanges:docker-compose restart lychee - Verify environment variables in docker-compose.yml take precedence over
.envfile
Getting Help
Section titled “Getting Help”For additional support:
Performance Optimization
Section titled “Performance Optimization”Recommended Setup for Large Galleries
Section titled “Recommended Setup for Large Galleries”For galleries with thousands of photos:
- Use worker services for background processing
- Scale workers based on your hardware (2-4 workers recommended)
- Use Redis for queue backend instead of database:environment:- QUEUE_CONNECTION=redis- REDIS_HOST=redis- REDIS_PORT=6379
- Allocate sufficient resources in docker-compose:deploy:resources:limits:memory: 2Greservations:memory: 1G
FrankenPHP Benefits
Section titled “FrankenPHP Benefits”The FrankenPHP-powered Version 7 image provides significant performance improvements over Version 6:
- Faster boot times: 4-6ms vs 40-60ms per request
- Better throughput: 3-4x improvement in requests per second
- Lower latency: Reduced response times across all operations
- Memory efficiency: Framework components kept in memory and reused
These improvements are automatic when using Version 7 - no additional configuration required.
Security Considerations
Section titled “Security Considerations”- Use Docker secrets for sensitive credentials in production
- Mount
.envas read-only (:ro) to prevent modifications - Use strong passwords for database and admin accounts
- Keep images updated to receive security patches
- Run behind a reverse proxy (nginx, Traefik, Caddy) with TLS
- Restrict network access using Docker networks
- Use specific version tags instead of
latestin production for reproducible deployments
