Il mio mondo digitale

Self‑hosting di Ente Foto con Docker Compose e Backblaze B2

Pubblicato il: da Denial403

7 min di lettura

Ente Foto è un servizio per l’archiviazione e la sincronizzazione di foto e video con una forte attenzione alla privacy. Per funzionalità ricorda Google Foto o Apple Foto (backup automatico, app mobile, organizzazione per album), ma con una differenza fondamentale: crittografia end‑to‑end e possibilità di hostarlo sul proprio server.

In questo articolo racconto la mia esperienza di installazione di Ente Foto in un ambiente di test, utilizzando Docker Compose e come storage un bucket S3 compatibile su Backblaze B2.

Mi sono basato sulla documentazione ufficiale di Ente e sugli appunti di alcuni amici nerd, adattando il tutto alla mia infrastruttura.


Perché Ente Foto

Se stai cercando un’alternativa self‑hosted a Google Foto che non sacrifichi la privacy, Ente è una delle soluzioni più interessanti oggi disponibili:

  • Crittografia end‑to‑end reale
  • Supporto a storage S3 compatibili
  • App ufficiali (Android, iOS, desktop)
  • Installazione relativamente semplice via Docker

L’unico vero requisito è avere un minimo di confidenza con Docker e con la gestione di servizi web.


Prerequisiti

Nel mio setup ho utilizzato:

  • Sistema operativo Linux (Debian 13)
  • Docker e Docker Compose installati
  • Un bucket S3 su Backblaze B2

Naturalmente puoi adattare la guida ad altre distribuzioni Linux o ad altri provider S3 compatibili.


Clonare il repository di Ente

Per iniziare cloniamo il repository ufficiale di Ente e ci spostiamo nella directory di configurazione del server:

git clone https://github.com/ente-io/ente
cd ente/server/config

All’interno di questa directory troviamo i file di esempio necessari per l’installazione.


Preparazione dei file di configurazione

Rinominiamo i file di esempio che useremo:

cp example.env .env
cp example.yaml museum.yaml

File .env

# Copy this file to .env in the same directory in which this file is present
# This file contains the environment variables needed for Ente's cluster to run properly.
# This file is split based on services declared in Docker Compose file
#
# Service: Postgres
# This is used for storing data in database pertaining to collections, files, users, subscriptions, etc.
# These credentials are needed for accessing the database via Museum.
# Please set a strong password for accessing the database.
# Enter these values in museum.yaml file under `db`.
# This need not be defined if using external DB (i. e. no Compose service for PostgreSQL is used)
POSTGRES_USER=pguser
POSTGRES_PASSWORD=postgrespassword
POSTGRES_DB=ente_db

# Service: MinIO
# This is used for MinIO object storage service that's shipped by default with the compose file
# to reduce need for an external S3-compatible bucket for quick testing.
# It is recommended to use an external bucket for long-term usage.
# The credentials required for accessing the object storage is documented below.
# It is not needed to configure these variables if you are using an external bucket
# Enter the user value into key and password in secret for buckets in museum.yaml under `s3` section.
MINIO_ROOT_USER=
MINIO_ROOT_PASSWORD=

# Service: Web
# This is used for configuring public albums, API endpoints, etc.
# Replace the below endpoints to the correct subdomains of your choice.
ENTE_API_ORIGIN=https://api.ente.culturanerd.it
ENTE_ALBUMS_ORIGIN=https://albums.ente.culturanerd.it
ENTE_PHOTOS_ORIGIN=https://web.ente.culturanerd.it

Nel file .env ho effettuato poche modifiche:

  • Impostato POSTGRES_PASSWORD con una password sicura
  • Valorizzato le variabili:
ENTE_API_ORIGIN=
ENTE_ALBUMS_ORIGIN=
ENTE_PHOTOS_ORIGIN=

utilizzando i nomi DNS per la mia installazione

Queste variabili sono fondamentali per il corretto funzionamento delle app client.


File museum.yaml

# Copy this file to museum.yaml in the same directory in which this file is present

