First-Time Dev Environment Setup
Run this once. After completion, switch to the dev-lifecycle skill for daily development.
1. System Dependencies
Verify these tools are installed:
python3 --version # 3.12+
uv --version # Python package manager
gh --version # GitHub CLI (optional, for PR/issue ops)
docker --version # Container builds + Kind cluster
kind --version # Local K8s cluster (sandbox dev only)
kubectl version --client # K8s CLI
helm version --short # Helm chart deployment
hurl --version # E2E testing (HTTP request runner)
Install missing tools (macOS):
curl -LsSf https://astral.sh/uv/install.sh | sh
brew install kind kubectl helm hurl
2. Install Repo Dependencies
make install
This installs Python dependencies with uv, installs web dependencies with pnpm, and configures git hooks.
3. Configure Database (Neon)
The project uses Neon Serverless PostgreSQL — no local Postgres needed.
For local API development (make dev-api), start from:
cp .env.example .env
Edit .env and set at least:
TREADSTONE_DATABASE_URL=postgresql+asyncpg://neondb_owner:xxx@ep-xxx.ap-southeast-1.aws.neon.tech/neondb?sslmode=require
TREADSTONE_JWT_SECRET=CHANGE_ME
The URL scheme must be postgresql+asyncpg:// (not postgresql://). Keep ?sslmode=require.
For local Kubernetes deployment (make local), also prepare:
cp .env.example .env.local
Then set:
TREADSTONE_DATABASE_URL=postgresql+asyncpg://...
TREADSTONE_JWT_SECRET=CHANGE_ME
TREADSTONE_LEADER_ELECTION_ENABLED=true
4. Apply Database Migrations
make migrate
Expected: INFO [alembic.runtime.migration] Context impl PostgresqlImpl. with migration details listed.
5. Verify Environment
make test
Expected: all tests pass (integration tests are excluded by default). If tests pass, the environment is ready.
Optional API sanity check:
make dev-api
# In another terminal:
curl http://localhost:8000/health
6. Local K8s Cluster (Sandbox Development)
For sandbox-related features that require a real Kubernetes cluster, follow deploy/README.md — use make local (and make destroy-local to tear down) so the Makefile runs context checks before Helm; smoke testing end-to-end.
Quick start:
kubectl config use-context kind-treadstone # or your Kind context name
make local # One-command: Kind cluster + build + deploy
curl -sf http://api.localhost/health # API via Ingress (Web UI: http://app.localhost)
make test-e2e # default BASE_URL=http://api.localhost
Pure API development (make dev-api) does not require a K8s cluster.
Troubleshooting
uv sync fails:
- Confirm Python 3.12+:
python3 --version - Try:
uv python install 3.12
Database connection fails (could not connect):
- Check the connection string in
.env - Confirm the URL uses
postgresql+asyncpg://notpostgresql:// - Neon free-tier projects auto-suspend; first connection may be slow (~1s cold start)
alembic upgrade head reports authentication failed:
- Confirm
.envexists in the project root - URL-encode special characters in the password
make local fails before app startup:
- Confirm
.env.localexists - Confirm
TREADSTONE_JWT_SECRETis set - Confirm
TREADSTONE_LEADER_ELECTION_ENABLED=truefor the K8s environment - Optional: set
TREADSTONE_PROD_CONTEXTsodestroy-localis refused while kubectl points at prod;make localruns the context check after Kind setup and before Helm (seedeploy/README.md). If Kind already exists but kubectl still points at prod, switch withkubectl config use-context kind-treadstone