When using Docker, all application services run in isolated containers, so you must explicitly mount the host folders you want to use. Please note that PhotoPrism and MariaDB cannot see folders that have not been mounted. This is an important security feature.

The following paths are used on the host if you are running Linux and follow our recommendation to install PhotoPrism in /opt/photoprism. In the Docker container, the /opt prefix is omitted so that, for example, /opt/photoprism/originals is mounted to /photoprism/originals:

Originals Folder

The originals folder contains your original photo and video files. By default, it is located at /opt/photoprism/originals on the host server and at /photoprism/originals in the app container. If you are using Docker Compose, you can use ~ as a shortcut for the home directory.

volumes:
  - "./originals:/photoprism/originals"    # original media files (photos and videos)

You can mount any folder accessible from the host, including network shares. Additional directories can also be mounted as subfolders of /photoprism/originals (depending on overlay file system support):

volumes:
  - "./originals:/photoprism/originals"
  - "/mnt/photos:/photoprism/originals/media"

On Windows, prefix the host path with the drive letter and use / instead of \ as separator:

volumes:
  - "D:/Originals:/photoprism/originals"

If read-only mode is enabled, all features that require write permission to the originals folder are disabled, e.g. WebDAV, uploading and deleting files. Set PHOTOPRISM_READONLY to "true" in docker-compose.yml for this. You can mount a folder with the :ro flag to make Docker block write operations as well.

Storage Folder

SQLite, config, cache, thumbnail, and sidecar files are saved in the storage folder, which by default is located at /opt/photoprism/storage on the host server and at /photoprism/storage in the app container.

  • a storage folder mount must always be configured in your docker-compose.yml file so that you do not lose these files after a restart or upgrade
  • never configure the storage folder to be inside the originals folder unless the name starts with a . to indicate that it is hidden
  • we recommend placing the storage folder on a local SSD drive for best performance
  • mounting symbolic links or using them inside the storage folder is currently not supported

Should you later want to move your instance to another host, the easiest and most time-saving way is to copy the entire storage folder along with your originals and database.

Import Folder

You can optionally mount an import folder from which files can be transferred to the originals folder in a structured way that avoids duplicates:

  • by default, it is located at /opt/photoprism/import on the host server and at /photoprism/import in the app container
  • imported files receive a canonical filename and will be organized by year and month
  • never configure the import folder to be inside the originals folder, as this will cause a loop by importing already indexed files

You can safely skip this. Adding files via Web Upload and WebDAV remains possible, unless read-only mode is enabled or the features have been disabled.

MariaDB Database

Our example includes a pre-configured MariaDB database server that uses /opt/photoprism/database as storage folder. If you remove it and provide no other database server credentials, SQLite database files will be created in /opt/photoprism/storage.

Never store database files on an unreliable device such as a USB flash drive, SD card, or shared network folder. These may also have unexpected file size limitations, which is especially problematic for databases that do not split data into smaller files. We strongly recommend using SSD storage for databases only, see System Requirements

Network Storage

Shared folders that have already been mounted on your host can be mounted like any local drive or directory. Alternatively, you can mount network storage with Docker Compose. Please never store database files on an unreliable device such as a USB stick, SD card, or network drive.

Unix / NFS

Follow this docker-compose.yml example to mount Network File System (NFS) shares e.g. from Unix servers or NAS devices:

services:
  photoprism:
    # ...
    volumes:
      # Map named volume "originals"
      # to "/photoprism/originals":
      - "originals:/photoprism/originals"     
  mariadb:
    # ...

# Specify named volumes:
volumes:
  originals:
    driver_opts:
      type: nfs
      # Authentication and other mounting options:
      o: "addr=1.2.3.4,username=user,password=secret,soft,rw,nfsvers=4"
      # Mount this path:
      device: ":/mnt/example"

device should contain the path to the share on the NFS server, note the : at the beginning. In the above example, the share can be mounted as the named volume originals. You can also choose another name as long as it is consistent.

Driver-specific options can be set after the server address in o, see the nfs manual page. Here are some examples of commonly used options:

  • nfsvers=3 or nfsvers=4 to specify the NFS version
  • nolock (optional): Remote applications on the NFS server are not affected by lock files inside the Docker container (only other processes inside the container are affected by locks)
  • timeo=n (optional, default 600): The NFS client waits n tenths of a second before retrying an NFS request
  • soft (optional): The NFS client aborts an NFS request after retrans=n unsuccessful retries, otherwise it retries indefinitely
  • retrans=n (optional, default 2): Sets the number of retries for NFS requests, only relevant when using soft

SMB / CIFS

Follow this docker-compose.yml example to mount CIFS network shares, e.g. from Windows, NAS devices or Linux servers with Samba:

services:
  photoprism:
    # ...
    volumes:
      # Map named volume "originals"
      # to "/photoprism/originals":
      - "originals:/photoprism/originals"     
  mariadb:
    # ...

# Specify named volumes:
volumes:
  originals:
    driver_opts:
      type: cifs
      o: "username=user,password=secret,rw"
      device: "//host/folder"

Then restart all services for the changes to take effect. Note that related values must start at the same indentation level in YAML and that tabs are not allowed for indentation. We recommend using 2 spaces, but any number will do as long as it is consistent.

PhotoPrism® Documentation

For detailed information on specific product features, services, and related resources, see our Knowledge Base, or read the User Guide for help using the web user interface: