← All articles
a combination combination padlock attached to a fence

Ente: End-to-End Encrypted Photo Storage You Can Self-Host

Media 2026-02-14 · 7 min read ente photos encryption privacy google-photos-alternative
By Selfhosted Guides Editorial TeamSelf-hosting practitioners covering open source software, home lab infrastructure, and data sovereignty.

Google Photos knows what your face looks like, where you have been, who you spend time with, and what your home looks like inside. Most self-hosted photo alternatives solve the data ownership problem but not the encryption problem -- your photos sit unencrypted on your server, and anyone with access to that machine can see everything. Ente takes a fundamentally different approach: end-to-end encryption. Your photos are encrypted on your device before upload. The server never sees unencrypted data. Even if your server is compromised, your photos remain private.

Photo by Luca Volpe on Unsplash

Ente encrypted photo storage logo

How Ente's Encryption Works

Ente uses client-side encryption with keys derived from your password. Here is the flow:

  1. You set a password when creating your account
  2. A master key is derived from your password on your device
  3. Each photo is encrypted with a unique key
  4. Photo keys are encrypted with your master key
  5. Only encrypted blobs are uploaded to the server
  6. The server stores encrypted data and encrypted metadata
  7. Decryption happens on your device when you view photos

This means:

This is real end-to-end encryption, not "encrypted at rest" marketing. The server is genuinely zero-knowledge.

Self-Hosting the Ente Server

Ente's server (called Museum) is written in Go and uses PostgreSQL for metadata and S3-compatible storage for encrypted photo blobs.

Prerequisites

Docker Compose Setup

version: "3.8"

services:
  museum:
    image: ghcr.io/ente-io/server:latest
    container_name: ente-museum
    restart: unless-stopped
    depends_on:
      - ente-db
      - minio
    ports:
      - "8080:8080"
    volumes:
      - ./museum.yaml:/museum.yaml:ro
      - ente-data:/data
    environment:
      ENTE_DB_HOST: ente-db
      ENTE_DB_PORT: "5432"
      ENTE_DB_NAME: ente
      ENTE_DB_USER: ente
      ENTE_DB_PASSWORD: ente_db_password

  ente-db:
    image: postgres:16-alpine
    container_name: ente-db
    restart: unless-stopped
    volumes:
      - ente-db-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: ente
      POSTGRES_PASSWORD: ente_db_password
      POSTGRES_DB: ente

  minio:
    image: minio/minio:latest
    container_name: ente-minio
    restart: unless-stopped
    command: server /data --console-address ":9001"
    volumes:
      - minio-data:/data
    environment:
      MINIO_ROOT_USER: ente_minio
      MINIO_ROOT_PASSWORD: ente_minio_password
    ports:
      - "9000:9000"
      - "9001:9001"

volumes:
  ente-data:
  ente-db-data:
  minio-data:

Server Configuration

Create museum.yaml in your Ente directory:

db:
  host: ente-db
  port: 5432
  name: ente
  user: ente
  password: ente_db_password

s3:
  are_local_buckets: true
  b2-eu-cen:
    key: ente_minio
    secret: ente_minio_password
    endpoint: http://minio:9000
    region: eu-central-1
    bucket: ente-b2-eu-cen

jwt:
  secret: "generate-a-long-random-secret-here"

key:
  encryption: "generate-32-byte-hex-key"
  hash: "generate-32-byte-hex-key"

Generate the required keys:

# JWT secret
openssl rand -base64 48

# Encryption and hash keys (32-byte hex)
openssl rand -hex 32
openssl rand -hex 32

MinIO Bucket Setup

After starting the stack, create the required bucket in MinIO:

docker compose up -d

# Install MinIO client
docker exec ente-minio mc alias set local http://localhost:9000 ente_minio ente_minio_password
docker exec ente-minio mc mb local/ente-b2-eu-cen

The Ente server should now be accessible at http://your-server:8080.

Connecting Client Apps

Ente provides apps for all major platforms:

