Skip to main content

Operator deploy

If you’re an operator deploying Nightshift for your team, use the single-command deploy script. It provisions a c5.metal, pulls everything from PyPI and GitHub Releases, and starts serving — no repo checkout needed.
./infra/deploy.sh --hostname api.example.com --api-key ns_abc123
Optional flags:
  • --region <region> — AWS region (default: us-east-1)
  • --version <tag> — pin to a specific release (default: latest)
  • --port <port> — backend port (default: 3000)
The script allocates an Elastic IP and prints DNS instructions at the end. Point your hostname’s A record at the Elastic IP, and Caddy provisions TLS automatically. To upgrade an existing deployment:
./infra/upgrade.sh ubuntu@<ELASTIC_IP> --key ~/.ssh/nightshift.pem
./infra/upgrade.sh --version v0.3.0  # reads target from state file

Dev environment setup

For development (requires a local repo checkout):
./infra/dev/setup.sh
For a production deployment with TLS in one step:
./infra/dev/setup.sh --production --hostname api.example.com
This opens ports 80/443, provisions the instance, and runs production.sh on the remote machine to install Caddy + systemd services. See Server for details.

What setup.sh does

1

SSH keypair

Creates (or reuses) the nightshift-dev SSH keypair and saves the .pem to ~/.ssh/nightshift-dev.pem.
2

Security group

Creates (or reuses) a security group locked to your current public IP on port 22. With --production, also opens ports 80 and 443 for Caddy’s auto-TLS.
3

AMI lookup

Finds the latest Ubuntu 22.04 AMI from Canonical.
4

Launch instance

Launches a c5.metal instance (96 vCPUs, 192 GiB RAM, 100 GB gp3 root volume).
5

Bootstrap

Runs a user-data bootstrap script that installs:
  • Firecracker (latest release from GitHub) + jailer binary
  • Linux kernel (vmlinux) from Firecracker CI S3 bucket → /opt/nightshift/vmlinux
  • Ubuntu rootfs converted to ext4 (2 GB sparse) → /opt/nightshift/rootfs.ext4
  • KVM module loaded + /dev/kvm permissions via setfacl + udev rule
  • Python via uv package manager
  • Node.js 22 LTS + Claude Code (npm global)
  • IP forwarding enabled via sysctl
6

Poll for readiness

Polls SSH and waits for /opt/nightshift/.setup-done marker.
7

Write connection details

Writes connection details to infra/dev/.instance.
Metal instances take 5–8 minutes to boot. If setup fails, debug with:
ssh -i ~/.ssh/nightshift-dev.pem ubuntu@<IP> 'tail -50 /var/log/nightshift-setup.log'

Tear down

./infra/dev/teardown.sh
Terminates the instance and removes infra/dev/.instance. The SSH keypair and security group are preserved for next time.