Files
PocketVeto/DEPLOYING.md
Jack Levy a96bd024e9 docs: v1.0.0 — full documentation update
- ROADMAP.md: mark all v0.9.8–v0.9.10 items shipped; Phase 4
  accountability features complete; v1.0 criteria all met; update to
  reflect current state as of v0.9.10
- DEPLOYING.md: add SMTP/email section, ENCRYPTION_SECRET_KEY entry,
  fix OPENAI_MODEL default (gpt-4o → gpt-4o-mini), add pocketveto.org
  reference
- UPDATING.md: replace personal git remote with YOUR_GIT_REMOTE
  placeholder for public deployability
- ARCHITECTURE.md: add member_scores table, alignment API, LLM Batch
  API, email unsubscribe, bill tab UI, topic tags constant, Fernet
  encryption pattern, feature history through v0.9.10

Authored by: Jack Levy
2026-03-15 01:10:52 -04:00

241 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Deploying PocketVeto
Step-by-step guide for standing up the full stack on a fresh server.
---
## Prerequisites
**Server:**
- Linux (Ubuntu 22.04+ or Debian 12 recommended)
- Docker Engine 24+ and Docker Compose v2 (`docker compose` — note: no hyphen)
- At least 2 GB RAM (4 GB recommended if running an Ollama LLM locally)
- Port 80 open to the internet (and 443 if you add SSL)
**API keys you will need:**
| Key | Where to get it | Required? |
|---|---|---|
| `DATA_GOV_API_KEY` | [api.data.gov/signup](https://api.data.gov/signup/) — free, instant | **Yes** |
| One LLM key (OpenAI / Anthropic / Gemini) | Provider dashboard | **Yes** (or use Ollama) |
| `NEWSAPI_KEY` | [newsapi.org](https://newsapi.org) — free tier (100 req/day) | Optional |
Google Trends (`pytrends`) needs no key.
---
## 1. Get the code
```bash
git clone https://git.jackhlevy.com/jack/civicstack.git
# (Replace with your own fork URL or download a release from pocketveto.org)
cd civicstack
```
---
## 2. Configure environment
```bash
cp .env.example .env
nano .env # or your preferred editor
```
**Minimum required values:**
```env
# Network
LOCAL_URL=http://YOUR_SERVER_IP # or https://yourdomain.com if behind SSL
PUBLIC_URL= # leave blank unless you have a public domain
# Auth — generate with: python -c "import secrets; print(secrets.token_hex(32))"
JWT_SECRET_KEY=your-generated-secret
# Encryption key for sensitive prefs (generate once, never change after data is written)
ENCRYPTION_SECRET_KEY= # generate: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# PostgreSQL
POSTGRES_USER=congress
POSTGRES_PASSWORD=your-strong-password
POSTGRES_DB=pocketveto
# Redis
REDIS_URL=redis://redis:6379/0
# Congress.gov + GovInfo (shared api.data.gov key)
DATA_GOV_API_KEY=your-api-key
# LLM — pick one
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o-mini
```
Other providers (swap in place of the OpenAI block):
```env
# Anthropic
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_MODEL=claude-sonnet-4-6
# Gemini
LLM_PROVIDER=gemini
GEMINI_API_KEY=AIza...
GEMINI_MODEL=gemini-2.0-flash
# Ollama (local model — server must be running on the host)
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://host.docker.internal:11434
OLLAMA_MODEL=llama3.1
```
Optional extras:
```env
NEWSAPI_KEY=your-newsapi-key # enables richer news correlation
PYTRENDS_ENABLED=true # Google Trends; disable if hitting rate limits
CONGRESS_POLL_INTERVAL_MINUTES=30 # how often to check Congress.gov
```
```env
# Email notifications (optional — requires SMTP relay, e.g. Resend)
SMTP_HOST=smtp.resend.com
SMTP_PORT=465
SMTP_USER=resend
SMTP_PASSWORD=re_your-api-key
SMTP_FROM=alerts@yourdomain.com
```
---
## 3. Build and start
```bash
docker compose up --build -d
```
This will:
1. Pull base images (postgres, redis, nginx, node)
2. Build the API, worker, beat, and frontend images
3. Start all 7 containers
4. Run `alembic upgrade head` automatically inside the API container on startup
5. Seed the Celery Beat schedule in Redis
**First build takes 38 minutes** depending on your server. Subsequent builds are faster (Docker layer cache).
---
## 4. Verify it's running
```bash
docker compose ps
```
All services should show `Up`:
```
civicstack-api-1 Up
civicstack-beat-1 Up
civicstack-frontend-1 Up
civicstack-nginx-1 Up 0.0.0.0:80->80/tcp
civicstack-postgres-1 Up (healthy)
civicstack-redis-1 Up (healthy)
civicstack-worker-1 Up
```
Check the API health endpoint:
```bash
curl http://localhost/api/health
# → {"status":"ok","timestamp":"..."}
```
Open `http://YOUR_SERVER_IP` in a browser.
---
## 5. Create the admin account
Navigate to `http://YOUR_SERVER_IP/register` and create the first account.
**The first registered account automatically becomes admin.** All subsequent accounts are regular users. The admin account gets access to the Settings page with the pipeline controls, LLM switching, and user management.
---
## 6. Trigger initial data load
Log in as admin and go to **Settings**:
1. **Trigger Poll** — fetches bills updated in the last 60 days from Congress.gov (~510 minutes to complete)
2. **Sync Members** — syncs current Congress members (~2 minutes)
The Celery workers then automatically:
- Fetch bill text from GovInfo
- Generate AI briefs (rate-limited at 10/minute)
- Fetch news articles and calculate trend scores
You can watch progress in **Settings → Pipeline Status**.
---
## 7. Optional: Domain + SSL
If you have a domain name pointing to the server, add an SSL terminator in front of nginx. The simplest approach is Caddy as a reverse proxy:
```bash
# Install Caddy
apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update && apt install caddy
```
`/etc/caddy/Caddyfile`:
```
yourdomain.com {
reverse_proxy localhost:80
}
```
```bash
systemctl reload caddy
```
Caddy handles HTTPS certificates automatically via Let's Encrypt.
After adding SSL, update `.env`:
```env
PUBLIC_URL=https://yourdomain.com
```
Then rebuild the API so the new URL is used in notification payloads:
```bash
docker compose up --build -d api
```
---
## Useful commands
```bash
# View logs for a service
docker compose logs --tail=50 api
docker compose logs --tail=50 worker
docker compose logs -f worker # follow in real time
# Restart a service
docker compose restart worker
# Run a database query
docker compose exec postgres psql -U congress pocketveto
# Apply any pending migrations manually
docker compose exec api alembic upgrade head
# Open a Python shell inside the API container
docker compose exec api python
```
---
## Troubleshooting
See `TROUBLESHOOTING.md` for common issues (502 errors after rebuild, wrong postgres user, frontend changes not showing, etc.).