# This section is meant for configuration of database.
# Museum uses these values and credentials for connecting
# to the database.
# Set a strong password and if using PostgreSQL Docker container
# provided in Docker Compose file, ensure db.password is same
# as POSTGRES_PASSWORD
# Similarly ensure db.user and db.name are same as POSTGRES_USER and
# POSTGRES_DB respectively
db:
    host: postgres
    port: 5432
    name: ente_db
    user: pguser
    password: postgrespassword

# This section is for configuring storage buckets. Omit this section if
# you only intend to use Ente Auth
s3:
    # Change this to false if enabling SSL
    are_local_buckets: false
    # Only path-style URL works if disabling are_local_buckets with MinIO
    use_path_style_urls: true
    b2-eu-cen:
      # Uncomment the below configuration to override the top-level configuration
      # are_local_buckets: true
      # use_path_style_urls: true
      key: _KEY_
      secret: _SECRET_
      endpoint: s3.us-west-001.backblazeb2.com
      region: eu-central-2
      bucket: _NOMEBUCKET_
    wasabi-eu-central-2-v3:
      # are_local_buckets: true
      # use_path_style_urls: true
      key: <key>
      secret: <secret>
      endpoint: localhost:3200
      region: eu-central-2
      bucket: wasabi-eu-central-2-v3
      compliance: false
    scw-eu-fr-v3:
      # are_local_buckets: true
      # use_path_style_urls: true
      key: <key>
      secret: <secret>
      endpoint: localhost:3200
      region: eu-central-2
      bucket: scw-eu-fr-v3

# Specify the base endpoints for various web apps
apps:
    # If you're running a self hosted instance and wish to serve public links,
    # set this to the URL where your albums web app is running.
    public-albums: https://albums.ente.culturanerd.it
    cast: https://cast.ente.culturanerd.it
    embed-albums: https://share.ente.culturanerd.it
    # Set this to the URL where your accounts web app is running, primarily used for
    # passkey based 2FA.
    accounts: https://accounts.ente.culturanerd.it

# Key used for encrypting customer emails before storing them in DB
#
# To make it easy to get started, some randomly generated (but fixed) values are
# provided here. But if you're really going to be using museum, please generate
# new keys. You can use `go run tools/gen-random-keys/main.go` for that.
#
# Replace values in key and JWT for security
key:
    encryption: _ENCRYPTION_
    hash: _HASH_
# JWT secrets
jwt:
    secret: _SECRET_

Nel file museum.yaml ho modificato solo le sezioni necessarie, adattandole alla mia installazione.

In particolare:

  • Configurazione dello storage S3
  • Credenziali e endpoint di Backblaze B2
  • Bucket dedicato alle foto

I dati di accesso a Backblaze (key, secret, endpoint) si ottengono una volta creato il bucket dal pannello di controllo.

Bisogna solo modificare i valori:

key secret endopoint bucket

Lasciare inalterati gli altri parametri in quanto sono hardcoded nell'applicazione


Generazione delle chiavi crittografiche

Ente richiede alcune chiavi casuali definite nel file museum.yaml per:

  • encryption
  • hash
  • jwt

Per generarle è necessario installare Go:

apt install golang

Dopodiché eseguire lo script fornito dal progetto:

go ../tools/gen-random-keys/main.go

L’output andrà copiato nelle rispettive sezioni del file museum.yaml.


Avvio dei container

A questo punto siamo pronti per buildare e avviare i container Docker:

docker compose up -d

Il primo avvio richiede un po’ di tempo, soprattutto per il download delle immagini e l’inizializzazione dei servizi.

Al termine, se tutto è andato a buon fine, il server Ente sarà operativo.


Reverse proxy con Caddy

Per esporre Ente in HTTPS ho utilizzato Caddy come reverse proxy.

L’installazione e la configurazione di Caddy in Docker sono descritte in dettaglio in questo articolo

Una volta configurato Caddy, è sufficiente creare i VirtualHost in Caddyfile per:

  • API
  • Albums
  • Photos

puntando ai rispettivi servizi Docker di Ente.

# For Museum
api.ente.culturanerd.it {
    reverse_proxy http://localhost:8080
}

