AWS Lightsail Provider
Deploy preview environments to AWS Lightsail instances via SSH.
How it works
- Build: Provisions a Lightsail instance (or reuses the existing one for the PR), waits for it to be fully ready, clones the repo, and runs
docker build. Docker and git are pre-installed via a startup script — no manual setup required. - Deploy: Runs the built Docker image on the same instance. Each PR gets its own dedicated Lightsail instance.
- Delete: Terminates the Lightsail instance and releases all associated resources.
- List: Lists all Lightsail instances tagged
previewops: truefor the repo.
Prerequisites
- An AWS account.
- An IAM user or role with Lightsail permissions.
- An SSH key pair for instance access.
Step 1 — Create IAM credentials
Create an IAM user (or use an existing role) with the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lightsail:CreateInstances",
"lightsail:DeleteInstance",
"lightsail:GetBundles",
"lightsail:GetInstance",
"lightsail:GetInstances",
"lightsail:TagResource"
],
"Resource": "*"
}
]
}
- Go to the AWS IAM console → Users → Create user.
- Give the user a name (e.g.
previewops-lightsail) and click through to Set permissions. - Choose Attach policies directly → Create inline policy → switch to the JSON tab, paste the policy above → Next → save.
- Open the newly created user → Security credentials tab → Create access key.
- Select Application running outside AWS and click through to the confirmation screen.
- Copy both values now — AWS only shows the secret access key once.
| Credential | Where to find it |
|---|---|
AWS_ACCESS_KEY_ID |
Labelled Access key — starts with AKIA… |
AWS_SECRET_ACCESS_KEY |
Labelled Secret access key — only visible on this screen |
Step 2 — Create a dedicated SSH key pair
Generate a new key pair for Previewops:
ssh-keygen -t ed25519 -C "previewops-lightsail" -f ~/.ssh/previewops-lightsail
Register the public key with your Lightsail account:
- Go to the Lightsail console → Account (top-right) → SSH keys.
- Under Custom keys, click Upload key.
- Click Choose File. The
.sshfolder is hidden — use the shortcut for your OS to navigate to it:- macOS: Press
Cmd+Shift+G→ type~/.ssh→ press Enter - Linux: Press
Ctrl+L→ type~/.ssh→ press Enter - Windows: Type
%USERPROFILE%\.sshin the address bar → press Enter
- macOS: Press
- Select
previewops-lightsail.pub, then click Upload key. - Note the name you give the key pair — you will need it in Step 3.
Store the private key content as AWS_SSH_PRIVATE_KEY in Previewops credentials:
cat ~/.ssh/previewops-lightsail # copy the full output including -----BEGIN/END----- lines
Step 3 — Configure the repo
keyPairName is required. All other providerConfig fields are optional:
provider: aws-lightsail
providerConfig:
keyPairName: previewops # required — name of the key pair registered in Step 2
region: us-east-1 # optional (default: us-east-1)
bundleId: micro_2_0 # optional (default: micro_2_0) — instance size
# run: aws lightsail get-bundles --query 'bundles[].bundleId'
blueprintId: ubuntu_22_04 # optional (default: ubuntu_22_04) — OS image
# run: aws lightsail get-blueprints --query 'blueprints[].blueprintId'
Complete example with all options:
# .previewops.yaml
provider: aws-lightsail
providerConfig:
keyPairName: previewops # name of the Lightsail key pair registered in your account
region: us-east-1 # AWS region (default: us-east-1)
bundleId: micro_2_0 # instance size — micro_2_0 ($7/mo, default), small_2_0 ($12/mo), medium_2_0 ($20/mo)
blueprintId: ubuntu_22_04 # OS image (default: ubuntu_22_04)
# Common options — all optional
concurrency: 3 # max simultaneous active previews per repo
ttlHours: 24 # auto-delete after N hours (default: 24)
port: 3000 # optional — auto-detected from your Dockerfile EXPOSE; falls back to 8080
memory: 512Mi # container memory passed to docker run (default: 512Mi)
cpu: 1 # CPU shares passed to docker run (default: 1)
dockerfile: Dockerfile # Dockerfile path relative to repo root (default: Dockerfile)
buildContext: . # Docker build context (default: .)
env:
NODE_ENV: preview # inject env vars into the preview container
Step 4 — Verify
Comment /validate-previewops --provider=aws-lightsail on any open PR. The bot replies with a status dashboard showing:
- BYOC Credentials —
aws-lightsailwith the date it was last updated. .previewops.yaml— theproviderfield and anyproviderConfigkeys you have set.
Example output:
🔍 Credentials & configuration status
BYOC Credentials
Provider Last Updated aws-lightsail2025-01-15
.previewops.yaml
Field Value provideraws-lightsailproviderConfigkeyskeyPairName,region
Instance sizing
Choose a bundle that has enough RAM for your Docker build. Previewops requires at least 1 GB RAM — the nano_2_0 and nano_3_0 bundles (512 MB) are too small and will be rejected before the instance is created.
| Bundle | RAM | CPU | Price (approx) | Suitable for |
|---|---|---|---|---|
micro_2_0 |
1 GB | 2 vCPU | ~$7/mo | Default — most Node/Python/Go apps |
small_2_0 |
2 GB | 2 vCPU | ~$12/mo | Larger builds, Java, multi-stage |
medium_2_0 |
4 GB | 2 vCPU | ~$20/mo | Resource-heavy builds |
Run aws lightsail get-bundles --query 'bundles[].bundleId' to list all available bundle IDs in your region.
Notes
- Instances are provisioned on-demand for each PR and terminated on delete/close.
- First deploy takes ~3 minutes (instance boot + readiness checks).
- Subsequent deploys to the same PR reuse the existing instance (~30 s).
- The preview URL is
http://prev-{org5}-{repo}-pr{N}-aws-lightsail.{ip}.nip.io— a human-readable nip.io hostname that resolves to the instance's public IP ({org5}= first 5 characters of the org name, slugified). No DNS configuration required.
Troubleshooting
| Error | Fix |
|---|---|
| SSH authentication failure / connection refused | Ensure AWS_SSH_PRIVATE_KEY matches the key pair registered in Lightsail for this account |
The KeyPair does not exist: <name> |
Key pairs are region-scoped. Set AWS_REGION (credentials form) or providerConfig.region (.previewops.yaml) to the region where the key pair was registered |
AccessDeniedException: not authorized to perform lightsail:GetBundles |
Add lightsail:GetBundles to the IAM policy (see Step 1) |
AccessDeniedException on any other action |
Ensure all six actions in the Step 1 policy are present on the IAM user |
| SSH connection refused (after instance is running) | Instance hasn't finished booting; the provider waits up to 3 min for readiness automatically |
Instance never reaches running |
Check the AWS Lightsail console for quota limits or region availability |
bundleId nano_2_0 is too small for docker builds |
The selected bundle has less than 1 GB RAM. Change bundleId to micro_2_0 or larger |