docs: add agent codebase guide

This commit is contained in:
jjbrunton committed 2026-08-09 16:21:57 +01:00
1 parent 742c06d0c4
commit c630303b47
12 files changed
+881 -4483

No files matched your search

+89 -354
View File
@@ -1,397 +1,132 @@
# Deployment Guide
# Deployment and operations
Complete guide for deploying RedditBot in various environments.
## Production model
---
The production unit is the `reddit-bot` Docker Compose service. The image uses the Playwright base, installs/builds the Node application, serves the compiled React dashboard and Express API on port 3000, and stores state under `/app/data` on the named `reddit_bot_data` volume.
## Table of Contents
The container does not run VNC, accept Reddit passwords, or scrape a Matrix token from a login browser. Account authentication enters through a locally exported session dump and is persisted in the sensitive volume.
1. [Prerequisites](#prerequisites)
2. [Local Development](#local-development)
3. [Docker Deployment](#docker-deployment)
4. [Docker Compose](#docker-compose)
5. [Dokploy Deployment](#dokploy-deployment)
6. [Production Considerations](#production-considerations)
7. [Monitoring & Maintenance](#monitoring--maintenance)
8. [Troubleshooting](#troubleshooting-1)
## Authority and safety
---
Deployment, restart, start/resume, session import, configuration mutation, send actions, and data deletion are separate operations. Only perform the ones the user explicitly requested. In particular, “commit and push” does not authorize a Dokploy deployment or bot restart.
## Prerequisites
Before any live operation:
### Required
1. Confirm the target is the RedditBot Compose service, not the whole Dokploy host/instance.
2. Inspect current Git revision, worktree/remote state, deployment state, bot running/paused state, account runtimes, and recent errors.
3. Identify whether the action can send messages or change account state.
4. Back up affected persistent state before destructive or migration-heavy work.
5. Define observable success criteria and a recovery path.
| Requirement | Version | Notes |
|---|---|---|
| Node.js | 20.19+ or 22.12+ | Required by the locked Vite toolchain |
| npm | Bundled with Node | Use `npm ci` for lockfile-exact installs |
| OpenRouter API Key | - | Sign up at [openrouter.ai](https://openrouter.ai) |
| Reddit Account | - | With DM permissions enabled |
## Required environment
### Recommended
The Compose service passes:
| Requirement | Notes |
|---|---|
| 1 GB RAM | Minimum for browser automation |
| 1 CPU core | More for higher message throughput |
| 5 GB disk | For database, media, and browser data |
- `OPENROUTER_API_KEY`;
- `WEB_DASHBOARD_TOKEN`;
- optional `REDDIT_BOT_AGENT_READ_TOKEN`;
- optional `REDDIT_BOT_AGENT_CONTROL_TOKEN`.
---
Dokploy access credentials are stored in the ignored repository `.env`. Use them only when access is explicitly requested. Never print the file, include tokens in commands that will be echoed, commit them, or copy response metadata containing credentials. Follow redirects for Dokploy API calls.
## Local Development
## Persistence
### 1. Clone and Install
`reddit_bot_data:/app/data` contains:
```bash
git clone <repository-url>
cd RedditBot
npm install
```
- SQLite database and WAL files;
- imported browser/account sessions;
- cached Matrix credentials/state;
- downloaded private media;
- per-account browser profiles.
### 2. Configure
A volume replacement or deletion is therefore a destructive account-and-content reset. Verify a readable backup before touching it and state exactly what will be lost. Removing a Compose application and deleting its volume are not the same action.
Create `config.yaml`:
## Deployment procedure
```yaml
reddit:
subreddits:
- gonewild
pollInterval: 15
targetGender: "F"
sellerKeywords:
- seller
- onlyfans
Use the actual current Dokploy API/Compose identifiers from a read-only lookup; do not copy identifiers into documentation or assume an older deployment still has the same ID.
openrouter:
apiKey: "sk-or-v1-your-key-here"
model: "meta-llama/llama-3.2-90b-vision-preview"
fallbackModels:
- "google/gemini-2.0-flash-001"
1. Confirm the intended commit exists on the tracked remote branch.
2. Read current Compose/deployment status and capture the prior image/revision if available.
3. Confirm whether the bot must remain paused through deployment. Do not change persisted running state unless authorized.
4. Trigger the bounded Compose deployment.
5. Poll the deployment record to a terminal success/failure state; an accepted trigger is not completion.
6. Verify the running container is the new deployment and is not restarting.
7. Verify public `GET /healthz` and authenticated `GET /api/v1/readyz`/overview as appropriate.
8. Verify account runtime count/state, bot paused/running state, sync/cooldown state, and recent sanitized logs.
9. Verify the persistent volume is mounted and pre-deployment data is readable.
rateLimit:
minDelayMs: 30000
maxMessagesPerHour: 20
jitterMs: 15000
Do not use a green container health badge as the only evidence. The process may be healthy while account runtimes are logged out, the bot is paused, Matrix is degraded, or candidate/reply work is blocked.
browser:
sessionDir: "./data/browser-session"
dryRun: true
## Health semantics
database:
path: "./data/reddit-bot.db"
- `/healthz`: unauthenticated process liveness only; intentionally reveals no private state.
- `/api/v1/readyz`: authenticated component readiness and degraded authentication state.
- `/api/v1/overview`: consolidated runtime, account, sync, rate-limit, candidate/reply, and recent-error view.
- `/api/stats`, `/api/attention`, `/api/outreach`: operator-level workload detail.
- `/api/events/stream`: realtime signal, not a replacement for snapshot checks.
web:
port: 3000
Success should distinguish:
dryRun: true # Start in dry run mode
```
- process/container running;
- API reachable and authenticated;
- database/volume mounted;
- accounts restored and verified;
- bot intentionally paused or running;
- no crash loop or new high-severity errors;
- requested workload actually completed.
Set environment variables:
## Account session operations
```bash
export OPENROUTER_API_KEY="sk-or-v1-your-key"
export WEB_DASHBOARD_TOKEN="long-random-secret"
export REDDIT_BOT_AGENT_READ_TOKEN="separate-read-secret"
export REDDIT_BOT_AGENT_CONTROL_TOKEN="separate-control-secret"
```
The supported workflow is:
### 3. Import account session
1. Load `extensions/reddit-session-exporter` into the operator's local Chrome.
2. Sign in to Reddit locally and open Reddit Chat.
3. Export a combined Reddit cookie + Matrix session JSON.
4. Upload it through Settings > Access.
5. Wait for both Reddit and Matrix identities to verify and for the matching runtime to be replaced/started.
6. Delete the local export file.
Start the dashboard, then upload a combined Reddit and Matrix dump created by the local Chrome extension. Until both identities verify, account work remains paused.
The dump is a bearer credential bundle. Do not inspect or paste it into logs. An account with one valid half is still unavailable for work.
### 4. Start the Bot
## Incident diagnosis
```bash
# Terminal 1: backend with TypeScript execution
npm run dev
### No new outreach
# Terminal 2: Vite dashboard; proxies /api to port 3000
npm run dashboard:dev
Check, in order: persisted bot running state, the per-account delivery states on Overview, enabled/running account count, full authentication, reply backlog, account send timer/hourly cap, account-specific Matrix cooldown, global Reddit cooldown, candidate funnel counts/reasons, enabled subreddit count, recent intake/screening logs, and OpenRouter failures.
# Production: compile server and dashboard, then start
npm run build
npm start
```
Do not infer “no candidates” from “fetched N posts.” Inspect already processed/contacted, age/gender, seller, expired, AI skip, ready, retry, and rejected counts.
### 5. Access Dashboard
### Conversations appear stale
Open the Vite URL (normally http://localhost:5173) during frontend development.
Production dashboard checks use http://localhost:3000.
Separate Matrix remote acceptance from cached/dashboard visibility. Inspect Matrix identity/whoami, sync cursor/status, last full/delta sync, new event IDs, username enrichment, HTTP conversation snapshot, SSE validation/reconnect, and client query invalidation. A stale dashboard can coexist with a successful remote send.
---
### Reddit 403/429/404
## Docker Deployment
- 429: honor `retryAfterMs` through the shared coordinator and avoid additional account requests.
- repeated/broad 403: treat as a possible service-wide anti-abuse block; inspect successful requests and shared cooldown rather than declaring every subreddit private.
- listing 404: the code disables that configured subreddit persistently.
### Build the Image
### Database problems
```bash
docker build -t reddit-bot .
```
Stop writers if recovery needs file operations. Back up the entire data directory, inspect SQLite `integrity_check`/`foreign_key_check`, WAL state, disk capacity/permissions, migration version, and recent logs. Do not create an empty replacement database over the original.
### Run the Container
## Backup and destructive recovery
```bash
docker run -d \
--name reddit-bot \
-p 3000:3000 \
-v $(pwd)/data:/app/data \
-e OPENROUTER_API_KEY=sk-or-v1-your-key \
-e WEB_DASHBOARD_TOKEN=long-random-secret \
-e REDDIT_BOT_AGENT_READ_TOKEN=separate-read-secret \
-e REDDIT_BOT_AGENT_CONTROL_TOKEN=separate-control-secret \
reddit-bot:latest
```
### Dockerfile behavior
The image is based on the Playwright Jammy image because the remaining
authenticated browser operations need Chromium and its system libraries. It
does not install a display server, VNC, or consumer Google Chrome.
That build produces both `dist/` for the Express server and
`apps/dashboard/dist/` for Vite assets. Port 3000 serves the dashboard/API and
the container starts the Node process directly. This is a single-stage image and retains development dependencies
needed by the current build/runtime layout.
---
## Docker Compose
### docker-compose.yml
```yaml
version: '3.8'
services:
reddit-bot:
build: .
container_name: reddit-bot
ports:
- "3000:3000"
volumes:
- ./data:/app/data
environment:
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
- WEB_DASHBOARD_TOKEN=${WEB_DASHBOARD_TOKEN}
- REDDIT_BOT_AGENT_READ_TOKEN=${REDDIT_BOT_AGENT_READ_TOKEN:-}
- REDDIT_BOT_AGENT_CONTROL_TOKEN=${REDDIT_BOT_AGENT_CONTROL_TOKEN:-}
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
```
### Start with Compose
For routine backups, prefer a volume-level snapshot or a consistent SQLite online backup plus browser/media directories. For a reset:
```bash
# Set environment variables
cp .env.example .env
# Edit .env with your credentials
1. State whether scope is one account, selected content, the RedditBot volume, the Compose application, or the Dokploy instance.
2. Capture and validate a backup.
3. Stop relevant writers.
4. Resolve explicit volume/container/app identifiers with read-only inspection.
5. Perform only the authorized deletion.
6. Recreate/deploy, then verify health, schema, accounts, and persistence.
7. Report what was removed and whether/how it can be restored.
# Build and start
docker compose up -d --build
## Routine checks
# View logs
docker compose logs -f reddit-bot
- Review attention items, failed/retrying candidates, reply backlog age, account authentication, invitation/global cooldowns, model errors/cost, and disk/volume health.
- Review response/image rates only with mature sample counts and by source/strategy/account context.
- Back up before migrations, account resets, or Compose/volume changes.
- Rotate dashboard, agent, OpenRouter, Reddit, and Matrix credentials after suspected exposure.
# Stop
docker compose down
# Restart
docker compose restart
```
---
## Dokploy Deployment
Dokploy is a self-hosted platform for deploying applications. See `DOKPLOY_DEPLOY.md` for detailed instructions.
### Quick Start
1. **Create Application**: In Dokploy dashboard, create a new Docker application
2. **Set Environment Variables**:
- `OPENROUTER_API_KEY`
- `WEB_DASHBOARD_TOKEN`
3. **Mount Volume**: Mount `./data` for persistent storage
4. **Set Port**: Map container port 3000 to host port
5. **Deploy**: Push to repository and trigger deployment
### Dokploy Configuration
```yaml
# Dokploy-specific settings
app:
type: docker
repository: <your-repo>
branch: main
dockerfilePath: Dockerfile
environment:
OPENROUTER_API_KEY: $OPENROUTER_API_KEY
WEB_DASHBOARD_TOKEN: $WEB_DASHBOARD_TOKEN
ports:
- container: 3000
host: 3000
volumes:
- source: reddit-bot-data
target: /app/data
type: bind
restartPolicy: unless-stopped
```
---
## Production Considerations
### Security
1. **Network Isolation**: Keep the dashboard on a trusted network during the
migration cutover
2. **Environment Variables**: Never commit credentials; use secrets management
3. **Dashboard Access**: Authenticated Express hosting for React assets, API,
SSE, debug routes, and private media is a required cutover gate, not a
currently proven guarantee
4. **Browser Data**: Protect `data/browser/` directory
### Performance
1. **Account dumps**: Delete downloaded dumps after the dashboard verifies them
2. **WAL Mode**: SQLite WAL mode is enabled by default for concurrent reads
3. **Rate Limiting**: Adjust based on Reddit account age and trust level
4. **Message Volume**: Start low (10-20/hour) and increase gradually
### Reliability
1. **Auto-restart**: Use `restart: unless-stopped` in Docker
2. **Health Checks**: Monitor `/api/stats` endpoint
3. **Logging**: Review logs regularly for errors
4. **Backups**: Regularly backup `data/reddit-bot.db`
### Monitoring
1. **Dashboard**: Check web dashboard for real-time stats
2. **Response Rate**: Monitor response rates per strategy/subreddit
3. **Error Rate**: Watch for AI refusals, send failures
4. **Browser Health**: Verify session isn't expired
### Scaling
RedditBot is designed as a single-instance application. For scaling:
1. **Multiple Accounts**: Run separate instances per Reddit account
2. **Subreddit Split**: Distribute subreddits across instances
3. **Centralized DB**: Consider moving to PostgreSQL for multi-instance
---
## Monitoring & Maintenance
### Daily Checks
- [ ] Dashboard shows bot is running
- [ ] Response rate is reasonable (>10%)
- [ ] No repeated errors in logs
- [ ] Browser session is active
### Weekly Tasks
- [ ] Review analytics (strategy performance, subreddit performance)
- [ ] Check disk usage (media files, database)
- [ ] Verify backup is working
- [ ] Review successful messages for quality
### Monthly Tasks
- [ ] Backup database
- [ ] Review and update strategy variants
- [ ] Check for OpenRouter model updates
- [ ] Review and update seller keywords
- [ ] Verify browser session is still valid
### Backup Procedure
```bash
# Stop the bot
docker compose stop
# Backup database
cp data/reddit-bot.db data/reddit-bot.db.backup.$(date +%Y%m%d)
# Backup browser session (optional)
tar czf data/browser.backup.$(date +%Y%m%d).tar.gz data/browser/
# Restart the bot
docker compose start
```
---
## Troubleshooting
### Bot Won't Start
**Symptom**: Bot exits immediately on startup.
**Steps**:
1. Check logs: `docker compose logs reddit-bot`
2. Verify `config.yaml` syntax
3. Verify environment variables are set
4. Check for Zod validation errors in logs
### Account Import Fails
**Symptom**: Account work stays paused or import verification fails.
**Steps**:
1. Sign in to Reddit in local Chrome
2. Open Reddit Chat and wait for the extension badge to show `OK`
3. Export and upload a new combined session dump
4. Check logs for Reddit or Matrix identity errors
### AI Analysis Fails
**Symptom**: All messages show "AI refusal" or analysis errors.
**Steps**:
1. Verify API key is valid and has balance
2. Check model availability on OpenRouter
3. Try changing to a different model
4. Review logs for specific error messages
### High Error Rate
**Symptom**: Many messages fail to send.
**Steps**:
1. Check rate limiting (reduce maxMessagesPerHour)
2. Increase minDelayMs and jitterMs
3. Check for IP bans (try different network)
4. Review Reddit account standing
### Dashboard Not Accessible
**Symptom**: Cannot reach http://localhost:3000.
**Steps**:
1. Verify bot is running (`docker compose ps`)
2. Check port is not in use: `lsof -i :3000`
3. Verify firewall allows port 3000
4. Check web.port in config.yaml
### Database Issues
**Symptom**: Database errors or corruption.
**Steps**:
1. Stop the bot
2. Backup the database
3. Try opening with SQLite viewer to check integrity
4. If corrupted, restore from backup
5. Consider enabling automatic backups
The concise account activation instructions in [`../DOKPLOY_DEPLOY.md`](../DOKPLOY_DEPLOY.md) complement this operational guide.