# Temps Platform Setup

> |

- **Type:** Skill
- **Install:** `agentstack add skill-gotempsh-temps-temps-platform-setup`
- **Verified:** Pending review
- **Seller:** [gotempsh](https://agentstack.voostack.com/s/gotempsh)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [gotempsh](https://github.com/gotempsh)
- **Source:** https://github.com/gotempsh/temps/tree/main/skills/temps-platform-setup
- **Website:** https://temps.sh/docs

## Install

```sh
agentstack add skill-gotempsh-temps-temps-platform-setup
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Temps Platform Setup & Management

Complete guide for installing and managing the Temps self-hosted deployment platform.

## Table of Contents

- [Overview](#overview)
- [Installation Methods](#installation-methods)
- [Quick Start](#quick-start)
- [CLI Setup](#cli-setup)
- [Initial Configuration](#initial-configuration)
- [Platform Management](#platform-management)
- [DNS & TLS Setup](#dns--tls-setup)
- [Troubleshooting](#troubleshooting)
- [Security Considerations](#security-considerations)

---

## Overview

**Temps** is a self-hosted deployment platform with built-in analytics, monitoring, and error tracking. It deploys any application from Git with zero configuration.

**Key Features:**
- Deploy frontend, backend, and static sites from Git
- Built-in analytics, funnels, session replay
- Error tracking (Sentry-compatible)
- Uptime monitoring
- Automatic TLS certificates via Let's Encrypt
- PostgreSQL, Redis, MongoDB, S3 service provisioning
- Container orchestration with Docker

**Supported Languages:**
- **Frontend**: React, Next.js, Vue, Svelte, Angular
- **Backend**: Node.js, Python, Go, Rust, Ruby, PHP
- **Static**: Hugo, Jekyll, Gatsby
- **Custom**: Any application with a Dockerfile

---

## Installation Methods

### Method 1: Install Script (Recommended)

Download the installer, **review it**, then run it. Piping a remote
script straight into a shell (`curl ... | bash`) executes whatever the
server returns without giving you a chance to inspect it — download to a
file and read it first.

```bash
# 1. Download the installer to a file
curl -fsSL https://temps.sh/deploy.sh -o deploy.sh

# 2. Review it before running (check the URLs it fetches and what it writes)
less deploy.sh

# 3. Run it once you're satisfied
bash deploy.sh

# 4. Reload shell configuration
source ~/.zshrc  # or ~/.bashrc for bash users
```

**What it does:**
- Downloads the latest Temps binary
- Installs to `~/.temps/bin/`
- Adds to PATH in your shell configuration
- Verifies installation

**Verify installation:**
```bash
temps --version
```

### Method 1b: Headless / AI-agent install

When an AI agent (or any non-interactive/CI context) wants to spin up a
throwaway Temps instance to try it out, run `deploy.sh` with `--yes`: every
confirmation takes its default answer, value prompts are answered by flags,
and the run ends with a machine-readable JSON result. Without a terminal
and without `--yes`, the script fails fast at the first prompt with
guidance (it never hangs waiting for input that can't arrive).

```bash
# Local-only instance on this machine (127.0.0.1.sslip.io, HTTP, no domain).
# Download first (same rule as Method 1 — never pipe a remote script into a
# shell), then run.
curl -fsSL https://temps.sh/deploy.sh -o deploy.sh
bash deploy.sh --mode local --yes

# On a server with a public IP, use quick mode instead. It requires --email
# (the Let's Encrypt contact address — ACME has no fallback):
bash deploy.sh --mode quick --email you@example.com --yes

# Read the structured result (console URL, admin creds, API key):
cat ~/.temps/setup-result.json
```

The final stdout line carries the same JSON, so it can be harvested from
command output without knowing the file path:

```
::temps:result:: {"status":"ok","mode":"local","channel":"beta","console_url":"http://console.127.0.0.1.sslip.io:8080","apps_url_pattern":"http://.127.0.0.1.sslip.io:8080","domain":"127.0.0.1.sslip.io","admin_email":"admin@127.0.0.1.sslip.io","admin_password":"...","api_key":"tk_..."}
```

**Result fields:** `status`, `mode`, `channel`, `console_url`,
`apps_url_pattern` (with a `` placeholder), `domain`,
`admin_email`, `admin_password`, `api_key` (minted for headless installs;
`null` otherwise). The file is written with mode 0600 — treat it as a
secrets file.

**Flags for agents:**
- `--mode local` — this machine, loopback sslip.io, HTTP (default headless mode)
- `--mode quick` — server with a public IP, public sslip.io domain
- `--yes` / `-y` / `--non-interactive` — accept every confirmation's default
  answer (required for headless — it is NOT auto-enabled)
- `--email ` — Let's Encrypt contact + admin login email; required
  with `--yes` in quick mode
- `--domain ` — pre-answer the domain prompt (advanced mode)
- `--channel beta` — install a prerelease binary

After setup, the agent can immediately deploy using the returned `api_key`:

```bash
API_KEY=$(jq -r .api_key ~/.temps/setup-result.json)
API_URL="$(jq -r .console_url ~/.temps/setup-result.json)/api"
bunx @temps-sdk/cli configure set apiUrl "$API_URL"
bunx @temps-sdk/cli login --api-key "$API_KEY"
```

> Advanced/manual-DNS mode is **TTY-only** — it needs interactive DNS-record
> entry. Agents must use `--mode local` or `--mode quick`.

### Method 1c: Remote server over SSH (e.g. a fresh Hetzner VPS)

When the target is a remote machine you can already reach over SSH — a
Hetzner Cloud VPS, a DigitalOcean Droplet, any Ubuntu/Debian box — run the
same installer through SSH from your workstation. `ssh host 'bash ...'`
provides no TTY, so run it headless exactly like Method 1b — `--email` plus
`--yes` — and it writes the same machine-readable result. (Any prompt that
would need a terminal fails fast with guidance instead of hanging.)

**Prerequisites:**

- SSH access as `root` or a sudo-capable user, with key-based auth (e.g. the
  SSH key you attached when provisioning the Hetzner server)
- Ubuntu/Debian recommended; 3 vCPU / 4 GB RAM is the reference footprint
  (Hetzner cpx22)
- Inbound ports **80** and **443** open in the cloud firewall (Hetzner Cloud
  → Firewalls), plus 22 for SSH
- No separate managed database needed — the installer sets up Docker and a
  TimescaleDB container on the server itself

**Steps:**

```bash
SERVER=root@

# 1. Verify connectivity (key auth only, fail instead of prompting)
ssh -o BatchMode=yes "$SERVER" 'echo ok'

# 2. Download the installer locally and review it (same rule as Method 1 —
#    never pipe a remote script into a shell)
curl -fsSL https://temps.sh/deploy.sh -o deploy.sh
less deploy.sh

# 3. Copy the reviewed script to the server and run it headless
scp deploy.sh "$SERVER":/tmp/deploy.sh
ssh "$SERVER" 'bash /tmp/deploy.sh --mode quick --email you@example.com --yes'

# 4. Read the structured result (console URL, admin creds, API key) in place —
#    avoid copying the secrets file to your machine
ssh "$SERVER" 'cat ~/.temps/setup-result.json'
```

`--mode quick` publishes the console at `https://console..sslip.io`
using the server's public IP — no DNS records required to get started. The
console and apps get real Let's Encrypt certificates automatically via
on-demand TLS (the installer falls back to HTTP if the certificate manager
can't activate, e.g. when port 80/443 isn't reachable — the result JSON
carries whichever scheme is live).

**Point your local CLI at the new instance:**

```bash
RESULT=$(ssh "$SERVER" 'cat ~/.temps/setup-result.json')
bunx @temps-sdk/cli configure set apiUrl "$(printf '%s' "$RESULT" | jq -r .console_url)/api"
bunx @temps-sdk/cli login --api-key "$(printf '%s' "$RESULT" | jq -r .api_key)"
bunx @temps-sdk/cli projects list   # smoke test
```

**Which modes work over SSH:**

| Mode | Over SSH | What you get |
|------|----------|--------------|
| `quick` | Plain `ssh`, headless: `--email  --yes` | Console at `https://console..sslip.io` (on-demand TLS) — zero DNS setup |
| `advanced` | `ssh -t` (interactive wizard); `--domain`/`--email` pre-answer its prompts | Your own domain + wildcard Let's Encrypt certificate |
| `local` | Not useful remotely | Binds `127.0.0.1.sslip.io` — only reachable from the server itself |

**Advanced mode over SSH (custom domain + wildcard TLS):**

The advanced wizard is interactive, so force a TTY with `-t`. Pass
`--domain` and `--email` to pre-answer its value prompts — the wizard then
only stops where a human is genuinely needed. Running it inside `tmux` on
the server protects the wizard if your SSH connection drops mid-run:

```bash
ssh -t "$SERVER" 'tmux new -A -s temps-setup \
  "bash /tmp/deploy.sh --mode advanced --domain yourdomain.com --email you@example.com"'
```

With both flags supplied, what remains interactive is the **manual DNS-01
challenge** (by design — it proves you control the domain): the wizard
prints `_acme-challenge.` TXT values for you to add at your DNS
provider, waits for you to press Enter, and validates once they propagate
(it retries up to 5 times, so propagation delays are fine — keep the
session open while you edit DNS). It also reminds you to add the A records
(`` and `*.` → the server's public IP) that route traffic
to the instance. The admin email/password prompts default to `--email` and
a generated password, so Enter accepts them.

Do not combine `advanced` with `--yes` — the DNS-01 pause cannot be
auto-answered, and the script will say so and exit.

Alternatively, start with `quick` to get running immediately and attach a
real domain later with `bunx @temps-sdk/cli domains add --domain
yourdomain.com` followed by `domains verify`.

**Security notes:**

- `setup-result.json` contains the admin password and an API key — treat it
  as a secrets file. Read it over SSH as shown rather than downloading it,
  and never paste its contents into logs, chat, or committed files.
- Keep SSH host-key checking on (no `StrictHostKeyChecking=no`). Connect
  once interactively to accept the fingerprint, or pre-seed `known_hosts`
  from your provider's console.
- Later upgrades run the same way: `ssh "$SERVER" '~/.temps/bin/temps
  upgrade'` (the explicit path matters — non-interactive SSH shells may not
  source the rc file that puts `~/.temps/bin` on `PATH`).

### Method 2: Docker Compose (Production)

For production deployments with PostgreSQL and Redis:

```bash
# Clone the repository
git clone https://github.com/gotempsh/temps.git
cd temps

# Start with Docker Compose
docker-compose up -d
```

**Docker Compose includes:**
- Temps application server
- PostgreSQL 18 + TimescaleDB
- Redis for caching
- Automatic health checks
- Volume persistence

**Access the application:**
- API: http://localhost:3000 (TLS on 3443)
- Console: http://localhost:9000 (the Docker Compose console port)

### Method 3: From Source (Development)

```bash
# Prerequisites: Rust 1.70+, PostgreSQL, Bun
git clone https://github.com/gotempsh/temps.git
cd temps

# Build Rust backend
cargo build --release --bin temps

# Build web console (optional)
cd web
bun install
RSBUILD_OUTPUT_PATH=../crates/temps-cli/dist bun run build
cd ..

# Run migrations and start
./target/release/temps serve \
  --database-url "postgresql://user:pass@localhost:5432/temps"
```

---

## Quick Start

### 1. Start PostgreSQL Database

Temps requires **PostgreSQL 14+ with TimescaleDB extension**.

**Using Docker (easiest):**

```bash
# Create persistent volume
docker volume create temps-postgres

# Start PostgreSQL + TimescaleDB
docker run -d \
  --name temps-postgres \
  -v temps-postgres:/home/postgres/pgdata/data \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=temps \
  -e POSTGRES_DB=temps \
  -p 16432:5432 \
  timescale/timescaledb-ha:pg18
```

**Connection string:**
```
postgresql://postgres:temps@localhost:16432/temps
```

### 2. Run Temps Setup

The setup command initializes the database, creates admin user, and configures DNS/TLS:

> **Credential safety:** the placeholders below (``,
> ``, …) are not real values — replace them with
> your own. Secrets passed as command-line arguments are recorded in your
> shell history (`~/.bash_history`, `~/.zsh_history`) and are visible to
> any user who can run `ps` while the command runs. Prefer exporting them
> as environment variables (see below) or letting `temps setup` prompt
> for them interactively.

```bash
# Export secrets first so they don't land in shell history / process args.
# `temps setup` reads these env vars when the matching flag is omitted.
export GITHUB_TOKEN=""
export CLOUDFLARE_API_TOKEN=""

temps setup \
  --database-url "postgresql://postgres:@localhost:16432/temps" \
  --admin-email "your-email@example.com" \
  --wildcard-domain "*.yourdomain.com" \
  --dns-provider "cloudflare"
  # --github-token / --cloudflare-token are read from the exported
  # GITHUB_TOKEN / CLOUDFLARE_API_TOKEN env vars above. Omit the flags
  # entirely (and don't export) to have temps setup prompt interactively.
```

**Setup options:**

Each secret-bearing flag also reads from an environment variable (shown
below) when the flag is omitted — prefer the env var so the secret never
appears in shell history or `ps` output:

| Option | Description | Required | Env var fallback |
|--------|-------------|----------|------------------|
| `--database-url` | PostgreSQL connection string | ✅ Yes | `TEMPS_DATABASE_URL` |
| `--admin-email` | Admin user email | ✅ Yes | — |
| `--wildcard-domain` | Domain for deployments (e.g., `*.temps.sh`) | Optional | — |
| `--github-token` | GitHub personal access token | Optional | `GITHUB_TOKEN` |
| `--dns-provider` | DNS provider (`cloudflare`, `route53`, `digitalocean`) | Optional | — |
| `--cloudflare-token` | Cloudflare API token | If using Cloudflare | `CLOUDFLARE_API_TOKEN` |
| `--aws-access-key-id` | AWS access key | If using Route53 | `AWS_ACCESS_KEY_ID` |
| `--aws-secret-access-key` | AWS secret key | If using Route53 | `AWS_SECRET_ACCESS_KEY` |
| `--digitalocean-token` | DigitalOcean API token | If using DigitalOcean | `DIGITALOCEAN_API_TOKEN` |

**What setup does:**
1. Runs database migrations
2. Installs TimescaleDB extension
3. Creates the admin user with an **auto-generated password** (printed once — save it)
4. Configures DNS provider for automatic DNS records (when `--dns-provider` is given)
5. Sets up Let's Encrypt ACME account for TLS certificates (unless `--skip-ssl`)
6. Creates encryption keys for secure storage
7. Displays the admin email and password (save these!)

> Setup creates an admin **email + password**, not an API token. You log into
> the console with that email/password. Mint an API key/token afterward with
> `temps apikeys create` or `temps tokens create` (see the
> [temps-cli skill](../temps-cli/SKILL.md)).

### 3. Start Temps Server

```bash
temps serve \
  --database-url "postgresql://postgres:temps@localhost:16432/temps" \
  --address 0.0.0.0:80 \
  --tls-address 0.0.0.0:443 \
  --console-address 0.0.0.0:8081
```

**Server options:**

| Option | Description | Default | Environment Variable |
|--------|-------------|---------|---------------------|
| `--address` | HTTP API address | `127.0.0.1:3000` | `TEMPS_ADDRESS` |
| `--tls-address` | HTTPS address (proxy) | - | `TEMPS_TLS_ADDRESS` |
| `--console-address` | Admin console address | random localhost port¹ | `TEMPS_CONSOLE_ADDRESS` |
| `--database-url` | PostgreSQL URL | - | `TEMPS_DATABASE_URL` |
| `--data-dir` | Data directory | `~/.temps` | `TEMPS_DATA_DIR` |
| `--disable-https-redirect` | Serve HTTP without redirecting to HTTPS | off | - |

> ¹ When `--console-address` is omitted, the console binds to a **random
> localhost port** (printed at startup). `8081` is not a built-in default — it's
> the value the installer (`deploy.sh`) passes explicitly. Docker Compose uses
> `9000`. Pass `--console-address` to pin a port.

**Access points** (with the example invocation above):
- **API**: http://localhost:3000 or https://yourdomain.com
- **Console**: http://localhost:8081 (admin UI — the port you passed)
- **Deployments**: https://app-name.yourdomain.com (auto-generated)

### 4. Access the Console

Open the console in your browser:

```bash
# If running locally (use the console port you configured, or the one printed at startup)
open http://localhost:8081

# If running on server with domain
open https://temps.yourdomain.com
```

**First login:**
- **Email**: the admin email from setup (e.g. the one you passed, or `admin@…` in `--auto`)
- **Password**: the auto-generated admin password `temps setup` printed (check terminal output)

---

## CLI Setup

The Temps CLI

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [gotempsh](https://github.com/gotempsh)
- **Source:** [gotempsh/temps](https://github.com/gotempsh/temps)
- **License:** Apache-2.0
- **Homepage:** https://temps.sh/docs

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-gotempsh-temps-temps-platform-setup
- Seller: https://agentstack.voostack.com/s/gotempsh
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
