PhotoPrism es una aplicación web autoalojada para organizar fotos y vídeos: indexa tu biblioteca, lee los metadatos EXIF, clasifica las imágenes por contenido, reconoce caras y muestra las fotos en un mapa, todo en tu propio servidor. En este tutorial desplegarás PhotoPrism con Docker Compose y MariaDB en Ubuntu 24.04, indexarás una primera colección y lo publicarás en un dominio con HTTPS a través de Nginx.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS con al menos 2 núcleos y 4 GB de RAM, por ejemplo un VPS de CubePath. La indexación de bibliotecas grandes y la clasificación por IA agradecen más núcleos y memoria.
- Un usuario no root con privilegios
sudo. - Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker.
- Espacio en disco para tus fotos más un 20 a 30 % adicional para miniaturas y caché.
- Un dominio con un registro A apuntando a la IP del servidor, por ejemplo
fotos.tu_dominio.
Paso 1: Preparar los directorios
PhotoPrism trabaja con dos carpetas: originals, donde viven tus fotos originales, y storage, donde guarda miniaturas, caché, sidecars y copias de seguridad del índice. La base de datos de MariaDB irá en una tercera carpeta:
mkdir -p ~/photoprism/{originals,storage,database}
cd ~/photoprism
Genera dos contraseñas, una para el administrador de PhotoPrism y otra para la base de datos. Anótalas, las usarás en el siguiente paso:
openssl rand -base64 18
openssl rand -hex 16
La contraseña de administrador debe tener al menos 8 caracteres. Para la de la base de datos se usa hexadecimal para evitar caracteres especiales en el fichero YAML.
Paso 2: Crear el fichero de Docker Compose
Crea el fichero compose.yaml basado en la configuración oficial, reducido a las opciones que realmente necesitas:
nano ~/photoprism/compose.yaml
services:
photoprism:
image: photoprism/photoprism:latest
restart: unless-stopped
stop_grace_period: 15s
depends_on:
- mariadb
security_opt:
- seccomp:unconfined
- apparmor:unconfined
ports:
- "127.0.0.1:2342:2342"
environment:
PHOTOPRISM_ADMIN_USER: "admin"
PHOTOPRISM_ADMIN_PASSWORD: "contraseña_admin"
PHOTOPRISM_AUTH_MODE: "password"
PHOTOPRISM_SITE_URL: "https://fotos.tu_dominio/"
PHOTOPRISM_DISABLE_TLS: "true"
PHOTOPRISM_ORIGINALS_LIMIT: 5000
PHOTOPRISM_HTTP_COMPRESSION: "gzip"
PHOTOPRISM_LOG_LEVEL: "info"
PHOTOPRISM_DATABASE_DRIVER: "mysql"
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
PHOTOPRISM_DATABASE_NAME: "photoprism"
PHOTOPRISM_DATABASE_USER: "photoprism"
PHOTOPRISM_DATABASE_PASSWORD: "contraseña_bd"
PHOTOPRISM_SITE_CAPTION: "Mis fotos"
working_dir: "/photoprism"
volumes:
- "./originals:/photoprism/originals"
- "./storage:/photoprism/storage"
mariadb:
image: mariadb:11
restart: unless-stopped
stop_grace_period: 15s
security_opt:
- seccomp:unconfined
- apparmor:unconfined
command: --innodb-buffer-pool-size=512M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
volumes:
- "./database:/var/lib/mysql"
environment:
MARIADB_AUTO_UPGRADE: "1"
MARIADB_INITDB_SKIP_TZINFO: "1"
MARIADB_DATABASE: "photoprism"
MARIADB_USER: "photoprism"
MARIADB_PASSWORD: "contraseña_bd"
MARIADB_ROOT_PASSWORD: "contraseña_root_bd"
Sustituye contraseña_admin, contraseña_bd (debe ser la misma en los dos servicios), contraseña_root_bd y fotos.tu_dominio por tus valores. Algunas decisiones importantes:
- El puerto se publica solo en
127.0.0.1. Docker añade sus propias reglas de iptables y un puerto publicado en todas las interfaces quedaría expuesto a internet aunque UFW lo bloquee. Nginx será la única entrada. PHOTOPRISM_DISABLE_TLSdesactiva el certificado autofirmado que PhotoPrism generaría al ver una URLhttps://, porque de TLS se encargará Nginx.PHOTOPRISM_ADMIN_PASSWORDsolo se usa al crear la cuenta la primera vez. Para cambiarla después usa la interfaz web ophotoprism passwd.
Como el fichero contiene contraseñas, restringe sus permisos:
chmod 600 ~/photoprism/compose.yaml
Paso 3: Arrancar PhotoPrism
Descarga las imágenes y arranca los contenedores en segundo plano:
cd ~/photoprism
docker compose up -d
El primer arranque tarda un par de minutos mientras MariaDB inicializa la base de datos y PhotoPrism crea las tablas. Comprueba el estado:
docker compose ps
NAME IMAGE SERVICE STATUS PORTS
photoprism-mariadb-1 mariadb:11 mariadb Up 2 minutes
photoprism-photoprism-1 photoprism/photoprism:latest photoprism Up 2 minutes 127.0.0.1:2342->2342/tcp
Verifica que la aplicación responde en local:
curl -s -o /dev/null -w "%{http_code}\n" -L http://127.0.0.1:2342/
200
Si el contenedor se reinicia en bucle, revisa docker compose logs photoprism --tail 50; lo más habitual es una contraseña de base de datos que no coincide entre los dos servicios.
Paso 4: Publicar PhotoPrism por HTTPS con Nginx
Instala Nginx y Certbot, y permite el tráfico web en UFW:
sudo apt install nginx certbot python3-certbot-nginx
sudo ufw allow OpenSSH
sudo ufw allow "Nginx Full"
sudo ufw enable
Crea el sitio:
sudo nano /etc/nginx/sites-available/photoprism
server {
listen 80;
listen [::]:80;
server_name fotos.tu_dominio;
# Permite subir fotos y vídeos grandes desde el navegador
client_max_body_size 500M;
location / {
proxy_pass http://127.0.0.1:2342;
proxy_http_version 1.1;
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;
# WebSocket para las notificaciones en tiempo real
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 600s;
}
}
Activa el sitio, valida la configuración y obtén el certificado:
sudo ln -s /etc/nginx/sites-available/photoprism /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d fotos.tu_dominio
Abre https://fotos.tu_dominio e inicia sesión con el usuario admin y la contraseña que definiste. En Settings puedes cambiar el idioma de la interfaz a español.
Paso 5: Añadir e indexar fotos
PhotoPrism no vigila la carpeta de originales en tiempo real: los ficheros nuevos aparecen cuando se indexan. Copia tus fotos a ~/photoprism/originals, respetando la estructura de carpetas que quieras conservar. Desde otro equipo puedes usar rsync:
rsync -avh --progress /ruta/local/fotos/ tu_usuario@ip_del_servidor:~/photoprism/originals/
Lanza la indexación desde la línea de comandos. Es más rápido y más fácil de seguir que desde la web en bibliotecas grandes:
cd ~/photoprism
docker compose exec photoprism photoprism index --cleanup
La opción --cleanup elimina del índice los ficheros que ya no existen y las miniaturas huérfanas. El comando muestra cada fichero procesado y termina con un resumen del número de ficheros indexados y el tiempo empleado.
También puedes indexar desde la interfaz en Library > Index. Si prefieres subir fotos desde el navegador o la app móvil (por WebDAV), PhotoPrism las guarda en originals y las indexa automáticamente.
Para que las fotos que copias por rsync se indexen sin intervención, programa el índice con cron. Abre tu crontab:
crontab -e
Añade esta línea para indexar cada noche a las 3:00:
0 3 * * * cd "$HOME/photoprism" && docker compose exec -T photoprism photoprism index --cleanup > /dev/null 2>&1
Paso 6: Reconocimiento facial y búsqueda
Durante la indexación, PhotoPrism clasifica cada imagen (playa, montaña, perro, documento...) y detecta caras. Las caras que aparecen varias veces se agrupan automáticamente en People; asigna un nombre a cada grupo y PhotoPrism reconocerá a esa persona en el resto de la biblioteca.
Consulta el estado del reconocimiento facial:
docker compose exec photoprism photoprism faces stats
Si después de nombrar personas quieres que PhotoPrism vuelva a agrupar y asignar caras en toda la biblioteca, ejecuta:
docker compose exec photoprism photoprism faces index
Las fotos con coordenadas GPS en el EXIF se muestran en Places. En el buscador puedes combinar filtros, por ejemplo label:beach year:2024 o country:es.
Paso 7: Copias de seguridad
Tus fotos originales son lo más importante, pero el índice (álbumes, personas, etiquetas, favoritos) vive en la base de datos. PhotoPrism puede volcar la base de datos y los álbumes en storage/backup:
docker compose exec photoprism photoprism backup -i -a -f
Comprueba que se ha generado el volcado:
ls -lhR ~/photoprism/storage/backup/
Copia regularmente fuera del servidor, con rsync, restic o borg, las carpetas originals y storage/backup. Las miniaturas y la caché de storage se pueden regenerar y no hace falta incluirlas.
Actualizar PhotoPrism
Haz primero una copia de seguridad (paso 7) y después descarga las nuevas imágenes y recrea los contenedores:
cd ~/photoprism
docker compose pull
docker compose up -d
MariaDB actualizará sus tablas automáticamente gracias a MARIADB_AUTO_UPGRADE. Revisa docker compose logs photoprism --tail 30 para confirmar que arranca sin errores.
Solución de problemas
Access denied for user 'photoprism' en los logs. La contraseña de PHOTOPRISM_DATABASE_PASSWORD y MARIADB_PASSWORD no coinciden, o las cambiaste después del primer arranque. MariaDB solo lee esas variables al crear la base de datos; si ya existía, cambia la contraseña dentro de MariaDB o, en una instalación nueva, vacía la carpeta database y vuelve a arrancar.
Las fotos nuevas no aparecen. PhotoPrism no indexa originals en tiempo real. Ejecuta photoprism index o revisa que el cron del paso 5 está instalado con crontab -l.
La indexación satura el servidor. Limita los procesos en paralelo añadiendo PHOTOPRISM_WORKERS: 2 en environment y ejecuta docker compose up -d para aplicarlo.
Error 413 al subir vídeos desde el navegador. El vídeo supera client_max_body_size de Nginx. Aumenta el valor en el sitio y recarga con sudo systemctl reload nginx.
Conclusión
Has desplegado PhotoPrism con MariaDB en Docker, protegido detrás de Nginx con HTTPS, con indexación programada y copias del índice. Como siguientes pasos puedes conectar la app móvil PhotoSync u otro cliente WebDAV para subir fotos automáticamente, crear usuarios adicionales con photoprism users add o montar un volumen de almacenamiento dedicado para originals cuando la biblioteca crezca.
