Deploy Element Web
Web client for Matrix, an encrypted and federated chat network
element-web
Just deployed
Deploy and Host Element on Railway
Element is the official web client for Matrix, the open protocol behind decentralised, end-to-end encrypted messaging. It gives a team what they expect from Slack or Discord — rooms, threads, reactions, file sharing, search, voice and video calls — while accounts, history and encryption keys stay on a homeserver you choose. Institutions, universities and open-source communities run it because Matrix federates: people on different homeservers share a room the way people on different mail servers share a thread. Deploy Element on Railway and the client is yours to brand and point wherever you like.
Self-host Element on Railway and the client is a single service, element-web, built from gridalpha/element-railway on the official ghcr.io/element-hq/element-web image: nginx serving the bundle on port 8080 behind Railway's TLS edge, with the security headers upstream's own README asks hosts to send. No database, volume or worker is needed — session, room list and crypto store live in the browser's IndexedDB, everything else on the homeserver. With zero configuration it signs in against matrix.org; MATRIX_HOMESERVER_URL repoints it at any homeserver, including one in the same Railway project.

Getting Started with Element on Railway
Click Deploy, then open the generated *.up.railway.app URL. The first screen is Element's welcome page with Sign in and Create account; there are no default credentials to change, because this service has no accounts of its own — authentication belongs to the homeserver behind it. Out of the box it points at matrix.org, and the Edit link beside the server name aims one session elsewhere. To make it permanent, set MATRIX_HOMESERVER_URL to your homeserver's base URL and redeploy; a bare hostname works, https:// is added for you. ELEMENT_DISABLE_CUSTOM_URLS=true removes the server picker and ELEMENT_BRAND puts your own name in the UI. Signed in, you land on the room list: create a room from the + button (private rooms come up end-to-end encrypted), post a message, then open Explore rooms — together those exercise the bundle, the browser crypto stack and the homeserver connection.