# For Ente Photos web app
web.ente.culturanerd.it {
    reverse_proxy http://localhost:3000
}

# For Ente Accounts web app
accounts.ente.culturanerd.it {
    reverse_proxy http://localhost:3001
}

# For Ente Albums web app
albums.ente.culturanerd.it {
    reverse_proxy http://localhost:3002
}

# For Ente Auth web app
auth.ente.culturanerd.it {
    reverse_proxy http://localhost:3003
}

# For Ente Cast web app
cast.ente.culturanerd.it {
    reverse_proxy http://localhost:3004
}

# For Ente Public Locker web app
share.ente.culturanerd.it {
    reverse_proxy http://localhost:3005
}

# For Ente Embed web app
embed.ente.culturanerd.it {
    reverse_proxy http://localhost:3006
}

Creazione dell’account e conferma

All’apertura della pagina di login, create un account. Attenzione: non avendo ancora un server SMTP, la conferma via mail non arriverà. Per ottenere il codice di conferma:

docker compose logs

OTP


Rimozione dei limiti di storage

Per impostazione predefinita, lo storage è limitato a 10GB. Per rimuovere questo limite è necessario usare Ente CLI.


Installazione di Ente CLI e configurazione

Installiamo alcune dipendenze:

apt install gnome-keyring libsecret-1-0 dbus-x11

E lanciamo questi comandi per i quali, ancora una volta, ringrazio l'amico roughnecks

eval "$(dbus-launch --sh-syntax)"

mkdir -p ~/.cache
mkdir -p ~/.local/share/keyrings # where the automatic keyring is created

# 1. Create the keyring manually with a dummy password in stdin
eval "$(printf '\n' | gnome-keyring-daemon --unlock)"

# 2. Start the daemon, using the password to unlock the just-created keyring:
eval "$(printf '\n' | /usr/bin/gnome-keyring-daemon --start)"

Scaricare e estrarre Ente CLI:

wget https://github.com/ente-io/ente/releases/download/cli-v0.2.3/ente-cli-v0.2.3-linux-amd64.tar.gz
tar zxvf ente-cli-v0.2.3-linux-amd64.tar.gz

Creare il file config.yaml con questo contenuto e nella stessa posizione dell'eseguibile ente di ente-cli

endpoint:
    api: "http://localhost:8080"

Aggiungere l’account:

./ente account add

e recuperare lo user id:

./ente account list

Rendere l’utente admin modificando museum.yaml e inserendo in fondo al file:

internal:
    admin: _USER_ID_

Riavviare i container:

docker compose down && docker compose up -d

Infine, rimuovere il limite dello storage:

./ente admin update-subscription -u email@vostrodominio.tld --no-limit true

Fix errori CORS con Backblaze

Se non riuscite a caricare o visualizzare foto dalla webapp, potrebbe essere un problema di CORS. Procedura:

  • Installare il CLI Backblaze:
wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux
chmod +x b2-linux
mv b2-linux /usr/local/bin
  • Creare una nuova Application Key dall'interfaccia web di BackBlaze e autorizzarsi:
b2 authorize-account
  • Creare cors.json e applicarlo al bucket:
[
  {
    "corsRuleName": "entephotos",
    "allowedOrigins": [
      "*"
    ],
    "allowedHeaders": [
      "*"
    ],
    "allowedOperations": [
      "b2_download_file_by_id",
      "b2_download_file_by_name",
      "b2_upload_file",
      "b2_upload_part",
      "s3_get",
      "s3_post",
      "s3_put",
      "s3_head"
    ],
    "exposeHeaders": [
      "X-Amz-Request-Id",
      "X-Amz-Id-2",
      "ETag"
    ],
    "maxAgeSeconds": 3600
  }
]
b2 bucket update --cors-rules "$(<./cors.json)" _NOME_BUCKET_ allPrivate

Apps

L’app Android funziona perfettamente. Per collegare la vostra istanza:

  • Tappare 7 volte il logo per abilitare le opzioni sviluppatore

  • Inserire l’URL delle API, ad esempio:

https://api.ente.culturanerd.it