Push a nightly sandbox image
Set up a scheduled GitHub Action that builds and pushes your sandbox image every night.
Set up a scheduled GitHub Action that builds your app's image every night and pushes it to Cofactor. Each morning, new sandboxes start from last night's build.
- Fresh every night: a push is the version claims, flow runs and scheduled runs use as soon as it's ready.
- Named: each push is tagged
nightly, plus the date, so you can claim a specific night with--at. - Fails loudly: the job fails if the image doesn't boot in Cofactor.
Copy this prompt and give it to your coding agent (Claude Code, Codex, Cursor). It adds the workflow to your repo and fits it to your build:
Or set it up by hand below.
01Before you start
- A sandbox you already push by hand: a
cofactor.sandbox.yamland a Dockerfile that build a working image. If you don't have one yet, start with Sandboxes from a pushed image. - A Cofactor API key with the scopes
sandbox:read,sandbox:publishandproperty:read(create it in Settings > API Keys; see API Keys).sandbox:readalso lets the key read your sandboxes' persona logins, so treat it like any other CI secret. Save it in your GitHub repository as the secretCOFACTOR_API_TOKEN(Settings > Secrets and variables > Actions).
02Add the workflow
Save this as .github/workflows/cofactor-sandbox-nightly.yml. Replace Acme Tracker with your application's name, and the Dockerfile and definition paths if yours differ. If your Dockerfile needs build args, add them under build-args:.
name: Cofactor sandbox nightly
on:
schedule:
- cron: "0 6 * * *" # 06:00 UTC every day
workflow_dispatch:
permissions:
contents: read
jobs:
push:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- name: Build the image
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
platforms: linux/amd64
load: true
push: false
tags: app:sandbox
cache-from: type=gha
cache-to: type=gha,mode=max
- run: npm install -g @runcofactor/cli
- name: Push to Cofactor
env:
COFACTOR_API_TOKEN: ${{ secrets.COFACTOR_API_TOKEN }}
run: |
cofactor sandbox validate --upload cofactor.sandbox.yaml
cofactor sandbox push --application "Acme Tracker" app:sandbox \
--definition cofactor.sandbox.yaml --tag nightly --tag "$(date -u +%F)" --wait
The build cache keeps nightly pushes small: a push uploads only the layers Cofactor doesn't already have.
03Check that it worked
-
Run it once by hand: Actions > Cofactor sandbox nightly > Run workflow (or
gh workflow run cofactor-sandbox-nightly.yml). -
The push step ends with a line like
Push 3f6c…: ready [nightly, 2026-10-21]. -
Claim last night's build and check the app and its logins:
bashcofactor sandbox claim --application "Acme Tracker" --environment default --at nightly --wait
When you're done, run
cofactor sandbox destroy <id>.
A failed boot fails the job, with the failing service's log in the output. The workflow installs the latest CLI each night, so a sudden failure right after a CLI release can mean the CLI is ahead of the server; rerun it later. See Troubleshooting.