About Hosting Element
Element (formerly Riot) is released under AGPL-3.0 or GPL-3.0. Teams self-host it to control who can read their conversations, to satisfy a policy that rules out hosted chat vendors, or to put the client on their own domain.
- End-to-end encryption by default in private rooms, with device verification, cross-signing and encrypted key backup in the browser.
- Federation — rooms span homeservers, so partners join without an account on yours.
- A full team-chat feature set from the homeserver: spaces, threads, reactions, formatted messages, uploads, search.
- Calls — one-to-one voice and video, plus group conferences through Jitsi (
ELEMENT_JITSI_DOMAIN) or Element Call (ELEMENT_CALL_URL).
The service does two jobs: it serves the compiled client, and at container start it renders the config.json Element reads in the browser from the variables you set — so one image can front matrix.org, your own homeserver or a customer's without a rebuild. ELEMENT_CONFIG_EXTRA_JSON deep-merges a JSON object over that config, covering any option in docs/config.md.
Why Deploy Element on Railway
One service, no supporting infrastructure.
- Deploys with zero configuration and works immediately against matrix.org.
- HTTPS, a public domain and health checks, provisioned for you.
- Point it at your own homeserver with a single environment variable.
- Runs alongside a homeserver in the same project, or on its own.
- Redeploy pulls the current upstream image, with no local Docker work.
Common Use Cases
- A branded client for an existing homeserver — Element on
chat.yourcompany.comwith the server picker disabled, so staff need no other address. - Encrypted chat for a community or project — contributors get a familiar UI on a domain you control, still federated with Matrix.
- A replacement for a hosted chat vendor where the archive must stay on infrastructure you audit.
Dependencies for Element
- element-web — the only service. Built from gridalpha/element-railway on
ghcr.io/element-hq/element-web:latest; serves the client over nginx on port 8080, rendersconfig.jsonfrom your variables at start-up, and answers the/versionhealth check.
No database, cache or object storage is created: Element stores nothing server-side. The homeserver is deliberately not part of this template, so the client can front one you run.
Environment Variables Reference
| Variable | Default | What it does |
|---|---|---|
PORT | 8080 | Port Railway routes to and probes. |
ELEMENT_WEB_PORT | 8080 | Port nginx binds; the image default of 80 is unusable by its user. |
MATRIX_HOMESERVER_URL | matrix.org | Homeserver base URL; a bare hostname works, https:// is added. |
ELEMENT_DISABLE_CUSTOM_URLS | false | true removes the server picker and locks the client to one homeserver. |
ELEMENT_BRAND | Element | Name shown throughout the UI. |
ELEMENT_CONFIG_EXTRA_JSON | {} | JSON deep-merged over the config, for any other documented option. |
MATRIX_SERVER_NAME, ELEMENT_SHOW_REGISTRATION, MATRIX_IDENTITY_SERVER_URL, ELEMENT_DEFAULT_THEME, ELEMENT_PERMALINK_PREFIX, ELEMENT_JITSI_DOMAIN, ELEMENT_CALL_URL, ELEMENT_MAP_STYLE_URL, ELEMENT_SHOW_LABS_SETTINGS, ELEMENT_ENABLE_INTEGRATIONS, ELEMENT_DEFAULT_COUNTRY_CODE and ELEMENT_ROOM_DIRECTORY_SERVERS are available too, with working defaults.
Deployment Dependencies
- Upstream project: github.com/element-hq/element-web (AGPL-3.0 / GPL-3.0)
- Official image:
ghcr.io/element-hq/element-web - Source repository: github.com/gridalpha/element-railway
- Configuration reference: element-web
docs/config.md - A Matrix homeserver — matrix.org by default, or your own
Hardware Requirements for Self-Hosting Element
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 0.1 vCPU | 0.5 vCPU |
| RAM | 128 MB | 512 MB |
| Storage | None | None |
| Runtime | nginx, static bundle | nginx, static bundle |
The server stays near idle however busy the conversations get: encryption, rendering and search happen in each visitor's browser.
Self-Hosting Element
The official image runs anywhere Docker does. This shell command starts it on port 8080 with Element's defaults:
docker run -d --name element-web --restart unless-stopped \
-p 8080:80 ghcr.io/element-hq/element-web:latest
To point it at your own homeserver outside Railway, mount a config.json at /app/config.json:
{
"default_server_config": {
"m.homeserver": { "base_url": "https://matrix.example.com", "server_name": "example.com" }
},
"brand": "Example Chat",
"disable_custom_urls": true
}
On this template you set the same options as environment variables and the container writes that file on every start.
How Much Does Element Cost to Self-Host?
Element is free and open source under AGPL-3.0 or GPL-3.0 and nothing in the client is paywalled; a commercial licence exists for organisations that cannot accept the AGPL. Element's paid products are hosted homeservers and support, neither needed here. On Railway the cost is infrastructure only — one near-idle container plus bandwidth.
FAQ
What is Element? The official web client for Matrix, an open, federated, end-to-end encrypted messaging protocol. Element is the interface; a homeserver provides the accounts, rooms and message history.
What does this Railway template deploy?
One service running the official Element Web image behind nginx, with the client configuration rendered from environment variables at start-up, upstream's recommended security headers, and a /version health check.
Do I need my own Matrix homeserver to use this?
No. With no variables set the client signs in against matrix.org, so it is useful the moment it deploys. Set MATRIX_HOMESERVER_URL when you want your own server.
Why does this template have no database or storage service? Element keeps nothing server-side: sessions, room state and encryption keys live in the browser's IndexedDB, messages and accounts on the homeserver.
How do I connect self-hosted Element to a homeserver in the same Railway project?
Set MATRIX_HOMESERVER_URL to a reference to that service's public domain — browsers reach the homeserver directly, so it needs one.
How do I update my Element deployment to the latest version?
Redeploy from the Railway dashboard: the build pulls the current ghcr.io/element-hq/element-web:latest, and because the client stores nothing on the server there is no migration step.
Template Content
element-web
gridalpha/element-railway