Lychee logo

Lychee

Self-hosted photo and video management system for uploading, organizing, and sharing your media

Alternative to: google photos, apple photos, amazon photos, flickr


Lychee is a free, open-source photo-management tool you run on your own server or web space. It lets you upload, organize, and share photos and videos right from your browser, with support for albums, password-protected sharing links, and full EXIF/IPTC metadata. Built for privacy, it keeps your library entirely under your control with no storage limits or lossy compression.

Lychee Docker Compose example

Self-host Lychee on your own server, homelab, or VPS starting from this Docker Compose example. It runs Lychee in Docker containers using the official lycheeorg/lychee:latest, mariadb:11, redis:alpine images, with persistent volumes and automatic restarts preconfigured. Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.

services:
  lychee:
    image: lycheeorg/lychee:latest
    depends_on:
      - lychee_db
    volumes:
      - conf:/conf
      - uploads:/uploads
      - sym:/sym
      - logs:/logs
      - tmp:/lychee-tmp
    restart: unless-stopped
    environment:
      # User/group IDs the container runs as. Match your host user to keep uploaded
      # files owned sensibly on the mounted volumes.
      PUID: "1000"
      PGID: "1000"
      # PHP timezone.
      PHP_TZ: "UTC"
      # Application timezone.
      TIMEZONE: "UTC"
      # Full public URL where Lychee is served.
      APP_URL: "http://localhost"
      # Database connection. Host matches the lychee_db service name below.
      DB_CONNECTION: "mysql"
      DB_HOST: "lychee_db"
      DB_PORT: "3306"
      DB_DATABASE: "lychee"
      DB_USERNAME: "lychee"
      # Password for the Lychee database user (only reachable inside the compose network).
      DB_PASSWORD: "lychee"
      # Seconds to wait for the database to come up before the app boots.
      STARTUP_DELAY: "30"
      # Cache backend. "redis" uses the bundled lychee_cache service below.
      CACHE_DRIVER: "redis"
      REDIS_HOST: "lychee_cache"
      REDIS_PORT: "6379"
      # Password for Redis. Empty since the cache is internal to the compose network.
      REDIS_PASSWORD: ""

  lychee_db:
    image: mariadb:11
    volumes:
      - mysql:/var/lib/mysql
    restart: unless-stopped
    environment:
      # Root password for MariaDB (only reachable inside the compose network).
      MARIADB_ROOT_PASSWORD: "rootpassword"
      MARIADB_DATABASE: "lychee"
      MARIADB_USER: "lychee"
      # Must match DB_PASSWORD on the app service above.
      MARIADB_PASSWORD: "lychee"
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 20s
      start_period: 30s
      timeout: 10s
      retries: 5

  lychee_cache:
    image: redis:alpine
    volumes:
      - cache:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping || exit 1"]
      interval: 20s
      timeout: 5s
      retries: 5

volumes:
  conf:
  uploads:
  sym:
  logs:
  tmp:
  mysql:
  cache:

Prefer a managed setup? WinterFlow installs, configures, and updates Lychee for you using this same Docker Compose configuration.