0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

一人アドカレ 9日目: Enteの紹介

Posted at

イントロ

みなさま、画像の管理はどのようにされていますか?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 が導入されていること(リバースプロキシサーバー)

手順

  1. compose.ymlを作成します。

    domain.tldは自分の環境に合わせて変更してください。
    機能が多すぎてややこしいのですが、https://ente.domain.tldはバックエンド、https://pics.domain.tldがフロントエンドになります。
    その他、アルバムやアカウント管理、認証、キャスト機能などもあるので、各URLを確認してください。

    compose.yml
    services:
      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
    
  2. museum.yamlを作成します。

    初期は空白でいいです。Enteのアカウント作成後、デフォルトで10GBの制限があります。CLIによる容量無制限化の設定を行うことで100TBまでの拡張が行われます。
    その際のAdminユーザーのIDを入力するのがこのファイルです。(ドキュメント上では他にもs3の設定などが必要ですが全て.envで設定します)

    museum.yaml
    # internal:
    #   admins:
    #     - <USER ID>
    
  3. .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=""
    
  4. Docker Composeで起動します。

    docker compose up -d
    
  5. ブラウザでhttps://pics.domain.tldにアクセスし、アカウントを作成します。

    なお、バックエンドはhttps://ente.domain.tldになります。
    細かいことはドキュメントを確認してください。

Enteの感想

  • 良いところ
    • エンドツーエンド暗号化でプライバシー重視の写真管理
    • セルフホストS3に対応しており、クラウドにバックアップなどの管理も可能
    • 機械学習の機能があり、写真の整理が容易(写真に対してレシートやスクリーンショット、ミーム、ペットなど様々なラベルをつけてくれる)
  • 不満・使いこなせていないところ
    • Adminによる操作はCLIベース
    • 細かいストレージの制御が効かない

以上、Enteの紹介でした。

なお、Enteは2FAのアプリも出しており、Ente authにも大変お世話になっております。
こちらも興味があればぜひ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?