svg

How to Self Host Atuin Server

linux self-hosting atuin

I will quote the official documentation of Atuin:

Atuin replaces your existing shell history with a SQLite database, and records additional context for your commands. With this context, Atuin gives you faster and better search of your shell history. Additionally, Atuin (optionally) syncs your shell history between all of your machines. Fully end-to-end encrypted, of course.

It have been more than a year I use atuin to manage my shell history. It is a great tool to have. I can search my shell history easily and it is synced between my machines. I can’t imagine using shell without it.

Now, I want to show you how to self-host an Atuin server. You might wonder, what happens if the server goes down? Don’t worry, you can still access your shell history locally. By default, Atuin stores your shell history in a local SQLite database. The server is only used for syncing your shell history between your machines.

Even though Atuin is fully end-to-end encrypted, you may still be concerned about your shell history being synced. Rest assured, by default Atuin excludes sensitive data, and you can also customize the exclusion list.

The requirements to self-host an Atuin server are:

  • PostgreSQL
  • Linux server to run the Atuin server

The cheapest option that I have is to use free machine from fly.io: shared-cpu-1x with 256MB RAM. It is more than enough to run Atuin server. For PostgreSQL, I use the free tier from neon.tech, which offers 190 compute hours and 0.5 GB of storage. This is more than sufficient to store my shell history. Since I started using it on 2023-05-25, it has only used 0.18 out of 0.5 GB.

Here’s how to self-host an Atuin server:

  1. Deploy an app on fly.io, you can see my fly.toml for reference:

    app = '<your-fly-app-name>'
    primary_region = 'sin'
    swap_size_mb = 512
    
    [build]
    image = 'ghcr.io/atuinsh/atuin:2ee8801'
    
    [env]
    ATUIN_HOST = "0.0.0.0"
    ATUIN_PORT = "8888"
    ATUIN_OPEN_REGISTRATION = "true" # toggle this to false then redeploy after you have registered. So only you can register new account.
    
    [http_service]
      internal_port = 8888
      force_https = true
      auto_stop_machines = 'stop'
      auto_start_machines = true
      min_machines_running = 0
      processes = ['app']
    
    [[vm]]
    memory_mb = 256
    size = 'shared-cpu-1x'
    
    [processes]
    app = "server start"
  2. Create a PostgreSQL database:

    CREATE DATABASE atuin;
    CREATE USER atuin WITH PASSWORD '<strongpasswordhere>';
    GRANT ALL PRIVILEGES ON DATABASE atuin TO atuin;
  3. Create Fly.io Secret:

    fly secrets set ATUIN_DB_URI='postgresql://atuin:<strongpasswordhere>@<pooler-host-from-neon.tech>.aws.neon.tech/atuin?sslmode=require'
  4. Deploy the app:

    fly deploy --ha=false
  5. Edit ~/.config/atuin/config.toml, update the sync_address to your fly.io app address:

    sync_address = "https://<your-fly-app-name>.fly.dev"
  6. Register your account:

    atuin register

    Keep your secret key safe. You will need it to decrypt your shell history.

  7. Remember to disable the open registration by setting ATUIN_OPEN_REGISTRATION to false in your fly.toml and redeploy the app.

  8. Enjoy your self-hosted Atuin server!