---
title: "Deploy Ente"
description: "End-to-end encrypted cloud for your photos and 2FA codes"
category: "Storage"
url: https://railway.com/deploy/ente
---

# Deploy Ente

End-to-end encrypted cloud for your photos and 2FA codes

**[Deploy Ente on Railway](https://railway.com/template/ente)**

- **Creator:** A3A
- **Category:** Storage

## Template content

### cast https://raw.githubusercontent.com/ente/ente/main/web/apps/accounts/public/images/ente-circular.png

- **Image:** ghcr.io/ente/web:latest
- **Health check:** /
- **Public domain:** Yes

### auth https://raw.githubusercontent.com/ente/ente/main/web/apps/auth/public/images/favicon.png

- **Image:** ghcr.io/ente/web:latest
- **Health check:** /
- **Public domain:** Yes

### albums https://raw.githubusercontent.com/ente/ente/main/web/apps/accounts/public/images/ente-circular.png

- **Image:** ghcr.io/ente/web:latest
- **Health check:** /
- **Public domain:** Yes

### photos https://raw.githubusercontent.com/ente/ente/main/web/apps/accounts/public/images/ente-circular.png

- **Image:** ghcr.io/ente/web:latest
- **Health check:** /
- **Public domain:** Yes

### mailpit https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mailpit.svg

- **Image:** axllent/mailpit:latest
- **Health check:** /livez
- **Public domain:** Yes

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgres.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### museum https://raw.githubusercontent.com/ente/ente/main/web/apps/accounts/public/images/ente-circular.png

- **Source:** https://github.com/gridalpha/ente-railway
- **Public domain:** Yes

### accounts https://raw.githubusercontent.com/ente/ente/main/web/apps/accounts/public/images/ente-circular.png

- **Image:** ghcr.io/ente/web:latest
- **Health check:** /
- **Public domain:** Yes

## Buckets

- **ente**

## Documentation

![Ente logo](https://openalternative.co/cdn-cgi/image/width=1024,quality=75,format=avif,metadata=none/https%3A%2F%2Fassets.openalternative.co%2Ftools%2Fclui4lqs9002jpwcvx08v1va8%2Fscreenshot.webp%3Fv%3D1787837319821)

# Deploy and Host Ente on Railway

Ente is an open-source, end-to-end encrypted cloud for the two things people least want a provider to read: their photo library and their two-factor codes. Files, album names and TOTP secrets are encrypted on the device before they leave it, so the server only ever stores ciphertext. Ente Photos is an alternative to Google Photos and iCloud Photos, Ente Auth an alternative to Google Authenticator, and both ship native apps for iOS, Android, macOS, Windows, Linux and the web. Self-host Ente and you keep those clients while owning the storage, database and keys.

Deploy Ente on Railway and the whole stack arrives wired together. **museum** is the Go API server holding accounts, metadata and share links; **photos**, **accounts**, **albums**, **auth** and **cast** are the five web apps, each on its own public URL; **Postgres** stores metadata; a **Railway object storage bucket** holds the encrypted files; and **Mailpit** captures the verification-code emails Ente sends at sign-in. Clients fetch metadata from museum but upload encrypted blobs straight to the bucket through pre-signed URLs, so photo bytes never pass through the API server.

![Diagram of the Ente museum, web app, Postgres and Mailpit services on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1788060185/ente-architecture.png)

## Getting Started with Ente on Railway

Open the **photos** service URL once the deploy is green. There are no default credentials — whoever signs up first becomes the administrator, so click **Signup** and enter an email and password. Ente emails a six-digit verification code, and on a fresh deployment that mail lands in Mailpit: open the **mailpit** URL, sign in with the `MP_UI_AUTH` credentials from that service's variables, and copy the code. Enter it, save the recovery key it shows you — the only way back in if you forget your password — and pick the free plan. In the empty library, press **Upload**, choose a few images and create an album. When the thumbnails render, the round trip works: the browser encrypted the files, sent them to the bucket, then fetched and decrypted them again. Open the album's share panel and choose **Create public link** to check the albums service, then sign in to the **auth** URL to reach Ente Auth. Finally, set `ENTE_INTERNAL_DISABLE_REGISTRATION` to `true` on museum to close signups.

![Ente Photos library showing three uploaded photos and one album](https://res.cloudinary.com/rroe4rtk/image/upload/v1788060187/ente-photos-library.png)

![Ente Photos share panel with a public link enabled for an album](https://res.cloudinary.com/rroe4rtk/image/upload/v1788060189/ente-album-sharing.png)

![Public Ente album link opened by a signed-out visitor](https://res.cloudinary.com/rroe4rtk/image/upload/v1788060190/ente-public-album.png)

## About Hosting Ente

Ente's server is called museum: one Go binary owning accounts, album and file metadata, share links and the pre-signed URLs clients use to read and write objects. It never sees a decryption key, so self-hosting changes who holds the ciphertext, not how the cryptography works. Teams self-host it for a family or organisation library on their own infrastructure, to keep data in a chosen region, or to pay for storage rather than a subscription.

- End-to-end encrypted photo and video backup, with client-side search and albums
- Public album links that stay encrypted — the key rides in the URL fragment, never reaching the server
- Ente Auth: encrypted, synced TOTP codes, importable from Google Authenticator, Aegis and 2FAS
- Collaborative albums with viewer and collaborator roles, plus family sharing
- Cast to a TV or browser with a pairing code and no account on the display device

The web image bundles ten single-page apps on ten ports, each served from the root of its own origin, so every app you expose runs as its own service off that image with a different port. This template runs the five that matter for Photos and Auth; `share`, `embed`, `paste`, `locker` and `memories` add the same way.

## Why Deploy Ente on Railway

Railway removes the parts of self-hosting Ente that are not about photos:

- Managed Postgres and object storage, provisioned and wired in
- HTTPS and a domain per web app, no reverse proxy to configure
- Private networking between museum, Postgres and the mail service
- One-click redeploys and rollbacks when a new image ships
- Usage-based pricing, so an idle family instance costs little

## Common Use Cases

- A private family photo cloud with shared albums, replacing a Google Photos plan
- A team's encrypted 2FA vault, synced across phones and laptops via Ente Auth
- Publishing an event gallery as a password-protected public album link
- Keeping an image archive inside a chosen region

## Dependencies for Ente

- **museum** — the API server, from `ghcr.io/ente/server` plus a small startup wrapper that derives its long-lived keys. Serves the API on port 8080, health-checks at `/ping`.
- **photos, accounts, albums, auth, cast** — `ghcr.io/ente/web`, one service per app, ports 3000 to 3004.
- **Postgres** — `ghcr.io/railwayapp-templates/postgres-ssl:18`, holding users, albums, file metadata and share links. museum runs its migrations at boot.
- **Object storage bucket** — a Railway bucket for encrypted files, thumbnails and derived data.
- **Mailpit** — `axllent/mailpit`, an SMTP sink with a web inbox on a volume, so verification codes are readable before you connect a relay.

### Environment Variables Reference

| Variable | Service | Purpose |
|---|---|---|
| `MUSEUM_SECRET_SEED` | museum | Seeds the email-encryption, hashing and JWT keys. Back it up |
| `ENTE_DB_*` | museum | Postgres host, port, database, user, password, SSL mode |
| `ENTE_S3_B2_EU_CEN_*` | museum | Bucket endpoint, region, name and credentials. `b2-eu-cen` is a fixed key name, not a Backblaze dependency |
| `ENTE_S3_USE_PATH_STYLE_URLS` | museum | Must stay `true` so browser uploads pass CORS preflight |
| `ENTE_APPS_*` | museum | Public URLs of the albums, accounts and cast apps |
| `ENTE_SMTP_*` | museum | Mail host, port and sender. Point at your own relay for real email |
| `ENTE_INTERNAL_DISABLE_REGISTRATION` | museum | Set `true` after your account exists |
| `ENTE_API_ORIGIN` | web apps | Public museum URL, baked into the bundles on every boot |

### Deployment Dependencies

- Source: [github.com/ente/ente](https://github.com/ente/ente) (AGPL-3.0)
- Images: `ghcr.io/ente/server`, `ghcr.io/ente/web`, `axllent/mailpit`
- Docs: [ente.com/help/self-hosting](https://ente.com/help/self-hosting)
- Runtime: Go on Alpine; PostgreSQL 15+; any S3-compatible object store

## Hardware Requirements for Self-Hosting Ente

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB across all services | 2 GB |
| Storage | Postgres volume plus the library in object storage | Grows with the library |
| Runtime | Docker, PostgreSQL, S3-compatible storage | Same, plus an SMTP relay |

museum is light: encryption happens on the client, so it moves metadata and signs URLs rather than transcoding anything.

## Self-Hosting Ente with Docker

Upstream ships a quickstart that writes a Compose file with generated credentials, starting museum, Postgres, MinIO and the web apps:

```
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ente/ente/main/server/quickstart.sh)"
```

To run the published image against your own Postgres and bucket, configure it entirely through `ENTE_*` variables — museum maps `s3.b2-eu-cen.endpoint` in its config file to `ENTE_S3_B2_EU_CEN_ENDPOINT`, and so on for every key:

```
docker run -p 8080:8080 \
  -e ENTE_DB_HOST=postgres -e ENTE_DB_USER=ente -e ENTE_DB_PASSWORD=secret \
  -e ENTE_S3_B2_EU_CEN_ENDPOINT=https://s3.example.com \
  -e ENTE_S3_B2_EU_CEN_BUCKET=ente -e ENTE_S3_USE_PATH_STYLE_URLS=true \
  ghcr.io/ente/server
```

Leave `ENVIRONMENT` unset: `production` loads a profile that writes logs to a file instead of standard output and expects billing data files the published image does not carry.

## How Much Does Ente Cost to Self-Host?

Ente is free and open source under AGPL-3.0, and self-hosting has no licence fee or feature gate — the same server powers the hosted product. Ente's hosted plans start at 10 GB free and run from $2.49/month for 50 GB to $19.99/month for 2 TB, so the real comparison is Railway's usage-based cost for a small API container, Postgres and the storage the library occupies.

## FAQ

**What is Ente?**
An open-source, end-to-end encrypted cloud for photos, videos and two-factor codes, with apps for mobile, desktop and the web and a self-hostable Go server called museum.

**Why does the template include Postgres and object storage?**
museum keeps accounts, album structure and share links in Postgres and stores encrypted photo and video blobs as objects, keeping the database small while the library grows.

**How do I get the verification code when signing in to a self-hosted Ente?**
Ente emails a six-digit code at every sign-in, and this template routes that mail to Mailpit, so read it there. Point the `ENTE_SMTP_*` variables at a real relay to deliver codes to actual inboxes.

**How do I stop strangers from creating accounts on my instance?**
Set `ENTE_INTERNAL_DISABLE_REGISTRATION` to `true` on museum. The API enforces it both when a signup code is requested and when one is verified, so it applies to every client, not just the web app.


## Similar templates

- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.
- [Redis](https://railway.com/deploy/redis-1) — Self Host Latest Redis with Railway
- [EasyImg](https://railway.com/deploy/easyimg) — Simple self-hostable Nuxt.js personal image hosting system.

Open this page in a browser: https://railway.com/deploy/ente
