Back to TIL
shell

Setting up self-hosted Atuin

I’ve always wanted to give Atuin a shot. It’s a utility that replaces your shell’s history with a rather convenient feature: saving it to a database that can be backed up and synced. End-to-end encrypted, of course. Plus, there’s an option to self-host the sync server component. Also, it records the time it took to run something. Neat!

After hearing about it constantly over the last years, I decided to finally try it. The reason is simple: I rely quite heavily on my shell history for daily tasks. Losing that history due to getting new machines (or crashes), is rather painful. I always forget migrating the history. So, Atuin will act as a backup. Hopefully future-me will thank me for that.

Setup was a quick brew install atuin and following the post-install-instructions.

Importing your existing history

I can’t express how happy I was to discover that Atuin can import your shell’s existing history. I’m an avid fish user, hence my command was:

$ atuin import fish

Update: There’s another TIL where I adjust a setting for Python/Rust.

Self-Hosting Sync

The big benefit of Atuin is not merely the great history and search; it’s that it can sync it off to another machine.

As I do have a tiny server, I wanted to self-host the Atuin sync server. That way, my history would never leave my local LAN. The docs are rather great for self-hosting with Docker. I simply took the docker-compose.yml they offer. Sadly, when spinning it up I saw a lot of this:

Error: could not load server settings

...

Caused by:
    Permission denied (os error 13)

Thankfully, there was a forum post on this simply stating that one has to hardcode the linux user’s id, so that it is allowed to write to your local folder.

Finding your user id:

$ id
1000

Then, adapting the compose-file:

services:
  atuin:
    # Here's my user id
    user: 1000:1000
    restart: always
    image: ghcr.io/atuinsh/atuin:latest
    # ...rest omitted for brevity...
  postgresql:
    # Here's my user id
    user: 1000:1000
    image: postgres:14
    # ...rest omitted for brevity...
  # Note: I also added backups, as explained here https://docs.atuin.sh/self-hosting/docker/#creating-backups-of-the-postgres-database
  backup:
    # Here's my user id
    user: 1000:1000
    container_name: atuin_db_dumper
    image: prodrigestivill/postgres-backup-local
    # ...rest omitted for brevity...

It is said that their Docker image is already built with that ID, but for some weird reason that did not work for me. Putting it explicitly into the file did though.

After that, you have to configure Atuin to use your local server:

$ vim ~/.config/atuin/config.toml

Set the sync_address. In my case, just a fixed IP in my local network:

## address of the sync server
sync_address = "http://10.0.0.1:8888"

(there’s also TLS support, but I decided to not need it because this is local only and encrypted already. yes, still a risk. do not repeat that if you don’t know what you’re doing)

After that, I reopened the shell to make sure that the new Atuin config was loaded and registered on my own server:

$ atuin register -u luis -e [email protected]

Just for testing I triggered a manual sync:

$ atuin sync

Good to go!