---
title: "Deploy Atuin"
description: "Searchable, synced shell history for every machine you work on"
category: "Other"
url: https://railway.com/deploy/atuin
---

# Deploy Atuin

Searchable, synced shell history for every machine you work on

**[Deploy Atuin on Railway](https://railway.com/template/atuin)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/atuin/manifest.json

- **Creator:** A3A
- **Category:** Other

## Template content

### Postgres https://devicons.railway.app/i/postgresql.svg

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

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

- **Source:** https://github.com/gridalpha/atuin-server-railway
- **Health check:** /healthz
- **Public domain:** Yes

## Documentation

# Deploy and Host Atuin Server on Railway

Atuin replaces the shell history in bash, zsh, fish and nushell with a searchable SQLite database that keeps far more than the command text — working directory, exit code, duration, hostname and session — then syncs it between every machine you work on. The sync half is a small Rust service, `atuin-server`, and self-hosting it keeps your command history on infrastructure you control. Deploy Atuin Server on Railway and you get that endpoint without a VPS, a reverse proxy or a TLS certificate.

This template runs two services. `atuin` is the sync API, built from the [gridalpha/atuin-server-railway](https://github.com/gridalpha/atuin-server-railway) source repository on top of the official `ghcr.io/atuinsh/atuin` image; it is the only service with a public URL and it answers every request from your `atuin` CLI. `Postgres` is a Railway-managed PostgreSQL 18 instance on a persistent volume, reachable only over the private network, holding every account and synced record. History is encrypted on your laptop before upload, so what lands in Postgres is ciphertext the server cannot read.

![Diagram of the Atuin sync server and Postgres services on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1788767906/atuin-server-architecture.png)

## Getting Started with Atuin Server on Railway

Deploy the template, pick a username, and let Railway generate the password. On first boot the service creates that account and then closes registration, so the public URL is never an open sign-up page. Open the generated Railway URL in a browser: a JSON body with a Terry Pratchett quotation and the server version is the fastest confirmation the deployment is live.

Everything else happens in your terminal. Install the client, point it at your new server, and log in with the username and password from the service variables:

```
curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh
echo 'sync_address = "https://your-app.up.railway.app"' &gt;&gt; ~/.config/atuin/config.toml
atuin login -u 
atuin import auto
atuin sync
```

`atuin login` asks for an encryption key. On your first machine leave it blank and Atuin generates one; after that, run `atuin key` on a machine already set up and paste the phrase it prints. Losing that phrase means losing the ability to read your own history, so keep it in a password manager. Once `atuin sync` reports records uploaded, press Ctrl-R in a new shell, then repeat the login on a second machine and watch the same commands appear.

![Atuin record index showing synced history and kv counts](https://res.cloudinary.com/rroe4rtk/image/upload/v1788767908/atuin-server-sync-status.png)
![Encrypted PASETO history records stored by the Atuin server](https://res.cloudinary.com/rroe4rtk/image/upload/v1788767909/atuin-server-encrypted-records.png)
![Atuin server index endpoint reporting version 18.21.0](https://res.cloudinary.com/rroe4rtk/image/upload/v1788767910/atuin-server-server-index.png)

## About Hosting Atuin Server

Shell history is one of the most useful datasets a developer owns and one of the worst-managed: capped at a few thousand lines, lost when a terminal crashes, stranded per-machine, holding nothing but the text you typed. Atuin fixes all four, and self-hosting the sync server keeps that dataset — full of hostnames, flags and internal service names — off a third party's infrastructure.

- Full-text search over every command you have run, filtered by directory, host, exit code or session
- End-to-end encryption: records are sealed client-side with PASETO v4; the server stores only ciphertext
- Imports `.bash_history`, `.zsh_history`, fish history or histdb in one command
- Syncs an encrypted key-value store and dotfile aliases alongside history
- bash, zsh, fish and nushell, on macOS, Linux and WSL

The architecture is deliberately small. `atuin` is stateless — it authenticates requests, validates record indices and writes to Postgres — so a redeploy loses nothing. `Postgres` owns all durable state on its volume and is never exposed publicly. The server also publishes Prometheus metrics on a second port only reachable over the private network.

## Why Deploy Atuin Server on Railway

Running the sync server yourself normally means a VM, a database and a TLS story.

- HTTPS, certificates and renewals handled by Railway's edge
- Managed PostgreSQL with backups, provisioned and wired up already
- Your account is created at deploy time; registration stays closed by default
- Private networking between API and database — no public database port
- Redeploys are stateless, so upgrades are one click

## Common Use Cases

- **One history across every machine** — laptop, desktop and remote build boxes searching the same history.
- **Team-scale privacy** — a team that will not put its commands or internal hostnames on a vendor's servers.
- **Recovery for muscle memory** — a rebuilt machine restores years of commands with one `atuin sync`.
- **Finding what actually worked** — exit codes and durations stored beside each command.

## Dependencies for Atuin Server

- **atuin** — `ghcr.io/atuinsh/atuin:18.21`, wrapped by [gridalpha/atuin-server-railway](https://github.com/gridalpha/atuin-server-railway). Serves the sync API on port 8888 and creates the first account at boot.
- **Postgres** — Railway-managed PostgreSQL 18 on a volume, holding users, sessions and encrypted records. Atuin needs PostgreSQL 14+ and checks the version at startup.

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `ATUIN_DB_URI` | PostgreSQL connection string, wired to the `Postgres` service |
| `ATUIN_BOOTSTRAP_USERNAME` | Account created at first boot; letters, digits, hyphens |
| `ATUIN_BOOTSTRAP_PASSWORD` | Password for that account; generated for you at deploy time |
| `ATUIN_OPEN_REGISTRATION` | `false` by default; `true` lets other people sign up |
| `ATUIN_METRICS__ENABLE` | Prometheus exporter on the private network, on port 9001 |
| `ATUIN_MAX_RECORD_SIZE` | Largest single record the server will accept, in bytes |
| `PORT` | Port the API listens on; leave at 8888 |

### Deployment Dependencies

- Source repository: 
- Upstream project: 
- Container image: `ghcr.io/atuinsh/atuin`
- Self-hosting docs: 

## Hardware Requirements for Self-Hosting Atuin Server

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 0.5 vCPU | 1 vCPU |
| RAM | 256 MB API, 256 MB PostgreSQL | 512 MB each |
| Storage | 1 GB volume | 5 GB volume, growing with history |
| Runtime | Prebuilt Rust image, PostgreSQL 14+ | PostgreSQL 18 |

A single user with years of history usually stays under 100 MB in Postgres.

## Self-Hosting Atuin Server

Outside Railway the smallest working setup is the official image plus a PostgreSQL container. The following is a Docker Compose file:

```
services:
  atuin:
    image: ghcr.io/atuinsh/atuin:18.21
    command: start
    ports: ["8888:8888"]
    environment:
      ATUIN_HOST: "0.0.0.0"
      ATUIN_OPEN_REGISTRATION: "true"
      ATUIN_DB_URI: postgres://atuin:atuin@db/atuin
    depends_on: [db]
  db:
    image: postgres:18
    volumes: ["./database:/var/lib/postgresql/"]
    environment:
      POSTGRES_USER: atuin
      POSTGRES_PASSWORD: atuin
      POSTGRES_DB: atuin
```

`ATUIN_OPEN_REGISTRATION` has to be `true` long enough to create your account and should be turned off afterwards; the Railway template does that for you. To build from source instead:

```
git clone https://github.com/atuinsh/atuin &amp;&amp; cd atuin
cargo build --release --bin atuin-server
ATUIN_DB_URI="postgres://..." ./target/release/atuin-server start
```

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

Atuin is MIT-licensed and free, client and server alike, with no paid tier gating self-hosting and no seat count. The project also runs a hosted service, Atuin Hub, for people who would rather not operate a server; self-hosting is a first-class alternative, not a crippled one. On Railway you pay only for the compute and storage the two services use.

## FAQ

**What is Atuin?**
Atuin is an open-source replacement for shell history. It records every command into a local SQLite database with its directory, exit code and duration, gives you fuzzy search bound to Ctrl-R, and optionally syncs that history between machines with end-to-end encryption.

**What does this Railway template deploy?**
Two services: `atuin`, the Rust sync API with a public HTTPS URL, and `Postgres`, a managed PostgreSQL 18 database on a volume holding accounts and encrypted records.

**Why does the template include a PostgreSQL database?**
The sync server keeps no state on disk. Accounts, sessions and every uploaded record live in PostgreSQL, which is what makes the deployment durable and lets the API redeploy losing nothing.

**Can other people register on my self-hosted Atuin server?**
Not unless you allow it — registration is closed once your account is created. Set `ATUIN_OPEN_REGISTRATION` to `true` to invite others, then set it back.

**How do I connect the Atuin CLI to a self-hosted server?**
Set `sync_address` in `~/.config/atuin/config.toml` to your Railway URL, then run `atuin login -u `. Use the same encryption key on every machine; `atuin key` prints it.

**Can the server read my shell history?**
No. Records are encrypted with a key that never leaves your machines, and the server stores and returns opaque ciphertext — which is why losing that key is unrecoverable.

**Which shells and platforms does self-hosted Atuin support?**
bash, zsh, fish and nushell on macOS, Linux and WSL, with prebuilt client binaries for x86_64 and aarch64.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

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