NixOS on AWS, the declarative way. Reference implementation for image-based provisioning.
Also happens to run maintainer-grade AI coding agents. Cybernetic crustacean organisms. Living shell over metal endoskeleton.
This repo solves two problems:
If you're here to learn NixOS-on-AWS patterns, focus on the generic layer. If you're a openclaw maintainer deploying CLAWDINATORs, the specific layer is for you.
┌─────────────────────────────────────────────────────────────────┐ │ CLAWDINATOR LAYER (specific) │ │ Discord gateway · GitHub monitoring · Hive-mind memory · Soul │ ├─────────────────────────────────────────────────────────────────┤ │ NIXOS-ON-AWS LAYER (generic) │ │ AMI pipeline · OpenTofu infra · S3 bootstrap · agenix secrets │ └─────────────────────────────────────────────────────────────────┘
The patterns here work for any NixOS workload on AWS:
nixos-rebuild switch/run/agenix/* on hostsThe opinionated bits for running AI coding agents:
#clawdributors-testCLAWDINATOR-{1..n}.#clawdributors-test.SOUL.md and must be distilled into workspace docs.┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ nixos- │ │ S3 │ │ EC2 │ │ generators │────▶│ (raw img) │────▶│ (AMI) │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ nix build │ launch ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ flake.nix │ │ CLAWDINATOR │ │ + modules │ │ instance │ └──────────────┘ └──────────────┘ │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Discord │ │ GitHub │ │ EFS │ │ gateway │ │ monitor │ │ (memory) │ └──────────┘ └──────────┘ └──────────┘
nixos-generators produces a raw NixOS imagenixos-rebuild switchMost NixOS-on-AWS guides involve:
nixos-rebuild on running instancesThis repo takes a different approach: image-based provisioning only.
We needed AI agents that:
CLAWDINATORs are the result.
If you just want to understand the NixOS-on-AWS pattern, start here.
~/.aws/credentials or env vars)# Clone
git clone https://github.com/openclaw/clawdinators.git
cd clawdinators
# See the NixOS module (the interesting part)
less nix/modules/clawdinator.nix
# See how hosts are configured
less nix/hosts/clawdinator-1.nix
# See the OpenTofu infra
less infra/opentofu/aws/main.tf
# See the bootstrap scripts
ls scripts/
| File | What it teaches |
|---|---|
nix/modules/clawdinator.nix | How to write a NixOS module for a complex service |
scripts/build-image.sh | How to build raw NixOS images |
scripts/import-image.sh | How to import images as AWS AMIs |
infra/opentofu/aws/ | How to wire up S3 + IAM + VM Import |
# 1. Define your NixOS configuration { config, pkgs, ... }: { imports = [ ./modules/your-service.nix ]; services.your-service.enable = true; } # 2. Build a raw image # nix run github:nix-community/nixos-generators -- -f raw -c your-config.nix # 3. Upload to S3 + import as AMI (see scripts/) # 4. Launch with OpenTofu # tofu apply
For openclaw maintainers deploying actual CLAWDINATORs.
nix-secrets repo (agenix keys)# 1. Build the image
./scripts/build-image.sh clawdinator-1
# 2. Upload to S3
./scripts/upload-image.sh dist/nixos.img
# 3. Import as AMI
./scripts/import-image.sh
# 4. Upload bootstrap bundle (secrets + repo seeds)
./scripts/upload-bootstrap.sh clawdinator-1
# 5. Apply OpenTofu
cd infra/opentofu/aws
tofu init
tofu apply
# 6. Instance boots, pulls bootstrap, runs nixos-rebuild switch
# Gateway starts automatically
# Check Discord - CLAWDINATOR should announce itself in #clawdributors-test
# Check GitHub - should see activity in openclaw org repos
CLAWDINATORs update themselves via a systemd timer:
flake lock --update-input nix-openclawnixos-rebuild switchNo human intervention required for routine updates.
Paste this to your AI assistant to help with clawdinators setup/debugging:
I'm working with the clawdinators repo (NixOS-on-AWS + AI coding agents). Repository: github:openclaw/clawdinators What clawdinators is: - Two layers: generic NixOS-on-AWS infra + CLAWDINATOR-specific agent stuff - Image-based provisioning only (no SSH, no drift) - OpenTofu for AWS resources, agenix for secrets - CLAWDINATORs are AI agents that monitor GitHub and respond on Discord Key files: - nix/modules/clawdinator.nix — main NixOS module - nix/hosts/ — host configurations - scripts/ — build, upload, import, bootstrap scripts - infra/opentofu/aws/ — AWS infrastructure - clawdinator/workspace/ — agent workspace templates - memory/ — shared hive-mind templates Secrets are in a separate nix-secrets repo using agenix. What I need help with: [DESCRIBE YOUR TASK]
The clawdinator module exposes these options:
{ services.clawdinator = { enable = true; # Identity instanceName = "clawdinator-1"; # Raw Moltbot config config = { channels.discord = { enabled = true; dm.enabled = false; guilds = { "<GUILD_ID>" = { requireMention = true; channels = { "<CHANNEL_ID>" = { allow = true; requireMention = true; }; }; }; }; }; }; # Providers discordTokenFile = "/run/agenix/discord-bot-token"; anthropicApiKeyFile = "/run/agenix/anthropic-api-key"; openaiApiKeyFile = "/run/agenix/openai-api-key"; # GitHub App githubApp = { enable = true; appId = "..."; installationId = "..."; privateKeyFile = "/run/agenix/github-app-key"; }; # Memory (EFS) memoryEfs = { enable = true; mountPoint = "/var/lib/clawd/memory"; fileSystemId = "fs-..."; region = "eu-central-1"; }; }; }
See nix/modules/clawdinator.nix for all options.
Secrets are managed with agenix:
nix-secrets repo)/run/agenix/* on hosts at boot| Secret | Purpose |
|---|---|
| Discord bot token | Gateway authentication |
| Anthropic API key | Claude models |
| OpenAI API key | GPT/Codex models |
| GitHub App private key | Short-lived installation tokens |
| agenix host key | Decryption on the instance |
The bootstrap service downloads these from S3 at first boot:
s3://bucket/bootstrap/clawdinator-1/ ├── secrets/ # agenix-encrypted files ├── repos/ # git repo seeds └── config.json # instance metadata
clawdinators/ ├── nix/ │ ├── modules/ │ │ └── clawdinator.nix # Main NixOS module │ ├── hosts/ │ │ └── clawdinator-1.nix # Host configuration │ └── examples/ # Example configs for learners ├── infra/ │ └── opentofu/ │ └── aws/ # S3 + IAM + VM Import + EC2 ├── scripts/ │ ├── build-image.sh # Build raw NixOS image │ ├── upload-image.sh # Upload to S3 │ ├── import-image.sh # Import as AMI │ ├── upload-bootstrap.sh # Upload secrets + seeds │ ├── mint-github-app-token.sh │ ├── memory-read.sh # Shared memory access │ ├── memory-write.sh │ └── memory-edit.sh ├── clawdinator/ │ └── workspace/ # Agent workspace templates │ ├── AGENTS.md │ ├── SOUL.md │ ├── IDENTITY.md │ └── skills/ ├── memory/ # Hive-mind templates │ ├── project.md │ ├── ops.md │ └── discord.md ├── docs/ │ ├── PHILOSOPHY.md │ ├── ARCHITECTURE.md │ ├── SHARED_MEMORY.md │ └── SECRETS.md └── flake.nix
| Repo | Role |
|---|---|
| openclaw | Upstream runtime + gateway |
| nix-openclaw | Nix packaging for clawbot |
| clawhub | Public skill registry |
| ai-stack | Public agent defaults + skills |
Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it.
MIT - see LICENSE
A note on commercial use: Please do NOT make a commercial service out of this. That would be very un-br00tal. Clawdbot should stay fun and open — commercial hosting ruins the vibe. Yes, the license permits this, but that doesn't mean the community will like you if you do it.