Pull request previews on DigitalOcean

Run each pull request's stagelet on its own droplet in your DigitalOcean account. See what stagely setup creates, the token it needs and the firewalls.

Stagely gives each GitHub pull request a stagelet: a private, running copy of your app. On DigitalOcean, each stagelet runs on its own droplet in your account. You run stagely setup digitalocean once. After that, the customer agent creates a droplet when a pull request deploys, and deletes it when the stagelet ends.

What setup creates

Setup applies a Terraform module with OpenTofu or Terraform. It creates these resources in the region that you choose:

Resource Details
VPC <environment>-stagely, 10.42.0.0/20. The hosts, stagelet machines and build workers join it.
Agent host Droplet <environment>-agent, size s-1vcpu-1gb, Ubuntu 24.04
Gateway host Droplet <environment>-gateway, size s-1vcpu-1gb, Ubuntu 24.04, with a reserved IP
Cloud firewalls One for each host, and one for stagelet machines and build workers, which carry the tag <environment>-stagelet
Container registry DigitalOcean Container Registry with the name in -registry, on the basic tier
SSH key <environment>-stagely-setup, the key that setup uses to install the agent and the gateway
DNS record Only with -dns-domain: an A record for *.<stagelet domain> that points at the gateway’s reserved IP

DigitalOcean allows one container registry in each account. If your account already has one, pass its name in -registry and add -create-registry=false.

Credentials

Setup needs an API token with write access, in DIGITALOCEAN_TOKEN. The token stays on your computer and on the agent host. On the agent host, it is in /etc/stagely/stagely-agent.env, which only root can read. The agent uses the token to create and delete droplets, and to get registry credentials for them. The token never goes to a droplet that runs your app.

Stagelet machines and build workers

  • The agent creates one droplet for each stagelet. Its size is s-2vcpu-4gb. Setup has no flag to change this size.
  • The agent keeps two build workers, also of size s-2vcpu-4gb. They stay when stagelets come and go.
  • Each droplet starts from Ubuntu 24.04, and cloud-init installs Docker at the first boot. With -golden-image, droplets start from a snapshot that already has Docker. The stagely repository has the Packer template for this snapshot.
  • Each droplet joins the VPC. The agent connects to it on its private address over SSH, and accepts only the host key that it gave the droplet.

Registry

Build workers push images to your DigitalOcean Container Registry. Before each build and each start, the agent asks the DigitalOcean API for Docker credentials that expire after two hours. A build worker gets credentials that can push. A stagelet droplet gets credentials that can only pull.

Isolation

  • The firewall of stagelet machines and build workers accepts connections only from the agent host and the gateway host. A stagelet does not accept connections from another stagelet.
  • The agent host accepts only SSH, and only from your -operator-cidr ranges.
  • The gateway host accepts ports 80 and 443 from anywhere, and SSH from your ranges.
  • On each droplet, containers cannot open new connections to the metadata service at 169.254.169.254. This service holds the droplet’s user data, which includes its host key.

Run setup

export DIGITALOCEAN_TOKEN=<token>
stagely login
stagely setup digitalocean \
  -environment production \
  -region fra1 \
  -stagelet-domain stagelets.example.com \
  -registry example-stagely \
  -operator-cidr 203.0.113.7/32 \
  -binaries bin/linux-amd64 \
  -acme-email ops@example.com
Flag Meaning
-region DigitalOcean region, required
-registry Container registry name, required
-create-registry Default true. Set -create-registry=false when the DigitalOcean account already has a registry.
-dns-domain Domain in DigitalOcean DNS that is a parent of the stagelet domain, such as example.com for stagelets.example.com. Setup then adds the DNS record. For any other domain, setup adds no record and prints no reminder to add one.
-golden-image Snapshot id of a golden image for stagelet machines and build workers

Setup also takes the flags that every cloud takes. At the end, it prints the gateway’s reserved IP. Without -dns-domain, point DNS at the gateway yourself.

After setup

  1. Add .stagely.yml to your repository.
  2. Add config values and secrets.
  3. Read the Security model before you add real secrets.