Install Ente.io on TrueNAS Community

Ente is a “private cloud for your memories”, and usable as an alternative for iCloud Photos or Google Photos/Drive. Installing on TrueNAS Community (formerly TrueNAS SCALE) can be a bit tricky, though. This is especially due to outdated and contradicted documentation.

Principles

Ente is a set of so-called apps, which are somewhat independent. Available are apps for the API, albums, public albums, accounts, auth, family and cast. It uses S3 storage to store uploaded photos end-to-end encrypted, and a(n optional) local machine learning to process to improve its search.

Coverage

In this article, I’m going to create a setup to allow running the API, albums and accounts app. API is the connection between all apps. The albums app allows us to view the uploaded photos and the accounts app manages accounts, as the name suggests. Since I don’t need the other apps, I’m not going to configure them.

Additionally, this article is not for beginners of TrueNAS Community. It requires basic knowledge of the apps system within TrueNAS and doesn’t explain all parts within TrueNAS in detail (especially regarding configuration, logs, etc.).

What about the documentation?

First of all, the documentation provides a quick start script, which can’t be used on TrueNAS Community due to its different nature on how Docker container work there as apps. It suggests to run everything inside a single container: the apps, the database as well as the S3 storage.

Since I maybe want to use the S3 storage for different purposes in the future, I decided to install it as separate app. As the catalogue already provides MinIO as S3 storage app, we’re going to use this.

MinIO

Installing MinIO is pretty straight forward. Go to your TrueNAS web UI, select Apps and then Discover Apps, search for MinIO and install it as any other app. After that, access its console by opening its web UI, create a new user with read and write access, which later will be used to allow Ente accessing the S3 storage and create a bucket with a name you like. In my case, it’s ente.

Ente

Since Ente is not available as app directly within TrueNAS, we need to create it manually.

First, make sure that all necessary directories and files exist. In my case, all apps are running in /mnt/SSData/apps. Thus, you will see this directory throughout the following article and in the Docker file. Make sure to adjust it to fit your setup.

Configuration

We need to create the directories data and postgres-data as well as the files credentials.yaml and museum.yaml. All within the directory of the app. In my case, I used this commands:

mkdir -p /mnt/SSData/apps/ente/data
mkdir -p /mnt/SSData/apps/ente/postgres-data
touch /mnt/SSData/apps/ente/credentials.yaml
touch /mnt/SSData/apps/ente/museum.yaml

Open the credentials.yaml and paste this content:

key:
      encryption: *snip*
      hash: *snip*

jwt:
      secret: *snip*

db:
      host: postgres
      port: 5432
      name: ente_db
      user: pguser
      password: *snip*

s3:
      are_local_buckets: true
      b2-eu-cen:
         key: ente-user
         secret: *snip*
         endpoint: https://minio.domain.tld
         region: eu-central-2
         bucket: ente
Code language: YAML (yaml)

For key.encryption, generate a key via this command:
head -c 32 /dev/urandom | base64 | tr -d '\n'

For key.hash, generate a hash via this command:
head -c 64 /dev/urandom | base64 | tr -d '\n'

For jwt.secret, generate a secret via this command:
head -c 32 /dev/urandom | base64 | tr -d '\n' | tr '+/' '-_'

For db.password, you can create a password via this command:
head -c 21 /dev/urandom | base64 | tr -d '\n'

For s3.key and s3.secret, use your selected username/password combination you’ve created in MinIO, where s3.key is the username and s3.secret is the password.

Make also sure to replace the s3.endpoint to your MinIO instance, adjust the region to your liking (it doesn’t matter) and use the bucket name you’ve created for s3.bucket. Leave s3.b2-eu-cen as is. It’s hardcoded in Ente, but has nothing directly to do with B2 in this local environment.

Open the museum.yaml and paste this content:

apps:
      accounts: https://ente-accounts.domain.tld

webauthn:
      rpid: ente-accounts.domain.tld
      rporigins:
        - "https://ente-accounts.domain.tld"
Code language: YAML (yaml)

Replace the domains as needed.

Install app

Then, it’s time to create the actual app. Go to Apps > Discover Apps, click on the three vertical dots in the upper right corner and select “Install via YAML” in the drop-down menu. A new window opens to create a new custom app. Give it a name, in my case, again, ente, and paste the following configuration:

