Skip to content

Manual Installation

This guide covers installing Lychee without Docker. For most users, the Docker installation is simpler and recommended.

  • A web server such as Apache or nginx
  • A database — using one of the following:
    • MySQL (version > 5.7.8) / MariaDB (version > 10.2)
    • PostgreSQL (version > 9.2)
    • SQLite3
  • PHP >= 8.4 with these extensions:
    • bcmath, ctype, dom, exif, fileinfo, filter, gd, json, libxml, ldap (optional), mbstring, openssl, pcre, PDO, Phar, SimpleXML, tokenizer, xml, xmlwriter
    • imagick (optional — better thumbnails)
    • PhpRedis (optional — to use Redis)
  • A database-specific PHP extension:
    • SQLite3 for SQLite databases
    • MySQLi (or PDO_MySQL) for MySQL / MariaDB
    • PgSql (or PDO_PGSQL) for PostgreSQL
  • On FreeBSD, you may also need: session, zlib
  • Optional CLI tools:
    • Exiftool (better EXIF metadata handling)
    • FFmpeg (video thumbnails)

While Lychee works on 32-bit systems, a 64-bit OS is strongly recommended.

  1. Download the latest release zip from the Releases page.
  2. Extract it to your web directory (e.g. /var/www/html).

Building from source requires Composer and npm.

Terminal window
git clone https://www.github.com/LycheeOrg/Lychee /var/www/html/Lychee
cd /var/www/html/Lychee
composer install --no-dev
npm install
npm run build

Three OS users may be involved:

  • Web user — the user running the web server daemon (e.g. www-data, apache, nginx)
  • PHP user — the user running PHP-FPM/CGI (often the same as the web user)
  • CLI user — your shell user, relevant if importing photos via CLI

Required permissions:

  • All Lychee files must be readable by the web/PHP user.
  • storage/ and bootstrap/cache/ must be writable by the web/PHP user.
  • public/uploads and public/sym must be writable by the web/PHP user (and the CLI user if importing via CLI).
  • public/dist must be writable if you want to customize CSS via the web frontend.

For CLI imports, the recommended approach is to add all users to a shared group, set group ownership, enable group write, and set the sgid bit on directories so new files inherit the group.

The main directory should contain a .env file. Composer typically creates this from .env.example during installation. If it doesn’t exist, copy it manually:

Terminal window
cp .env.example .env

The APP_KEY setting must be set. If Composer didn’t generate one:

Terminal window
php artisan key:generate

Set APP_URL in .env to the external URL by which the public/ directory is accessible. This must match your web server configuration.

The default .env provides usable settings out of the box. You may want to configure cache, database, and session settings — see the Configuration page.

Configure your web server to serve the public/ directory. Do not expose the top-level Lychee directory — this would allow public access to the .env file and application code.

It is strongly recommended to serve Lychee over TLS. Consider Let’s Encrypt for certificates and Mozilla’s SSL Configuration Generator for server configuration.

Enable mod_rewrite so the included public/.htaccess is honored. Also check the Apache upgrade instructions for required permissions in your site configuration.

If the default .htaccess does not work, try this alternative:

Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

A sample nginx server block (without TLS):

server {
listen 80;
server_name <mydomain>.<tld>;
root /var/www/Lychee/public/;
index index.php;
# If the request is not for a valid file, send to bootstrap
if (!-e $request_filename)
{
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
# Serve /index.php through PHP
location = /index.php {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "post_max_size=100M
max_execution_time=200
upload_max_filesize=30M
memory_limit=300M";
fastcgi_param PATH /usr/local/bin:/usr/bin:/bin;
include fastcgi_params;
}
# Deny access to other .php files
location ~ [^/]\.php(/|$) {
return 403;
}
error_log /var/log/nginx/lychee.error.log;
access_log /var/log/nginx/lychee.access.log;
}

For subdirectory hosting, see the FAQ.