Upgrading to version 7
Major Changes in Version 7
Section titled “Major Changes in Version 7”Version 7 marks a fundamental shift in Lychee’s Docker architecture:
- FrankenPHP replaces nginx + PHP-FPM: The application now runs on FrankenPHP with Laravel Octane for dramatically improved performance
- Simplified volume mounts: Individual directory mounts have been consolidated into cleaner volume structures
- Optional worker service: Background job processing can now be scaled independently
- New environment variables: Worker mode configuration requires specific settings
Do note that this change also has consequences in the way Lychee reads your .env file. Updating values in the .env file will now require a container restart to take effect.
Port change
Section titled “Port change”Version 7 uses FrankenPHP which listens on port 8000 instead of the previous 80 used by nginx. Make sure to update your port mappings accordingly in your docker-compose.yml.
Volume Mount Changes
Section titled “Volume Mount Changes”In order to avoid you running into issues while booting version 7, we are blocking the startup of the container if the old volume structure is detected.
Version 6 Volume Structure (OLD)
Section titled “Version 6 Volume Structure (OLD)”volumes: - ./lychee/conf:/conf - ./lychee/uploads:/uploads - ./lychee/sym:/sym - ./lychee/logs:/logs - ./lychee/tmp:/lychee-tmpVersion 7 Volume Structure (NEW)
Section titled “Version 7 Volume Structure (NEW)”volumes: - ./lychee/uploads:/app/public/uploads - ./lychee/logs:/app/storage/logs - ./lychee/tmp:/app/storage/tmp # so that uploads are not filling up the memory of the container - ./lychee/storage/app:/app/storage/app # OPTIONAL: for persistent storage of app data - ./conf/user.css:/app/public/dist/user.css # OPTIONAL - ./conf/custom.js:/app/public/dist/custom.js # OPTIONALThe /sym volume has been removed as Lychee no longer uses symbolic links for storage. This was a security feature that originated from version 4, but is no longer necessary as the functionality has been removed.
Important: With multiple volumes under /app/storage, you may think you could simplify the configuration by specifying one single volume for /app/storage instead. This is incorrect. Doing so will make the app exit with the error “The /app/bootstrap/cache directory must be present and writable.”
Service Architecture Changes
Section titled “Service Architecture Changes”Version 7 introduces a multi-service architecture with an optional worker service for background job processing.
Basic Setup (Single Service)
Section titled “Basic Setup (Single Service)”For basic installations without background workers:
services: lychee_api: image: ghcr.io/lycheeorg/lychee:edge container_name: lychee ports: - "${APP_PORT:-8000}:8000" volumes: - ./lychee/uploads:/app/public/uploads - ./lychee/logs:/app/storage/logs - ./lychee/tmp:/app/storage/tmp environment: - DB_CONNECTION=mysql - DB_HOST=lychee_db - DB_PORT=3306 - DB_DATABASE=lychee - DB_USERNAME=lychee - DB_PASSWORD=your_password # ... other environment variables depends_on: - lychee_db networks: - lycheeAdvanced Setup (With Workers)
Section titled “Advanced Setup (With Workers)”For better performance with background job processing:
services: lychee_api: image: ghcr.io/lycheeorg/lychee:edge container_name: lychee ports: - "${APP_PORT:-8000}:8000" volumes: - ./lychee/uploads:/app/public/uploads - ./lychee/logs:/app/storage/logs - ./lychee/tmp:/app/storage/tmp environment: - DB_CONNECTION=mysql - DB_HOST=lychee_db - QUEUE_CONNECTION=database # CRITICAL for worker mode # ... other environment variables depends_on: - lychee_db networks: - lychee
lychee_worker: image: ghcr.io/lycheeorg/lychee:edge container_name: lychee_worker volumes: - ./lychee/uploads:/app/public/uploads - ./lychee/logs:/app/storage/logs - ./lychee/tmp:/app/storage/tmp environment: - LYCHEE_MODE=worker # CRITICAL: Tells container to run in worker mode - DB_CONNECTION=mysql - DB_HOST=lychee_db - DB_PORT=3306 - DB_DATABASE=lychee - DB_USERNAME=lychee - DB_PASSWORD=your_password - QUEUE_CONNECTION=database # CRITICAL: Must match API service # ... other environment variables depends_on: - lychee_db - lychee_api networks: - lycheeWorker Service Benefits
Section titled “Worker Service Benefits”The worker service provides several advantages:
- Parallel Processing: Scale workers independently by running multiple instances
- Better Performance: Offload heavy tasks (photo processing, imports) from the main API
- Resource Management: Allocate different resources to API and workers
Scaling Workers
Section titled “Scaling Workers”You can run multiple worker instances for parallel processing:
lychee_worker: image: ghcr.io/lycheeorg/lychee:edge deploy: replicas: 3 # Run 3 worker instances # ... rest of configurationOr manually with different container names:
lychee_worker_1: image: ghcr.io/lycheeorg/lychee:edge container_name: lychee_worker_1 environment: - LYCHEE_MODE=worker # ... rest of configuration
lychee_worker_2: image: ghcr.io/lycheeorg/lychee:edge container_name: lychee_worker_2 environment: - LYCHEE_MODE=worker # ... rest of configurationMigration Steps
Section titled “Migration Steps”Follow these steps to migrate from v6 to v7:
1. Backup Everything
Section titled “1. Backup Everything”# Backup your databasedocker exec lychee_db mysqldump -u lychee -p lychee > lychee_backup.sql
# Backup your uploads and configurationcp -r ./lychee ./lychee_backup2. Stop Your Current v6 Services
Section titled “2. Stop Your Current v6 Services”docker-compose down3. Update Your docker-compose.yml
Section titled “3. Update Your docker-compose.yml”Replace your v6 docker-compose.yml with the v7 configuration. You can find the complete example at: https://github.com/LycheeOrg/Lychee/blob/master/docker-compose.yaml
4. Reorganize Your Volume Data (if needed)
Section titled “4. Reorganize Your Volume Data (if needed)”If your current directory structure doesn’t match the new volume mounts, reorganize:
# The uploads directory structure should remain compatible# Ensure your uploads are in ./lychee/uploads/5. Update Environment Variables
Section titled “5. Update Environment Variables”Key changes to your environment configuration:
- If using workers: Add
QUEUE_CONNECTION=databaseorQUEUE_CONNECTION=redis - If using workers: Add
LYCHEE_MODE=workerto worker service only - Review other environment variables for any deprecated options
6. Start v7 Services
Section titled “6. Start v7 Services”docker-compose up -d7. Verify Installation
Section titled “7. Verify Installation”Check that all services are running:
docker-compose psCheck logs for errors:
docker-compose logs -f lychee8. Fix the thumbnails
Section titled “8. Fix the thumbnails”You will notice that after the upgrade, thumbnails are missing. You can regenerate them by running:
docker exec -it lychee php artisan lychee:recompute-album-sizesdocker exec -it lychee php artisan lychee:recompute-album-statsor by logging into the web interface and going to Settings ⇒ Maintenance ⇒ Album Precomputed Fields.
Troubleshooting
Section titled “Troubleshooting”Container keeps restarting
- Verify that you have APP_KEY properly set in your
.envordocker-compose.ymlif that is not the case you can runecho "APP_KEY=base64:$(openssl rand -base64 32)"to create a new one.
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 the correct paths
- Check file permissions on host directories
- Ensure uploads directory:
./lychee/uploadsexists and is writable
Performance issues
- Consider adding worker services for background processing
- Check FrankenPHP is running (should see FrankenPHP in logs, not nginx)
- Verify
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
For more help, visit our GitHub Discussions or Discord server.
Migrating from Traditional Installation to Docker Compose
Section titled “Migrating from Traditional Installation to Docker Compose”This guide helps you migrate an existing Lychee installation from a traditional setup (e.g., /var/www/html/Lychee) to a Docker Compose deployment.
Prerequisites
Section titled “Prerequisites”Before starting the migration, make sure you have docker compose installed. You can follow the instructions here.
Migration Steps
Section titled “Migration Steps”1. Backup Your Current Installation
Section titled “1. Backup Your Current Installation”# Backup the databasemysqldump -u your_db_user -p your_db_name > ~/lychee_db_backup.sql
# Backup the entire Lychee directorycp -r /var/www/html/Lychee ~/lychee_backup
# Backup your .env file specificallycp /var/www/html/Lychee/.env ~/lychee_env_backup2. Create Docker Compose Directory Structure
Section titled “2. Create Docker Compose Directory Structure”Create a directory for your Docker Compose setup:
mkdir -p ~/lychee-dockercd ~/lychee-docker
# Create directories for volume mountsmkdir -p lychee/uploadsmkdir -p lychee/storage/appmkdir -p lychee/logsmkdir -p lychee/tmpmkdir -p lychee/conf3. Copy Your Data
Section titled “3. Copy Your Data”Move your existing uploads and configuration:
# Copy uploads (this may take time depending on your photo library size)sudo cp -r /var/www/html/Lychee/public/uploads/* ~/lychee-docker/lychee/uploads/
# Copy your .env configurationsudo cp /var/www/html/Lychee/.env ~/lychee-docker/lychee/conf/.env
# If you have custom CSS or JavaScriptsudo cp /var/www/html/Lychee/public/dist/user.css ~/lychee-docker/conf/user.css 2>/dev/null || truesudo cp /var/www/html/Lychee/public/dist/custom.js ~/lychee-docker/conf/custom.js 2>/dev/null || true
# Set appropriate permissionssudo chown -R $USER:$USER ~/lychee-docker/lycheechmod -R 755 ~/lychee-docker/lychee4. Create docker-compose.yml
Section titled “4. Create docker-compose.yml”Create a docker-compose.yml file in ~/lychee-docker:
services: lychee_db: image: mariadb:11 container_name: lychee_db environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=lychee - MYSQL_USER=lychee - MYSQL_PASSWORD=lychee_password volumes: - ./lychee/lychee_db:/var/lib/mysql networks: - lychee restart: unless-stopped
lychee_api: image: ghcr.io/lycheeorg/lychee:latest container_name: lychee ports: - "8000:8000" # Change the first part XXXX:8000 this to your preferred port env_file: - ./lychee/conf/.env 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 # Optional: Uncomment if you have custom CSS/JS # - ./conf/user.css:/app/public/dist/user.css # - ./conf/custom.js:/app/public/dist/custom.js environment: - APP_KEY=base64:YOUR_APP_KEY_HERE # Generate it with `openssl rand -base64 32` - DB_CONNECTION=mysql - DB_HOST=lychee_db - DB_PORT=3306 - DB_DATABASE=lychee - DB_USERNAME=lychee - DB_PASSWORD=lychee_password depends_on: - lychee_db networks: - lychee restart: unless-stopped
networks: lychee:6. Update Your .env File
Section titled “6. Update Your .env File”Edit ~/lychee-docker/lychee/conf/.env to update database connection settings:
# Update these values to match your docker-compose.ymlDB_CONNECTION=mysqlDB_HOST=lychee_dbDB_PORT=3306DB_DATABASE=lycheeDB_USERNAME=lycheeDB_PASSWORD=lychee_password
# Set the application URLAPP_URL=http://your-domain.com:8000 # Update with your domain/IP7. Import Your Database
Section titled “7. Import Your Database”Start the database container and import your data:
cd ~/lychee-docker
# Start only the database servicedocker-compose up -d lychee_db
# Wait for the database to be ready (about 10-20 seconds)sleep 20
# Import your database backupdocker exec -i lychee_db mysql -u lychee -plychee_password lychee < ~/lychee_db_backup.sql8. Start Lychee
Section titled “8. Start Lychee”# Start all servicesdocker-compose up -d
# Check logs to ensure everything started correctlydocker-compose logs -f lycheePress Ctrl+C to exit log viewing.
9. Configure Reverse Proxy (Optional)
Section titled “9. Configure Reverse Proxy (Optional)”If you’re using a reverse proxy (recommended for production), configure it to forward to the Docker container.
Nginx Example:
server { listen 80; server_name your-domain.com;
location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
# For large photo uploads client_max_body_size 100M; }}Apache Example:
<VirtualHost *:80> ServerName your-domain.com
ProxyPreserveHost On ProxyPass / http://localhost:8000/ ProxyPassReverse / http://localhost:8000/
# For large photo uploads LimitRequestBody 104857600</VirtualHost>Enable required modules and restart:
# For Apachesudo a2enmod proxy proxy_httpsudo systemctl restart apache2
# For Nginxsudo systemctl restart nginx10. Verify Migration
Section titled “10. Verify Migration”- Access Lychee at
http://your-domain.com(orhttp://your-domain.com:8000if not using reverse proxy) - Log in with your existing credentials
- Verify your photos and albums are displayed correctly
- Check Settings ⇒ Diagnostics to ensure everything is working
11. Optional: Add Worker Service
Section titled “11. Optional: Add Worker Service”For better performance with large photo libraries, consider adding a worker service:
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 - DB_CONNECTION=mysql - DB_HOST=lychee_db - DB_PORT=3306 - DB_DATABASE=lychee - DB_USERNAME=lychee - DB_PASSWORD=lychee_password - QUEUE_CONNECTION=database depends_on: - lychee_db - lychee_api networks: - lychee restart: unless-stoppedAlso add QUEUE_CONNECTION=database to the lychee_api service environment variables, then restart:
docker-compose up -dPost-Migration Cleanup
Section titled “Post-Migration Cleanup”After confirming everything works correctly:
# Disable the old web server from starting on bootsudo systemctl disable apache2 # or nginx
# You can remove the old installation (keep the backup!)# sudo rm -rf /var/www/html/Lychee # Only after thorough testing!Troubleshooting
Section titled “Troubleshooting”Cannot access Lychee
- Check if containers are running:
docker ps - Check logs:
docker logs lychee - Verify port 8000 is not blocked by firewall
- If using reverse proxy, check proxy configuration
Photos not showing
- Verify uploads were copied correctly:
ls -la ~/lychee-docker/lychee/uploads/ - Check volume mount permissions
- Verify file paths in database match new structure
Database connection errors
- Confirm database container is running:
docker ps lychee_db - Verify credentials in
.envmatchdocker-compose.yml - Check database logs:
docker logs lychee_db
Permission errors
- Fix ownership:
sudo chown -R 33:33 ~/lychee-docker/lychee/(33 is www-data UID/GID but can also be 82 for alpine) - Or make directories writable:
chmod -R 777 ~/lychee-docker/lychee/(less secure)
For additional help, visit our GitHub Discussions or Discord server.
Upgrading from Lychee v3 to v4
Section titled “Upgrading from Lychee v3 to v4”Checking requirements
Section titled “Checking requirements”Check that the server satisfies the requirements. In particular pay attention the PHP extensions. You can display installed PHP extensions using phpinfo().
Preparing the files
Section titled “Preparing the files”Assuming the following tree:
/var/ |- www/ |- html/ |- Lychee/ |- <you are here>Rename Lychee into Lychee-v3:
mv Lychee Lychee-v3Install Lychee files by either uploading the content of the released zip or cloning the repository:
git clone https://github.com/LycheeOrg/Lychee LycheeMove the pictures from the version 3 to the newly created installation:
mv Lychee-v3/uploads/big/* Lychee/public/uploads/big/mv Lychee-v3/uploads/medium/* Lychee/public/uploads/medium/mv Lychee-v3/uploads/small/* Lychee/public/uploads/small/mv Lychee-v3/uploads/thumb/* Lychee/public/uploads/thumb/Preparing the server
Section titled “Preparing the server”- In the version 3, this was the root
.of Lychee. - In the version 4, this is the
publicdirectory inside Lychee.
Using Apache
Section titled “Using Apache”Make sure you have the module rewrite available and enabled: a2enmod rewrite.
Modify your /etc/apache2/apache2.conf to allow .htaccess to set up the rewrite rules:
<Directory /var/www/html/Lychee> Options Indexes FollowSymLinks AllowOverride All Require all granted</Directory>Modify or create example.com.conf in /etc/apache2/sites-available/ to point out the served directory:
<VirtualHost *:80> ServerName example.com
DocumentRoot /var/www/html/Lychee/public
ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined</VirtualHost>Enable the site:
a2ensite `example.com.conf`Restart apache2:
systemctl restart apache2Using Nginx
Section titled “Using Nginx”If you are using Nginx, an example configuration can be found here.
Run the migrations
Section titled “Run the migrations”Make sure you have DB_OLD_LYCHEE_PREFIX set in your .env to correspond the table prefix of your old database, then run php artisan migrate.
