Introduction
L’historique du shell, c’est un peu la mémoire du sysadmin. On y retrouve cette commande magique copiée à 3 h du matin, le one-liner iptables dont on a oublié la syntaxe, ou la ligne ffmpeg qui a enfin fonctionné. Problème : par défaut, cet historique reste prisonnier de chaque machine.
Atuin propose de remplacer l’historique natif de bash/zsh/fish par une base de données locale synchronisable sur un serveur auto-hébergé. Résultat : on retrouve son historique partout, avec recherche fuzzy et chiffrement côté client.
Voici comment déployer son propre serveur Atuin proprement.
Qu’est-ce qu’Atuin ?
Atuin fait deux choses :
- Enrichir l’historique : horodatage, durée d’exécution, code de retour, répertoire de travail, etc.
- Synchroniser entre appareils : via un serveur auto-hébergé, l’historique reste disponible sur toutes les machines.
Toutes les données envoyées au serveur sont chiffrées avec une clé générée localement. Le serveur stocke des blobs chiffrés : sans la clé, il ne peut rien lire.
Pourquoi self-hoster ?
Le service cloud officiel existe et est pratique. Mais si on déjà self-host Nextcloud, Vaultwarden, Immich… autant garder son historique chez soi aussi. Ça élimine la dépendance à un tiers, et ça permet de maîtriser les données.
Le déploiement est simple : une image Docker et une base PostgreSQL.
Déploiement avec Docker Compose
Atuin se déploie facilement en self-hosting avec Docker Compose.
docker-compose.yml
Voici un exemple minimal. Le port est bindé sur 127.0.0.1 pour éviter toute exposition directe sur Internet.
services:
atuin:
image: ghcr.io/atuinsh/atuin:latest
container_name: atuin
restart: unless-stopped
command: server start
environment:
ATUIN_DB_URI: postgres://atuin:${ATUIN_DB_PASSWORD}@db/atuin
ATUIN_DB_USERNAME: atuin
ATUIN_DB_PASSWORD: ${ATUIN_DB_PASSWORD}
ATUIN_HOST: 0.0.0.0
ATUIN_PORT: 8888
ATUIN_OPEN_REGISTRATION: "false"
ATUIN_TLS__ENABLE: "false"
TZ: Europe/Paris
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config:/config
ports:
- 127.0.0.1:8888:8888
networks:
- atuin
db:
image: postgres:18
container_name: atuin-db
restart: unless-stopped
environment:
POSTGRES_USER: atuin
POSTGRES_PASSWORD: ${ATUIN_DB_PASSWORD}
POSTGRES_DB: atuin
volumes:
- /etc/localtime:/etc/localtime:ro
- ./pgdata:/var/lib/postgresql/data
networks:
- atuin
networks:
atuin:
Note sécurité : si vous exposez Atuin sur Internet, faites-le derrière un reverse proxy (Traefik, Nginx, Caddy…) avec TLS. Ne laissez jamais le port 8888 accessible directement depuis l’extérieur.
Variables sensibles : le fichier .env
Le mot de passe de la base de données est injecté via un fichier .env situé à côté du docker-compose.yml :
ATUIN_DB_PASSWORD=un-mot-de-passe-fort
Docker Compose charge automatiquement ce fichier et remplace ${ATUIN_DB_PASSWORD} dans le compose.
Création du premier compte
Avec ATUIN_OPEN_REGISTRATION=false, personne ne peut s’inscrire librement. Pour créer le premier compte, la méthode classique est d’activer temporairement l’inscription ouverte, de créer le compte depuis un client Atuin, puis de refermer.
- Activez l’inscription ouverte dans
.env:
ATUIN_OPEN_REGISTRATION=true
- Recréez le conteneur pour prendre en compte la variable :
docker compose up -d --force-recreate
- Depuis un client Atuin déjà configuré avec
sync_address, créez le compte :
atuin register -u julien -e julien@example.com -p votre-mot-de-passe
- Repassez
ATUIN_OPEN_REGISTRATION=false, recréez le conteneur, et c’est terminé.
La documentation officielle du self-hosting avec Docker détaille cette procédure : https://docs.atuin.sh/self-hosting/docker-setup/
Configuration client : premier appareil
Installez le client sur votre poste :
curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh
Configurez l’adresse du serveur :
mkdir -p ~/.config/atuin
cat > ~/.config/atuin/config.toml <<EOF
sync_address = "https://history.example.com"
EOF
Le compte a été créé côté serveur, mais la clé de chiffrement doit être générée localement. Lancez atuin key avant le premier login :
atuin key
atuin login -u julien -p <mot-de-passe>
atuin sync
Important :
atuin keyaffiche une liste de mots. C’est votre clé de chiffrement. Sauvegardez-la dans votre gestionnaire de mots de passe. Sans elle, vous ne pourrez pas récupérer votre historique.
Ajouter un autre appareil
Sur les machines suivantes, ne générez pas une nouvelle clé avec atuin key. Vous ne pourriez pas lire l’historique déjà synchronisé.
Depuis un appareil déjà configuré, affichez la clé existante :
atuin key
Sur la nouvelle machine, placez cette même clé avant de vous connecter :
mkdir -p ~/.local/share/atuin
# écrire la clé dans ~/.local/share/atuin/key
echo "sync_address = \"https://history.example.com\"" > ~/.config/atuin/config.toml
atuin login -u julien -p <mot-de-passe>
atuin sync
La clé peut aussi être copiée directement depuis ~/.local/share/atuin/key d’une machine vers l’autre, par exemple via votre gestionnaire de mots de passe ou scp.
Intégration au shell
Bash
Ajoutez dans ~/.bashrc :
eval "$(atuin init bash)"
Zsh
Ajoutez dans ~/.zshrc :
eval "$(atuin init zsh)"
Fish
Dans un shell fish, exécutez :
atuin init fish | source
Pour rendre la configuration permanente :
echo "atuin init fish | source" >> ~/.config/fish/config.fish
Rechargez votre configuration ou ouvrez un nouveau terminal.
Utilisation quotidienne
Une fois initialisé, Atuin remplace le rappel de l’historique classique (Ctrl+R) par une interface enrichie :

Ctrl+R: recherche fuzzy dans l’historique.atuin search <terme>: recherche en ligne de commande.atuin sync: synchronisation manuelle.atuin stats: statistiques d’utilisation.
L’historique est chiffré localement avant envoi. Le serveur ne voit que des données opaques.
Conclusion
Atuin est un petit outil qui change la vie quand on vit dans un terminal. Auto-hébergé, il ajoute une brique de plus à un infrastructure personnelle tout en gardant le contrôle sur ses données.
Le seul point de vigilance : la clé de chiffrement. C’est elle qui protège tout votre historique. Perdez-la, et même vous ne pourrez plus rien lire.
