イントロ
みなさま、画像の管理はどのようにされていますか?GoogleフォトやiCloudフォトを使っていますか?
今回紹介するのは、Ente photos!
Enteはプライバシー重視のエンドツーエンド暗号化された写真管理アプリケーションです。
プライバシーを気にしている方、Googleドライブに肌色の写真があっていつBANされるかヒヤヒヤしている方、ぜひEnteをお試しください。
機械学習による顔認識もしてくれて、この学習データも含めてプライバシーファーストです。6日目に紹介しているGarageに配置するのでストレージ容量は自分で管理できる、というのがメリットです。
Enteの使い方
環境情報
$ docker version
Client: Docker Engine - Community
Version: 29.1.3
API version: 1.52
Go version: go1.25.5
Git commit: f52814d
Built: Fri Dec 12 14:49:51 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 29.1.3
API version: 1.52 (minimum version 1.44)
Go version: go1.25.5
Git commit: fbf3ed2
Built: Fri Dec 12 14:49:51 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v2.2.0
GitCommit: 1c4457e00facac03ce1d75f7b6777a7a851e5c41
runc:
Version: 1.3.4
GitCommit: v1.3.4-0-gd6d73eb8
docker-init:
Version: 0.19.0
GitCommit: de40ad0
前提条件
- Docker がインストールされていること
- Traefik が導入されていること(リバースプロキシサーバー)
手順
-
compose.ymlを作成します。domain.tldは自分の環境に合わせて変更してください。
機能が多すぎてややこしいのですが、https://ente.domain.tldはバックエンド、https://pics.domain.tldがフロントエンドになります。
その他、アルバムやアカウント管理、認証、キャスト機能などもあるので、各URLを確認してください。compose.ymlservices: museum: image: ghcr.io/ente-io/server container_name: museum restart: unless-stopped depends_on: postgres: condition: service_healthy env_file: - .env volumes: - ./museum.yaml:/museum.yaml:ro - ./data:/data:ro networks: - ente - traefik-network labels: traefik.enable: true traefik.docker.network: traefik-network traefik.http.routers.museum.rule: Host(`ente.domain.tld`) traefik.http.routers.museum.entrypoints: websecure traefik.http.routers.museum.tls: true traefik.http.routers.museum.tls.certResolver: cloudflare traefik.http.services.museum.loadbalancer.server.port: 8080 # ファイルアップロード用の設定 traefik.http.routers.museum.middlewares: museum-headers traefik.http.middlewares.museum-headers.headers.customrequestheaders.X-Forwarded-Proto: https glance.parent: ente glance.name: museum postgres: image: postgres:15-trixie container_name: ente-db restart: unless-stopped env_file: - .env user: "1000:1000" healthcheck: test: pg_isready -q -d ${POSTGRES_DB} -U ${POSTGRES_USER} start_period: 30s start_interval: 1s volumes: - ./db:/var/lib/postgresql/data labels: glance.parent: ente glance.name: db networks: - ente # 11日目の記事で紹介します # - postgres-backup-network ente-web: image: ghcr.io/ente-io/web container_name: ente-web restart: unless-stopped environment: NODE_ENV: production NEXT_PUBLIC_ENTE_ENDPOINT: https://ente.domain.tld NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT: https://entealbum.domain.tld NEXT_PUBLIC_ENTE_ACCOUNTS_URL: https://enteaccounts.domain.tld ENTE_API_ORIGIN: https://ente.domain.tld ENTE_ALBUMS_ORIGIN: https://entealbum.domain.tld env_file: - .env networks: - ente - traefik-network labels: traefik.enable: true traefik.docker.network: traefik-network # Main web interface (pics) traefik.http.routers.enteweb.rule: Host(`pics.domain.tld`) traefik.http.routers.enteweb.entrypoints: websecure traefik.http.routers.enteweb.tls: true traefik.http.routers.enteweb.tls.certResolver: cloudflare traefik.http.routers.enteweb.service: enteweb traefik.http.services.enteweb.loadbalancer.server.port: 3000 # Albums traefik.http.routers.entealbum.rule: Host(`entealbum.domain.tld`) traefik.http.routers.entealbum.entrypoints: websecure traefik.http.routers.entealbum.tls: true traefik.http.routers.entealbum.tls.certResolver: cloudflare traefik.http.routers.entealbum.service: entealbum traefik.http.services.entealbum.loadbalancer.server.port: 3002 # Accounts traefik.http.routers.enteaccounts.rule: Host(`enteaccounts.domain.tld`) traefik.http.routers.enteaccounts.entrypoints: websecure traefik.http.routers.enteaccounts.tls: true traefik.http.routers.enteaccounts.tls.certResolver: cloudflare traefik.http.routers.enteaccounts.service: enteaccounts traefik.http.services.enteaccounts.loadbalancer.server.port: 3001 # Auth traefik.http.routers.enteauth.rule: Host(`enteauth.domain.tld`) traefik.http.routers.enteauth.entrypoints: websecure traefik.http.routers.enteauth.tls: true traefik.http.routers.enteauth.tls.certResolver: cloudflare traefik.http.routers.enteauth.service: enteauth traefik.http.services.enteauth.loadbalancer.server.port: 3005 # Cast(キャスト機能) traefik.http.routers.entecast.rule: Host(`entecast.domain.tld`) traefik.http.routers.entecast.entrypoints: websecure traefik.http.routers.entecast.tls: true traefik.http.routers.entecast.service: entecast traefik.http.services.entecast.loadbalancer.server.port: 3004 networks: ente: traefik-network: external: true # # 11日目の記事で紹介します # postgres-backup-network: # external: true -
museum.yamlを作成します。初期は空白でいいです。Enteのアカウント作成後、デフォルトで10GBの制限があります。CLIによる容量無制限化の設定を行うことで100TBまでの拡張が行われます。
その際のAdminユーザーのIDを入力するのがこのファイルです。(ドキュメント上では他にもs3の設定などが必要ですが全て.envで設定します)museum.yaml# internal: # admins: # - <USER ID> -
.envファイルを作成します。SMTPの設定は任意ですが、アカウント有効化する際にメール認証が行われます。SMTPの設定をしていない場合ログから確認する形になるので、初期設定はともかく、複数ユーザーの登録を想定している場合は設定した方がいいです。
.env# PostgreSQL設定 POSTGRES_USER=pguser POSTGRES_PASSWORD="PgP@ssw0rd!" POSTGRES_DB=ente_db # Garage S3の設定 MINIO_ROOT_USER="" # AccessKey MINIO_ROOT_PASSWORD="" # SecretKey MINIO_ENDPOINT="https://s3.domain.tld" # Garage S3エンドポイント MINIO_REGION="garage" MINIO_BUCKET="ente-photo" # Museum暗号化キー(32バイトのBase64) MUSEUM_KEY="" # openssl rand -base64 32 # Museum ハッシュキー(64バイトのBase64) MUSEUM_HASH="" # openssl rand -base64 64 # JWT秘密キー(32バイトのBase64、URL安全) MUSEUM_JWT_SECRET="" # openssl rand -base64 32 | tr '+/' '-_' | tr -d '=' # ENTE ## DB ENTE_DB_HOST=ente-db ENTE_DB_PORT=5432 ENTE_DB_NAME=${POSTGRES_DB} ENTE_DB_USER=${POSTGRES_USER} ENTE_DB_PASSWORD=${POSTGRES_PASSWORD} ## S3 storage ENTE_S3_ARE_LOCAL_BUCKETS=true ENTE_S3_USE_PATH_STYLE_URLS=true ENTE_S3_B2_EU_CEN_KEY=${MINIO_ROOT_USER} ENTE_S3_B2_EU_CEN_SECRET=${MINIO_ROOT_PASSWORD} ENTE_S3_B2_EU_CEN_ENDPOINT=${MINIO_ENDPOINT} ENTE_S3_B2_EU_CEN_REGION=${MINIO_REGION} ENTE_S3_B2_EU_CEN_BUCKET=${MINIO_BUCKET} # 全てGarage扱いにする(REGION, BUCKETが設定されていなければ多分一つのリージョン管理で終わる、特にエラーは出ていない感じ) ENTE_S3_WASABI_EU_CENTRAL_2_V3_KEY=${MINIO_ROOT_USER} ENTE_S3_WASABI_EU_CENTRAL_2_V3_SECRET=${MINIO_ROOT_PASSWORD} ENTE_S3_WASABI_EU_CENTRAL_2_V3_ENDPOINT=${MINIO_ENDPOINT} ENTE_S3_WASABI_EU_CENTRAL_2_V3_REGION=eu-central-2 ENTE_S3_WASABI_EU_CENTRAL_2_V3_BUCKET=wasabi-eu-central-2-v3 ENTE_S3_WASABI_EU_CENTRAL_2_V3_COMPLIANCE=false ENTE_S3_SCW_EU_FR_V3_KEY=${MINIO_ROOT_USER} ENTE_S3_SCW_EU_FR_V3_SECRET=${MINIO_ROOT_PASSWORD} ENTE_S3_SCW_EU_FR_V3_ENDPOINT=${MINIO_ENDPOINT} ENTE_S3_SCW_EU_FR_V3_REGION=eu-central-2 ENTE_S3_SCW_EU_FR_V3_BUCKET=scw-eu-fr-v3 ## WebApp ENTE_APPS_PUBLIC_ALBUMS=https://entealbum.domain.tld ENTE_APPS_CAST=https://entecast.domain.tld ENTE_APPS_ACCOUNTS=https://enteaccounts.domain.tld ## 暗号化キー設定 ENTE_KEY_ENCRYPTION=${MUSEUM_KEY} ENTE_KEY_HASH=${MUSEUM_HASH} ## JWT設定 ENTE_JWT_SECRET=${MUSEUM_JWT_SECRET} # Email設定 # ENTE_SMTP_HOST="" # ENTE_SMTP_PORT="" # ENTE_SMTP_USERNAME="" # ENTE_SMTP_PASSWORD="" # ENTE_SMTP_EMAIL="" # ENTE_SMTP_SENDER_NAME="" # ENTE_SMTP_ENCRYPTION="" -
Docker Composeで起動します。
docker compose up -d -
ブラウザで
https://pics.domain.tldにアクセスし、アカウントを作成します。なお、バックエンドは
https://ente.domain.tldになります。
細かいことはドキュメントを確認してください。
Enteの感想
- 良いところ
- エンドツーエンド暗号化でプライバシー重視の写真管理
- セルフホストS3に対応しており、クラウドにバックアップなどの管理も可能
- 機械学習の機能があり、写真の整理が容易(写真に対してレシートやスクリーンショット、ミーム、ペットなど様々なラベルをつけてくれる)
- 不満・使いこなせていないところ
- Adminによる操作はCLIベース
- 細かいストレージの制御が効かない
以上、Enteの紹介でした。
なお、Enteは2FAのアプリも出しており、Ente authにも大変お世話になっております。
こちらも興味があればぜひ