Developer Tools AWS

Atuin on AWS User Guide

| Product: Atuin on AWS

Overview

This image runs Atuin, the self-hosted sync server for magical shell history. The Atuin terminal client records your shell history into an encrypted, searchable database and, with this server, synchronises it across all of your machines. Because history is encrypted end to end with a key that never leaves your own machines, the server only ever stores opaque encrypted records, so your command history stays private on infrastructure you control instead of a third-party service.

The image is delivered as a ready-to-use appliance: postgresql.service, atuin.service and nginx.service are enabled and start on boot, so the moment an engineer connects over SSH the sync backend is already answering. The Atuin server binary is bound to the loopback interface (127.0.0.1:8888) and is fronted by an nginx reverse proxy on port 80, ready for your TLS certificate. There is no web interface — Atuin's client is a terminal tool you run on your own machines.

This appliance is secure by default. Atuin's server normally allows open registration, which would turn a public deployment into an open sign-up service; this image disables open registration, so the server is single-tenant. There is no default password and no baked secret: a unique PostgreSQL password and a per-instance account are generated on the first boot of every instance and written to a root-only credentials file. The shipped security group opens port 22 only, so the sync endpoint is never exposed to the network until you deliberately open port 80 or 443 behind your own access controls.

The PostgreSQL data directory is placed on a dedicated, independently resizable EBS data volume mounted at /var/lib/postgresql, so your encrypted history database grows on durable storage you can expand without touching the boot volume.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
  • The Atuin terminal client installed on the machines whose history you want to sync (see the upstream Atuin documentation)
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Atuin. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation takes a short time after the instance state becomes Running and the status checks pass: the image generates the per-instance database password, rotates the PostgreSQL role, seeds the per-instance account, and starts the Atuin server against it.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Atuin Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --metadata-options "HttpTokens=required" \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=atuin}]'

When the instance state is Running and both status checks pass, note its public or private IP address for the SSH step.

Step 3: Connect over SSH

Connect to the instance with your key pair. The login user depends on the operating system variant you launched.

Connecting to your instance

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/<key-name>.pem ubuntu@<public-ip>

Step 4: Confirm the Services Are Running

The appliance runs three services: postgresql.service (the backing store), atuin.service (the sync server, bound to loopback) and nginx.service (the reverse proxy on port 80). Confirm they are all active and check the Atuin server version.

systemctl is-active atuin nginx postgresql
atuin-server --version
active
active
active
atuin-server 18.17.1

The Atuin server binds only to the loopback interface on port 8888; nginx is the single public listener on port 80, and PostgreSQL listens only on loopback.

sudo ss -tlnp | grep -E '127.0.0.1:8888|:80 |127.0.0.1:5432'

The atuin, nginx and postgresql services all reporting active, the atuin-server binary reporting version 18.17.1, and ss showing nginx listening on port 80 while the atuin server and PostgreSQL are bound to the loopback interface on ports 8888 and 5432

Step 5: Check the Sync API Health

The sync API is served by nginx on port 80 and proxies to the loopback Atuin server. The unauthenticated health endpoint returns HTTP 200 with a JSON status when the server is healthy.

curl -s http://127.0.0.1/healthz
{"status":"healthy"}

Step 6: Read the Per-Instance Credentials

On first boot the image generates a unique per-instance account and PostgreSQL password and writes them to a root-only file. Read them with:

sudo cat /root/atuin-credentials.txt

The file records the sync address, the account username (cloudimg), the account password, and the PostgreSQL password. Point your Atuin client at the ATUIN_SYNC_ADDRESS shown in the file. Keep this file secret and treat the values as sensitive.

Step 7: Connect the Atuin Client and Sync

On each machine whose history you want to sync, install the Atuin terminal client, then set the sync address and log in. Atuin's end-to-end encryption key is generated on your own machine and never leaves it — the server only ever stores opaque encrypted blobs. On your first machine, run atuin key to display the encryption key and store it safely; you supply the same key when logging in on your other machines.

# On the client machine (not the server):
export ATUIN_SYNC_ADDRESS="http://<public-ip>/"
atuin login -u cloudimg -p '<account-password>' -k '<your-encryption-key>'
atuin sync

Your shell history now syncs across every machine you log in from, with fast full-text and contextual search available through the Atuin client. After the first sync, atuin sync runs automatically in the background.

The encrypted shell-history sync round-trip: the health endpoint returns healthy, the account API confirms the per-instance cloudimg user, a history record is pushed with POST /history returning HTTP 200, and the sync count increments confirming the record was stored on the server as an opaque encrypted blob

Step 8: Add More Users (Optional)

The server ships single-tenant with open registration disabled, which is why an unauthenticated registration attempt is refused with HTTP 400. To let additional people register their own accounts, set open_registration = true in /etc/atuin/server.toml and restart the server. Only enable this behind your own network controls, because it lets anyone who can reach the sync endpoint create an account.

sudo sed -i 's/^open_registration = false/open_registration = true/' /etc/atuin/server.toml
sudo systemctl restart atuin.service

Secure by default: an unauthenticated POST to /register is refused with HTTP 400 because open_registration is false in server.toml, the per-instance credentials file is root-only at mode 0600, and the PostgreSQL data directory sits on a dedicated ext4 EBS data volume mounted at /var/lib/postgresql

Step 9: Expose the Sync Endpoint Safely

The Atuin server is fronted by nginx on port 80, but the shipped security group opens port 22 only, so the sync endpoint is not reachable from the network until you open it. To let your machines reach the server, open port 80 (or 443 once you have added TLS) in the instance security group to your trusted network only, and put a TLS certificate in front of it before syncing over the public internet. Because history is already end-to-end encrypted, the server never sees your plaintext, but TLS protects the transport and your session token.

# Example: allow HTTPS from your office network only
aws ec2 authorize-security-group-ingress \
  --group-id <security-group-id> \
  --protocol tcp --port 443 --cidr <your-mgmt-cidr>

Step 10: The History Database and the Data Volume

Atuin stores its encrypted history records in the local PostgreSQL database atuin, whose data directory lives on the dedicated EBS data volume mounted at /var/lib/postgresql. You can back it up with the standard PostgreSQL tools and grow the volume with the standard EBS resize workflow without touching the boot volume.

findmnt /var/lib/postgresql
df -h /var/lib/postgresql
TARGET              SOURCE       FSTYPE OPTIONS
/var/lib/postgresql /dev/nvme1n1 ext4   rw,relatime,nofail

Support

This image is supported 24/7 by cloudimg. For help with Atuin server deployment, connecting the Atuin terminal client and configuring sync, enabling or disabling registration, TLS and reverse-proxy setup, version upgrades, and PostgreSQL backup and administration, contact cloudimg support. Atuin is distributed under the MIT license. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.