部署实战3 分钟0 次阅读

Self-Hosting Ente Photos with Docker: An End-to-End Encrypted Family Album

Ente keeps a zero-knowledge server: photos are encrypted on the device. Follow the official quickstart, then solve domains, HTTPS, object storage and verification codes.

Self-Hosting Ente Photos with Docker: An End-to-End Encrypted Family Album

Ente Photos is the rare open-source album with end-to-end encryption: photos are encrypted on the device before upload and the server only holds ciphertext. It ships iOS, Android, web and desktop clients, so a self-hosted instance can fully replace a cloud album. This guide follows the official quickstart and covers the parts that actually matter — domains, HTTPS and backups.

1. Three things to know first

  1. The mobile app requires HTTPS. Your self-hosted server address must start with https://; a bare IP over HTTP will not connect. Prepare two domains, for example photos.example.com (web) and api.example.com (API).
  2. At least 2 vCPU / 4 GB, photos in object storage (MinIO or external S3), PostgreSQL for the database.
  3. museum.yaml is a key file. It holds database and object-storage credentials; lose it and the data is effectively unreadable. Back it up.

2. Images and ports

ServiceImagePort
museum (API)ghcr.io/ente-io/server8080
web (Photos)ghcr.io/ente/web3000
web (public albums)ghcr.io/ente/web3002
postgrespostgres:15internal
miniopgsty/silo3200

3. Generate the config with the official quickstart

mkdir -p /opt/ente && cd /opt/ente
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ente/ente/main/server/quickstart.sh)"

The script creates my-ente/ containing compose.yaml and museum.yaml with random passwords already filled in:

cd my-ente
ls -l
docker compose up -d
docker compose ps

Once running, locally you get Photos at http://IP:3000, the API at http://IP:8080/ping and public albums at http://IP:3002.

4. Switch to your own domains and public addresses

By default the S3 endpoint in museum.yaml points at localhost:3200, which only works for local testing. For mobile uploads the client must be able to reach object storage. Two options:

  • Simple: give MinIO an HTTPS domain too (for example s3.example.com), change endpoint in museum.yaml to s3.example.com, and proxy it to port 3200.
  • Recommended: use external S3 in production (Cloudflare R2, Backblaze B2, Alibaba OSS and so on), set are_local_buckets to false and fill in key, secret and endpoint.

Also change ENTE_API_ORIGIN for the web service in compose.yaml to https://api.example.com, otherwise the frontend keeps calling localhost.

5. Reverse proxy

Proxy the three entry points separately, and watch upload size and timeouts:

server {
    listen 443 ssl http2;
    server_name photos.example.com;
    ssl_certificate     /etc/letsencrypt/live/photos.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/photos.example.com/privkey.pem;

    client_max_body_size 0;
    proxy_request_buffering off;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 600s;
    }
}

Repeat with api.example.com → 8080, albums.example.com → 3002 and s3.example.com → 3200 if you keep local MinIO.

6. Sign-up and verification codes

  1. Open https://photos.example.com and register.
  2. Registration needs an email code. A self-hosted instance does not send mail, so the code is printed in the museum logs:
docker compose logs museum | grep -i "verification\|otp" | tail -20
  1. After signing in, create albums and invite family. In the mobile app go to Settings → Server → Custom server and enter https://api.example.com.
Ente Photos web timeline
Ente Photos web timeline — data is ciphertext on the server

7. Backups

  • my-ente/museum.yaml: credentials and keys, back up separately.
  • PostgreSQL volume: docker compose exec postgres pg_dump -U pguser ente_db > ente.sql.
  • MinIO volume (or external S3 bucket): the encrypted photo bodies.

You need all three. Schedule a weekly backup of the database and museum.yaml, and enable versioning on the object storage bucket.

Ente architecture
Ente architecture: client-side encryption, museum, object storage

8. Troubleshooting

The app cannot reach the server? 99% of the time it is HTTPS or the certificate. Open https://api.example.com/ping in the phone browser first; it must return pong.

Uploads fail? Check that the S3 endpoint in museum.yaml is a public address the phone can reach, and that the bucket exists.

Forgot the admin password? Ente passwords participate in key derivation and cannot be reset server-side. Keep your recovery key safe.

9. Wrap-up

Ente is a little more work to deploy than Immich, and what you buy is "the server cannot see my photos". If privacy matters and you want a near-commercial experience, it is worth the extra hour.

Related: Immich tutorial · 2026 self-hosted album comparison

MORE / 03

继续阅读

ChronoFrame Docker Deployment: A One-Command Self-Hosted Portfolio
部署实战

ChronoFrame Docker Deployment: A One-Command Self-Hosted Portfolio

2026.11.14 · 3 分钟

Piwigo Docker Deployment: The Veteran Open-Source Family Gallery
部署实战

Piwigo Docker Deployment: The Veteran Open-Source Family Gallery

2026.11.14 · 3 分钟

Lychee Docker Deployment: A Beautiful Family Photo Album
部署实战

Lychee Docker Deployment: A Beautiful Family Photo Album

2026.11.14 · 3 分钟

星河码客

发现和分享优质开源项目,传承互联网精神,为开发者服务。

关于本站

联系我们

微信/广告合作:ITcloub(备注星河码客)

免责声明:本站资源版权归原作者所有,仅供学习与交流。如有侵权,请通过「关于我们 - 侵权投诉」联系删除。

Powered by Nuxt · Deployed on Cloudflare