To connect the official apps to your self-hosted server, you need to configure the API endpoint. In the mobile apps:

  1. On the login screen, tap the settings icon or look for "Self-hosted"
  2. Enter your server URL (e.g., https://photos.yourdomain.com)
  3. Create an account or log in

The web app can be self-hosted as well or used from web.ente.io pointed at your server.

Important: HTTPS Required

The mobile apps require HTTPS for the server connection. Set up your reverse proxy with a valid SSL certificate before trying to connect from mobile devices.

With Caddy:

photos.yourdomain.com {
    reverse_proxy ente-museum:8080
}

Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.

Migrating from Google Photos

Ente provides a migration tool for Google Takeout exports:

  1. Request your data from Google Takeout (select Google Photos only, choose .zip format)
  2. Download all the export archives
  3. Use the Ente CLI to import:
# Install the Ente CLI
# Download from https://github.com/ente-io/ente/releases (CLI section)

# Configure the CLI for your server
ente account add --endpoint https://photos.yourdomain.com

# Import from Google Takeout
ente export import --from /path/to/takeout/Google\ Photos/

The import preserves album structure, dates, and metadata. Processing time depends on your library size -- expect a few hours for libraries with tens of thousands of photos.

Migrating from Immich

If you are moving from Immich to Ente, export your library from Immich first, then import the files through the Ente client apps or CLI. There is no direct migration tool between the two, so the process involves:

  1. Export photos from Immich (or use the original source files)
  2. Upload to Ente via the desktop or mobile app
  3. Re-create albums manually

The main difference to be aware of: Immich stores photos unencrypted with server-side AI processing. Moving to Ente means giving up server-side features (face recognition, object detection, map view based on GPS) in exchange for end-to-end encryption. You cannot have both -- the server cannot analyze what it cannot see.

What You Gain and Lose vs Unencrypted Alternatives

You Gain

You Lose

Comparison with Alternatives

Ente vs Immich

Immich is the most popular self-hosted Google Photos alternative. It offers face recognition, object detection, map view, smart search, and a timeline that closely mimics Google Photos. These features require server-side access to your unencrypted photos. Immich is the right choice if you trust your server security and want the smartest photo management possible. Ente is the right choice if encryption is non-negotiable.

Ente vs PhotoPrism

PhotoPrism provides AI-powered photo organization with face detection, place recognition, and automatic categorization. Like Immich, these features require unencrypted server-side access. PhotoPrism is more mature than Immich in some areas (particularly search and organization) but has a less polished mobile experience. The same trade-off applies: PhotoPrism for AI features, Ente for encryption.

Ente vs Google Photos

Google Photos offers unlimited storage (at compressed quality), excellent AI features, and seamless integration with Android. The cost is that Google has full access to your photo library for advertising, AI training, and whatever else they decide. Ente provides none of the AI features but guarantees that nobody -- not Google, not you as server operator, not a hacker who breaches your server -- can access photos without the encryption key.

Ente vs Cryptee

Cryptee is another encrypted photo/document storage service but is SaaS-only with no self-hosting option. Ente's open-source server allows full self-hosting. Both provide genuine end-to-end encryption. If you want the simplicity of a managed service with encryption, Cryptee works. If you want full infrastructure control, Ente's self-hosted option is unique in this space.

Storage Considerations

Since photos are encrypted, they cannot be compressed or de-duplicated server-side. Plan your storage accordingly:

MinIO works well for local storage. For larger collections, consider mounting network storage (NFS, CIFS) as the MinIO data directory, or use an external S3 provider. Since data is encrypted before upload, using a third-party S3 provider does not compromise privacy.

Backup Strategy

With Ente, backups are simpler than with unencrypted alternatives because the data is already encrypted:

# Back up PostgreSQL metadata
docker exec ente-db pg_dump -U ente ente > ente-metadata-$(date +%Y%m%d).sql

# MinIO data can be backed up with standard file tools or replicated to another MinIO instance
# The encrypted blobs can safely be copied to any storage, even untrusted

The encrypted blobs are safe to store anywhere. Your PostgreSQL backup contains encrypted metadata. Both are useless without the user's encryption key.

When to Choose Ente

Choose Ente when:

Choose something else when:

Ente occupies a unique niche in the self-hosted photo space: it is the only serious option that prioritizes encryption over features. For users who consider their photo library one of their most sensitive data sets, that trade-off is worth making.

Get free weekly tips in your inbox. Subscribe to Self-Hosted Weekly