services:
  museum:
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      ENTE_CREDENTIALS_FILE: /credentials.yaml
    image: ghcr.io/ente-io/server
    ports:
      - '8080:8080'
    volumes:
      - /mnt/SSData/apps/ente/credentials.yaml:/credentials.yaml:ro
      - /mnt/SSData/apps/ente/museum.yaml:/museum.yaml:ro
      - /mnt/SSData/apps/ente/data:/data:ro
  postgres:
    environment:
      POSTGRES_DB: ente_db
      POSTGRES_PASSWORD: *snip*
      POSTGRES_USER: pguser
    healthcheck:
      start_interval: 1s
      start_period: 40s
      test: pg_isready -q -d ente_db -U pguser
    image: postgres:15
    volumes:
      - /mnt/SSData/apps/ente/postgres-data:/var/lib/postgresql/data
  web:
    image: ghcr.io/ente-io/web
    ports:
      - '3000:3000'
      - '3001:3001'
Code language: YAML (yaml)

Make sure to replace the POSTGRES_PASSWORD environment variable with the same password you’ve also added to the credentials.yaml.

Configure (sub-)domains

By default, the Ente API is now accessible via the host IP and port 8080, the albums (aka photos) via port 3000 and the accounts via port 3001.

In my case, I use ente.domain.tld for the API, ente-albums.domain.tld for the photos and ente-accounts.domain.tld for the accounts, all created via Nginx Proxy Manager. Make sure to create domains via a proxy as well, as otherwise, the API tries always to connect to localhost:8080, which your browser thinks is your own machine and not your TrueNAS Community system.

First login

On first login, you need to create a new user account. By default, despite hosting it on your own machine, Ente tries to create an account on ente.io. To make sure you’re using your own instance, you need to connect to it. See the documentation on how to switch to it:

Then, you can proceed with an account creation. After entering your desired credentials, an OTP code is required. You will find it in the logs of the museum Docker service in your TrueNAS app.

Remove upload size restrictions

By default, your new account can only upload 10 GiB of data, despite hosting it yourself. To change that, you need to use the CLI binary to change it.

Download it from here: https://github.com/ente-io/ente/releases?q=tag%3Acli-v0

The binary must be able to connect to the correct API, so you need to create a config.yaml in the same directory of the binary with the following content:

endpoint:
    api: "https://ente.domain.tld"Code language: YAML (yaml)

Again, adjust the domain to match your instance.

Now, you need to perform three commands. First to add the account to the CLI, then update the subscription to remove the upload size restrictions and finally get the user ID to add it to your museum.yaml for improved security.

The first command to add the account to the CLI:

$ ./ente account addCode language: Bash (bash)

You need to enter the app type (photos), an export directory (which we don’t need here, but it must be an existing valid directory) and your credentials. This may look like this:

$ ./ente account add
Enter app type (default: photos): photos
Enter export directory: ~/
Enter email address: my-email@domain.tld
Enter password:
Please wait authenticating...
Enter TOTP: 979927
Account added successfully
run `ente export` to initiate export of your account data
Code language: Bash (bash)

The command for updating the subscription looks like this:

$ ./ente admin update-subscription --no-limit true -u my-email@domain.tldCode language: Bash (bash)

Make sure to replace my-email@domain.tld with your own email address. The --no-limit true tells Ente that you will have no upload limit. Despite its name, the actual limit is 100 TiB. The output may look like this:

$ ./ente admin update-subscription --no-limit true -u my-email@domain.tld
Assuming my-email@domain.tld as the Admin
------------
Successfully updated storage and expiry date for user
Code language: Bash (bash)

Now list your your accounts to get its ID via this command:

$ ./ente account listCode language: Bash (bash)

This may look like this:

$ ./ente account list
Configured accounts: 1
====================================
Email:     my-email@domain.tld
ID:        1540553952286438
App:       photos
ExportDir: /Users/matze/
====================================
Code language: Bash (bash)

Last, but not least, open your museum.yaml and add your ID to the admins list. By default, the first user always is the admin, but explicitly setting this value enhances security:

internal:
    admins:
        - 1540553952286438Code language: YAML (yaml)

Don’t forget to restart the app and you’re done. 🙂

Note on passkeys

Currently, I didn’t get passkeys to work, since the passkeys page always tries to connect to the wrong API endpoint. I’ve created an issue about that topic and will update this article as soon as possible if a solution could be found.

Leave a Reply

Your email address will not be published. Required fields are marked *