Documentation
📋
Before you begin You need your license.json from your purchase email, AWS CLI configured with credentials, and a WireGuard client installed on your machine.

Step 1 — Download the CLI

01

Download for your platform

Go to xeroops.com/download and download the binary for your OS, or use the one-liner:

# Windows (PowerShell — recommended)
irm https://xeroops.com/install.ps1 | iex

# Linux
curl -Lo xeroops https://xeroops.com/downloads/latest/xeroops-linux-amd64
chmod +x xeroops && sudo mv xeroops /usr/local/bin/

# macOS (Apple Silicon)
curl -Lo xeroops https://xeroops.com/downloads/latest/xeroops-darwin-arm64
chmod +x xeroops && sudo mv xeroops /usr/local/bin/

Verify the install:

xeroops
XeroOps CLI v1.0.0
Usage: xeroops <command> [flags]
...

Step 2 — Configure AWS

02

Set up AWS credentials

XeroOps uses your AWS CLI credentials to provision resources. Your license is bound to a specific AWS account — make sure you're configuring the right one.

aws configure
AWS Access Key ID: AKIA...
AWS Secret Access Key: ...
Default region name: us-east-1
Default output format: json

Verify you're in the right account:

aws sts get-caller-identity
{
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/yourname"
}
âš ī¸
Account must match your license The Account value must match the account_id field in your license.json. XeroOps validates this cryptographically and will refuse to run in the wrong account.

Step 3 — Activate Your License

03

Place and activate license.json

Save your license.json attachment from the purchase email to a working directory, then activate:

xeroops activate -license-dir ./license.json
  Validating license signature...    OK
  Verifying AWS account binding...   OK
  Saving encrypted license...        OK
  License activated for: Acme Corp (member)

The activated license is stored at ~/.xeroops/license.enc. You don't need the license.json file again.

Step 4 — Initialize

04

Generate keys, secrets, and load blueprint

xeroops init generates all cryptographic keys (WireGuard, SSH, CloudFront) and every application secret (PostgreSQL password, admin API secrets) automatically — no separate prompt for them. It also copies AMIs to your region if needed. This is the slowest step if AMI copying is required (~5 min).

xeroops init
  Loading license...                 OK
  Checking AMIs in us-east-1...      OK
  Generating WireGuard keypairs...   OK
  Generating SSH keypair...          OK
  Generating CloudFront keypair...   OK
  Generating application secrets...  OK
  Writing deployment config...       OK
  WireGuard client config:           ~/.xeroops/xeroops.conf

You'll be prompted for your AWS region and optionally a domain name (for Route53 DNS) — if you provide one, DNS gets pointed at your load balancer automatically once you deploy. You can also add or change this later with xeroops set-domain.

Step 5 — Create Infrastructure

05

Provision AWS resources and upload config (no EC2 yet)

xeroops create provisions everything except EC2 instances — VPC, subnets, security groups, ENIs, EBS volumes, S3 buckets, IAM roles — then uploads your instance config and generated secrets to the new S3 uploads bucket. Every instance pulls this on boot. Resources here are free or near-free when idle.

xeroops create
  Creating VPC (10.0.0.0/16)...           OK
  Creating subnets...                      OK
  Creating internet gateway...             OK
  Creating route tables...                 OK
  Creating S3 VPC endpoint...             OK
  Creating 9 security groups...           OK
  Importing SSH keypair...                 OK
  Creating IAM role + instance profile... OK
  Creating 4 S3 buckets...                OK
  Creating 7 ENIs with static IPs...      OK
  Creating 2 EBS data volumes...          OK
  Uploading config to S3...               OK
  Infrastructure created. Run verify.

Step 6 — Verify

06

Confirm all resources exist in AWS

xeroops verify
  VPC                  vpc-0abc123...    ✓
  Public Subnet        subnet-0def...    ✓
  Private Subnet       subnet-0ghi...    ✓
  Internet Gateway     igw-0jkl...       ✓
  S3 VPC Endpoint      vpce-0mno...      ✓
  Security Groups      9/9               ✓
  ENIs                 7/7               ✓
  EBS Volumes          2/2               ✓
  S3 Buckets           4/4               ✓
  IAM Role             ✓
  All checks passed.

Step 7 — Deploy

07

Launch your cluster

xeroops deploy
  Pre-flight: checking S3 config...  OK
  Allocating Elastic IPs...          OK
  Launching 7 instances...           OK
  Waiting for db instances...        OK
  Attaching EBS volumes...           OK
  Associating EIPs...                OK
  Updating Route53 DNS...            OK
  Patching WireGuard config...       OK

  ─────────────────────────────────────────
  openresty-lb   10.0.1.10   1.2.3.4 (EIP)
  wireguard      10.0.1.11   5.6.7.8 (EIP)
  app1           10.0.2.10
  app2           10.0.2.11
  management     10.0.2.20
  db1            10.0.2.30
  db2            10.0.2.31
  ─────────────────────────────────────────
  Cluster deployed. Connect via WireGuard.

Step 8 — Set Your Domain

08

Point DNS at your load balancer — TLS follows automatically

If you didn't provide a domain during init, set one now. This finds or creates the Route53 hosted zone and points the domain's A record at your running openresty-lb Elastic IP:

xeroops set-domain yourdomain.com
  Checking Route53 for yourdomain.com...   OK
  App domain set: yourdomain.com (zone Z0...)
  Updating DNS record for yourdomain.com... OK
  yourdomain.com → 1.2.3.4

Once DNS resolves, a Let's Encrypt certificate is issued automatically — no manual certbot command needed. On a fresh boot, or by opening the ops dashboard's "Domain & Let's Encrypt" tab and saving, certbot-setup.service requests and installs the certificate for you. Renewal runs automatically via a systemd timer.

💡
Safe to run any time set-domain works before deploy too — it just saves the domain and lets deploy set the A record once the EIP exists. Run it again later to point at a different domain.

Step 9 — Connect via WireGuard

09

Import VPN config and connect

Your WireGuard client config was generated during init and updated with the real EIP during deploy.

# The config is at:
~/.xeroops/xeroops.conf

# Import into WireGuard client, then connect.
# You now have private network access to all nodes:
ssh app1    # 10.0.2.10
ssh db1     # 10.0.2.30
psql -h 10.0.2.20 -U postgres -d mydb  # via HAProxy
â„šī¸
SSH hostnames are set up for you xeroops deploy writes a managed block to your local ~/.ssh/config mapping each node name (app1, db1, management, etc.) to its private IP, with host-key checking disabled for these internal hosts. You can SSH by name instead of remembering IPs. Re-running deploy refreshes the block without touching the rest of your SSH config.
💡
Open the ops dashboard With WireGuard connected, visit http://10.0.1.10:8080 for the built-in System Command Center — live cluster health, backup verification, log search, and domain/role management. See Architecture for details.

Daily Workflow

After the one-time setup, your daily workflow is just two commands:

# Morning — start the cluster (~60 seconds)
xeroops deploy

# Evening — stop EC2s, keep everything else (free overnight)
xeroops cleanup