Il existe pléthore de solutions de sauvegarde de photos Android/iOS telles que par exemple les gratuites/payantes Apple iCloud, Google Photos ou l’auto-hébergement de Next/OwnCloud. Pas fan des Next/OwnCloud « juste » pour des photos, voici Immich :)

Composé d’un serveur à auto-héberger (Docker) et d’une application Android (F-Droid/Google)/iOS, Immich supporte la géolocalisation (traitée localement), la recherche et, donc, la sauvegarde automatique des photos/vidéos. C’est une simple alternative à iCloud/Google Photos, gratuite.
Features:
* Upload and view assets(videos/images).
* Multi-user supported.
* Quick navigation with drag scroll bar.
* Auto Backup.
* Support HEIC/HEIF Backup.
* Extract and display EXIF info.
* Real-time render from multi-device upload event.
* Image Tagging/Classification based on ImageNet dataset
* Object detection based on COCO SSD.
* Search assets based on tags and exif data (lens, make, model, orientation)
* Upload assets from your local computer/server using immich cli tools
* Reverse geocoding from image exif data
* Show asset’s location information on map (OpenStreetMap).
* Show curated places on the search page
* Show curated objects on the search page
Pour l’installer via Docker, il faut suivre la documentation (Docker, compose, UNRAID, Kubernetes, Portainer). Nous y trouvons un docker-compose et un fichier de variables qui sont donc à télécharger dans le même dossier et à modifier en adéquation avec ses besoins.
C’est assez « lourd » dans le sens où Immich nécessite un un serveur d’upload, du machine-learning pour la détection, une interface Web, un cache et une base de données.
Voici par exemple mes compose et env
version: "3.5" services: immich-server: container_name: immich_server image: ghcr.io/immich-app/immich-server:release entrypoint: ["/bin/sh", "./start-server.sh"] volumes: - /mnt/Data/immich:/usr/src/app/upload env_file: - .env depends_on: - redis - database - typesense restart: always labels: - "com.centurylinklabs.watchtower.enable=true" immich-microservices: container_name: immich_microservices image: ghcr.io/immich-app/immich-server:release entrypoint: ["/bin/sh", "./start-microservices.sh"] volumes: - /mnt/Data/immich:/usr/src/app/upload env_file: - .env depends_on: - redis - database - typesense restart: always labels: - "com.centurylinklabs.watchtower.enable=true" immich-machine-learning: container_name: immich_machine_learning image: ghcr.io/immich-app/immich-machine-learning:release volumes: - /mnt/Data/immich:/usr/src/app/upload - /mnt/Data/docker/immich/cache:/cache env_file: - .env restart: always labels: - "com.centurylinklabs.watchtower.enable=true" immich-web: container_name: immich_web image: ghcr.io/immich-app/immich-web:release entrypoint: ["/bin/sh", "./entrypoint.sh"] env_file: - .env restart: always labels: - "com.centurylinklabs.watchtower.enable=true" typesense: container_name: immich_typesense image: typesense/typesense:0.24.0 environment: - TYPESENSE_API_KEY=${TYPESENSE_API_KEY} - TYPESENSE_DATA_DIR=/data logging: driver: none volumes: - /mnt/Data/docker/immich/tsdata:/data restart: always labels: - "com.centurylinklabs.watchtower.enable=true" redis: container_name: immich_redis image: redis:6.2 restart: always labels: - "com.centurylinklabs.watchtower.enable=true" database: container_name: immich_postgres image: postgres:14 env_file: - .env environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} PG_DATA: /var/lib/postgresql/data volumes: - /mnt/Data/docker/immich/sql:/var/lib/postgresql/data restart: always labels: - "com.centurylinklabs.watchtower.enable=true" immich-proxy: container_name: immich_proxy image: ghcr.io/immich-app/immich-proxy:release environment: # Make sure these values get passed through from the env file - IMMICH_SERVER_URL - IMMICH_WEB_URL ports: - 2283:8080 logging: driver: none depends_on: - immich-server restart: always labels: - "com.centurylinklabs.watchtower.enable=true"
################################################################################### # Database ################################################################################### DB_HOSTNAME=immich_postgres DB_USERNAME=userdelamortquitue DB_PASSWORD=pwddelamortquitue DB_DATABASE_NAME=immich # Optional Database settings: # DB_PORT=5432 ################################################################################### # Redis ################################################################################### REDIS_HOSTNAME=immich_redis # REDIS_URL will be used to pass custom options to ioredis. # Example for Sentinel # {"sentinels":[{"host":"redis-sentinel-node-0","port":26379},{"host":"redis-sentinel-node-1","port":26379},{"host":"redis-sentinel-node-2","port":26379}],"name":"redis-sentinel"} # REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJyZWRpcy1zZW50aW5lbDEiLCJwb3J0IjoyNjM3OX0seyJob3N0IjoicmVkaXMtc2VudGluZWwyIiwicG9ydCI6MjYzNzl9XSwibmFtZSI6Im15bWFzdGVyIn0= # Optional Redis settings: # Note: these parameters are not automatically passed to the Redis Container # to do so, please edit the docker-compose.yml file as well. Redis is not configured # via environment variables, only redis.conf or the command line # REDIS_PORT=6379 # REDIS_DBINDEX=0 # REDIS_USERNAME= # REDIS_PASSWORD= # REDIS_SOCKET= ################################################################################### # Upload File Location # # This is the location where uploaded files are stored. ################################################################################### UPLOAD_LOCATION=/mnt/Data/immich ################################################################################### # Typesense ################################################################################### TYPESENSE_API_KEY=unesourisverte123herbe # TYPESENSE_ENABLED=false # TYPESENSE_URL uses base64 encoding for the nodes json. # Example JSON that was used: # [ # { 'host': 'typesense-1.example.net', 'port': '443', 'protocol': 'https' }, # { 'host': 'typesense-2.example.net', 'port': '443', 'protocol': 'https' }, # { 'host': 'typesense-3.example.net', 'port': '443', 'protocol': 'https' }, # ] # TYPESENSE_URL=ha://WwogICAgeyAnaG9zdCc6ICd0eXBlc2Vuc2UtMS5leGFtcGxlLm5ldCcsICdwb3J0JzogJzQ0MycsICdwcm90b2NvbCc6ICdodHRwcycgfSwKICAgIHsgJ2hvc3QnOiAndHlwZXNlbnNlLTIuZXhhbXBsZS5uZXQnLCAncG9ydCc6ICc0NDMnLCAncHJvdG9jb2wnOiAnaHR0cHMnIH0sCiAgICB7ICdob3N0JzogJ3R5cGVzZW5zZS0zLmV4YW1wbGUubmV0JywgJ3BvcnQnOiAnNDQzJywgJ3Byb3RvY29sJzogJ2h0dHBzJyB9LApd ################################################################################### # Reverse Geocoding # # Reverse geocoding is done locally which has a small impact on memory usage # This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable # This ranges from 0-3 with 3 being the most precise # 3 - Cities > 500 population: ~200MB RAM # 2 - Cities > 1000 population: ~150MB RAM # 1 - Cities > 5000 population: ~80MB RAM # 0 - Cities > 15000 population: ~40MB RAM #################################################################################### DISABLE_REVERSE_GEOCODING=false REVERSE_GEOCODING_PRECISION=3 #################################################################################### # WEB - Optional # # Custom message on the login page, should be written in HTML form. # For example: # PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>[email protected]</i><br>Password: <i>demo</i>" #################################################################################### PUBLIC_LOGIN_PAGE_MESSAGE=Bienvenue :) #################################################################################### # Alternative Service Addresses - Optional # # This is an advanced feature for users who may be running their immich services on different hosts. # It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers. # Note: immich-microservices is bound to 3002, but no references are made #################################################################################### IMMICH_WEB_URL=http://immich-web:3000 IMMICH_SERVER_URL=http://immich-server:3001 IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003 #################################################################################### # Alternative API's External Address - Optional # # This is an advanced feature used to control the public server endpoint returned to clients during Well-known discovery. # You should only use this if you want mobile apps to access the immich API over a custom URL. Do not include trailing slash. # NOTE: At this time, the web app will not be affected by this setting and will continue to use the relative path: /api # Examples: http://localhost:3001, http://immich-api.example.com, etc #################################################################################### #IMMICH_API_URL_EXTERNAL=http://localhost:3001
Et pour être complet, l’utiliser depuis un smartphone, il faut évidemment un proxy.
Voici par exemple mon DDNS Cloudflare
docker run -d \ --name=immichddns \ --restart always \ -e ZONE=domaine.perso \ -e HOST=immich.domaine.perso \ -e [email protected] \ -e API=xxx \ -e PROXY=true \ -e FORCE_CREATE=true \ --label=com.centurylinklabs.watchtower.enable=true \ joshuaavalon/cloudflare-ddns
Une fois le serveur installé et accessible on peut s’enregistrer dessus puis s’y connecter


Quelques options






Test avec l’applciation pour iPhone



Et mon espace commence à se remplir

Immich me semble être la solution la plus simple pour se passer des services payants iCloud/Google Photos.