Set Up CI/CD
Temps deploys automatically on every push. For teams that want tests, linting, or approval gates before deployment, you can add CI/CD workflows that run quality checks first and then trigger Temps deployments.
How deployment triggers work
Temps receives Git webhooks from your provider (GitHub, GitLab). When you push to a branch that matches an environment, Temps starts a deployment automatically.
The default flow:
Push to main → GitHub sends webhook → Temps builds and deploys
This means CI/CD is already built in for the simple case. You only need external CI when you want to add checks before deployment (tests, linting, type checking) or want programmatic control over when deployments happen.
Option 1: Auto-deploy with CI checks
Keep Temps auto-deploy enabled and run CI checks in parallel. Your CI pipeline runs tests while Temps builds and deploys. If tests fail, you know there is a problem — but the deployment still happens.
This is the simplest approach for solo developers or small teams who want fast feedback:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
Temps deploys independently — the CI pipeline provides feedback but does not gate the deployment.
Option 2: CI gates before deploy
Disable auto-deploy on the environment and trigger deployments from CI only after checks pass:
Step 1: Disable auto-deploy
Go to your project > Environments > select the environment > Settings and set Automatic Deploy to off.
When Automatic Deploy is off, Temps stops the Git push pipeline before it does any work: a matching webhook from GitHub or GitLab is received, but Temps logs that auto-deploy is disabled and returns early — no build, container, or rollout is created. This setting is opt-in: if neither the project nor the environment has auto-deploy enabled, push events do not deploy. See How the automatic-deploy flag is resolved below for the exact merge rules and the two exceptions.
How the automatic-deploy flag is resolved
Automatic Deploy is stored as automatic_deploy on the deployment config, and it can be set at both the project and the environment level. When a Git push webhook arrives, Temps computes the effective value by merging the two configs:
| Project flag | Environment flag | Effective auto-deploy |
|---|---|---|
| Not set | Not set | Off (push does not deploy) |
| On | (any) | On |
| (any) | On | On |
| Off | Off | Off |
The environment config combines with the project config using OR-on-booleans (so either level enabling it turns it on), and when neither config exists the result is false. Auto-deploy is opt-in, not opt-out.
This gate runs before any deployment work — before the duplicate-deployment check, before cancelling in-flight deployments, and before queuing the build. When auto-deploy is off, Temps logs an informational message and stops.
Two exceptions bypass the gate and always deploy:
- Manual triggers. The Deploy button and the
trigger-pipelineAPI/CLI are explicit user actions, so they deploy regardless of theautomatic_deploysetting. This is exactly the path used in Step 2 below — disabling auto-deploy never blocks a CI-triggered deploy. - The first deployment for an environment. If an environment has no prior deployments, its first push deploys even when
automatic_deployis off, so a freshly created opt-out project still gets a baseline deployment.
The same gate applies to both GitHub and GitLab webhooks — both providers funnel through the same push pipeline.
Step 2: Trigger deployment from CI
Use the Temps API or CLI to trigger a deployment after your CI checks pass:
name: Test and Deploy
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Trigger Temps deployment
run: |
curl -X POST "$TEMPS_API_URL/api/projects/$PROJECT_ID/trigger-pipeline" \
-H "Authorization: Bearer $TEMPS_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"environment_id\": $ENVIRONMENT_ID, \"branch\": \"main\"}"
env:
TEMPS_API_URL: ${{ secrets.TEMPS_API_URL }}
TEMPS_API_TOKEN: ${{ secrets.TEMPS_API_TOKEN }}
PROJECT_ID: ${{ secrets.TEMPS_PROJECT_ID }}
ENVIRONMENT_ID: ${{ secrets.TEMPS_ENVIRONMENT_ID }}
Step 3: Store secrets in CI
Add these secrets to your CI provider:
| Secret | Value | Where to find it |
|---|---|---|
TEMPS_API_URL | Your Temps instance URL (e.g. https://temps.example.com) | Your server configuration |
TEMPS_API_TOKEN | API token from the Temps dashboard | Settings > API Tokens |
TEMPS_PROJECT_ID | Numeric project ID | Project URL or API |
TEMPS_ENVIRONMENT_ID | Numeric environment ID | Environment settings |
Deploy via the API
If your CI does the build itself, you don't have to make Temps rebuild from source. Temps exposes endpoints to deploy a pre-built Docker image, upload an image tarball, or push a static bundle. Use these when you want CI to own the build step and Temps to own the rollout.
| Method | When to use | API endpoint |
|---|---|---|
| Pre-built Docker image | You build and push to a registry in CI, then tell Temps to deploy it | POST /api/projects/{id}/environments/{id}/deploy/image |
| Docker image upload | You build an image in CI and upload the tarball directly (no registry needed) | POST /api/projects/{id}/environments/{id}/deploy/image-upload |
| Static bundle | You build static files in CI and upload a zip or tar.gz | POST /api/projects/{id}/upload/static then .../deploy/static |
| Git trigger | You want Temps to build from source, but triggered by CI instead of a webhook | POST /api/projects/{id}/trigger-pipeline |
All endpoints require an API token in the Authorization: Bearer header.
Deploy a pre-built Docker image
If your CI pushes an image to a registry (Docker Hub, GitHub Container Registry, etc.), tell Temps to pull and deploy it:
curl -X POST "$TEMPS_API_URL/api/projects/$PROJECT_ID/environments/$ENVIRONMENT_ID/deploy/image" \
-H "Authorization: Bearer $TEMPS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"image": "ghcr.io/your-org/your-app:sha-abc1234"}'
Temps pulls the image, starts a container, runs health checks, and shifts traffic to it. The old container is stopped once the new one is healthy.
Upload a Docker image without a registry
If you don't want to push to a registry, upload the image tarball directly (up to 1 GB):
# Save the image as a tarball in your CI
docker save your-app:latest | gzip > image.tar.gz
# Upload and deploy it
curl -X POST "$TEMPS_API_URL/api/projects/$PROJECT_ID/environments/$ENVIRONMENT_ID/deploy/image-upload" \
-H "Authorization: Bearer $TEMPS_API_TOKEN" \
-F "image=@image.tar.gz"
Deploy a static bundle
For static sites (React, Vue, Astro, etc.) built in CI, upload the build output (tar.gz or zip, up to 500 MB), then deploy it:
# Build in CI, then archive the output
npm run build
tar -czf build.tar.gz -C dist .
# Step 1: upload the bundle
BUNDLE_RESPONSE=$(curl -X POST "$TEMPS_API_URL/api/projects/$PROJECT_ID/upload/static" \
-H "Authorization: Bearer $TEMPS_API_TOKEN" \
-F "file=@build.tar.gz")
# Step 2: trigger the static deployment with the upload response
curl -X POST "$TEMPS_API_URL/api/projects/$PROJECT_ID/environments/$ENVIRONMENT_ID/deploy/static" \
-H "Authorization: Bearer $TEMPS_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$BUNDLE_RESPONSE"
Using the Temps CLI
The Temps CLI provides more control than raw API calls. Install it in your CI environment:
# Install
npx @temps-sdk/cli --help
# Or with bun
bunx @temps-sdk/cli --help
Deploy from Git
Trigger a deployment for a specific branch, tag, or commit:
# Deploy the current branch
temps deploy git --project my-app --environment production
# Deploy a specific commit
temps deploy git --project my-app --environment production --commit abc123
# Deploy a tag
temps deploy git --project my-app --environment production --tag v1.2.3
# Wait for deployment to complete (with timeout)
temps deploy git --project my-app --environment production --wait --timeout 300
Deploy a pre-built image
If your CI builds a Docker image, deploy it directly without rebuilding on Temps:
temps deploy image \
--image ghcr.io/your-org/your-app:latest \
--project my-app \
--environment production \
--wait
Deploy static files
Upload static files from your CI build output:
temps deploy static \
--path ./dist \
--project my-app \
--environment production
Authentication
Set these environment variables for the CLI:
export TEMPS_API_URL=https://temps.example.com
export TEMPS_API_TOKEN=your-api-token
Outbound webhooks
Temps can send deployment event notifications to external systems. Use this to post to Slack, update a status page, or trigger downstream actions.
Setting up
- Go to Settings > Webhooks in your project
- Add a webhook URL (e.g. a Slack incoming webhook URL)
- Select events to listen for
- Optionally set a secret for HMAC signature verification
Available events
| Event | Description |
|---|---|
deployment.created | A deployment was queued |
deployment.succeeded | The deployment completed successfully |
deployment.failed | The deployment failed |
deployment.cancelled | The deployment was cancelled |
deployment.ready | The deployment is live and receiving traffic |
project.created | A new project was created |
project.deleted | A project was deleted |
domain.created | A domain was added |
domain.provisioned | A TLS certificate was provisioned |
Webhook payload
Each webhook delivery includes:
- Project name and ID
- Branch and commit SHA
- Commit message
- Deployment status
- Timestamp
Failed deliveries can be retried from the webhook delivery history in the dashboard.
Rollback
If a deployment introduces a bug, you can roll back:
Automatic rollback
Temps rolls back automatically if the new container fails health checks. The old container keeps running and the route table reverts — no manual intervention needed.
Manual rollback via dashboard
- Go to your project > Deployments
- Find the last working deployment
- Click Rollback to redeploy that version
Git-based rollback
Revert the commit and push:
git revert HEAD
git push origin main
Temps deploys the reverted commit as a new deployment.
Complete example: Next.js with GitHub Actions
.github/workflows/deploy.yml
name: Test and Deploy
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npx tsc --noEmit
- run: npm test -- --ci
deploy:
needs: test
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Deploy to Temps
run: |
curl -X POST "$TEMPS_API_URL/api/projects/$PROJECT_ID/trigger-pipeline" \
-H "Authorization: Bearer $TEMPS_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"environment_id\": $ENVIRONMENT_ID, \"branch\": \"main\", \"commit\": \"${{ github.sha }}\"}"
env:
TEMPS_API_URL: ${{ secrets.TEMPS_API_URL }}
TEMPS_API_TOKEN: ${{ secrets.TEMPS_API_TOKEN }}
PROJECT_ID: ${{ secrets.TEMPS_PROJECT_ID }}
ENVIRONMENT_ID: ${{ secrets.TEMPS_ENVIRONMENT_ID }}