Restructure chat service, web routes, and add test suite
Split monolithic chat service into modular structure with Matrix client support, extract web server into per-resource route modules, introduce bootstrap/main-loop separation, and add comprehensive vitest coverage across services, repositories, and utilities. Adds project docs and CLAUDE.md agent instructions.
This commit is contained in:
1 parent
dfa0580859
commit
633bb0ec04
84 files changed
+19278
-3888
No files matched your search
@@ -0,0 +1,413 @@
|
||||
# Deployment Guide
|
||||
|
||||
Complete guide for deploying RedditBot in various environments.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
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)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required
|
||||
|
||||
| Requirement | Version | Notes |
|
||||
|---|---|---|
|
||||
| Node.js | 18+ | LTS recommended |
|
||||
| npm | 9+ | Or yarn/pnpm |
|
||||
| OpenRouter API Key | - | Sign up at [openrouter.ai](https://openrouter.ai) |
|
||||
| Reddit Account | - | With DM permissions enabled |
|
||||
|
||||
### Recommended
|
||||
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
## Local Development
|
||||
|
||||
### 1. Clone and Install
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd RedditBot
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. Configure
|
||||
|
||||
Create `config.yaml`:
|
||||
|
||||
```yaml
|
||||
reddit:
|
||||
subreddits:
|
||||
- gonewild
|
||||
pollInterval: 15
|
||||
targetGender: "F"
|
||||
sellerKeywords:
|
||||
- seller
|
||||
- onlyfans
|
||||
|
||||
openrouter:
|
||||
apiKey: "sk-or-v1-your-key-here"
|
||||
model: "meta-llama/llama-3.2-90b-vision-preview"
|
||||
fallbackModels:
|
||||
- "google/gemini-2.0-flash-001"
|
||||
|
||||
rateLimit:
|
||||
minDelayMs: 30000
|
||||
maxMessagesPerHour: 20
|
||||
jitterMs: 15000
|
||||
|
||||
browser:
|
||||
headless: true
|
||||
userDataDir: "./data/browser"
|
||||
|
||||
database:
|
||||
path: "./data/reddit-bot.db"
|
||||
|
||||
web:
|
||||
port: 3000
|
||||
|
||||
dryRun: true # Start in dry run mode
|
||||
```
|
||||
|
||||
Set environment variables:
|
||||
|
||||
```bash
|
||||
export REDDIT_USERNAME="your-username"
|
||||
export REDDIT_PASSWORD="your-password"
|
||||
```
|
||||
|
||||
### 3. Initial Login
|
||||
|
||||
Run the login script to establish a browser session:
|
||||
|
||||
```bash
|
||||
npm run login
|
||||
```
|
||||
|
||||
This will:
|
||||
1. Open a browser window
|
||||
2. Navigate to Reddit login
|
||||
3. Wait for you to complete login (including 2FA if enabled)
|
||||
4. Save cookies to `data/browser/`
|
||||
|
||||
### 4. Start the Bot
|
||||
|
||||
```bash
|
||||
# Development (with TypeScript execution)
|
||||
npm run dev
|
||||
|
||||
# Production (compiled JavaScript)
|
||||
npm start
|
||||
```
|
||||
|
||||
### 5. Access Dashboard
|
||||
|
||||
Open http://localhost:3000 in your browser.
|
||||
|
||||
---
|
||||
|
||||
## Docker Deployment
|
||||
|
||||
### Build the Image
|
||||
|
||||
```bash
|
||||
docker build -t reddit-bot .
|
||||
```
|
||||
|
||||
### Run the Container
|
||||
|
||||
```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 REDDIT_USERNAME=your-username \
|
||||
-e REDDIT_PASSWORD=your-password \
|
||||
-e BROWSER_HEADLESS=true \
|
||||
reddit-bot:latest
|
||||
```
|
||||
|
||||
### Dockerfile Structure
|
||||
|
||||
```dockerfile
|
||||
# Build stage
|
||||
FROM node:18-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/config.yaml ./config.yaml
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["node", "dist/index.js"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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}
|
||||
- REDDIT_USERNAME=${REDDIT_USERNAME}
|
||||
- REDDIT_PASSWORD=${REDDIT_PASSWORD}
|
||||
- BROWSER_HEADLESS=true
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--spider", "http://localhost:3000/api/stats"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
```
|
||||
|
||||
### Start with Compose
|
||||
|
||||
```bash
|
||||
# Set environment variables
|
||||
cp .env.example .env
|
||||
# Edit .env with your credentials
|
||||
|
||||
# Build and start
|
||||
docker compose up -d --build
|
||||
|
||||
# View logs
|
||||
docker compose logs -f reddit-bot
|
||||
|
||||
# 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`
|
||||
- `REDDIT_USERNAME`
|
||||
- `REDDIT_PASSWORD`
|
||||
- `BROWSER_HEADLESS`
|
||||
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
|
||||
REDDIT_USERNAME: $REDDIT_USERNAME
|
||||
REDDIT_PASSWORD: $REDDIT_PASSWORD
|
||||
BROWSER_HEADLESS: "true"
|
||||
|
||||
ports:
|
||||
- container: 3000
|
||||
host: 3000
|
||||
|
||||
volumes:
|
||||
- source: reddit-bot-data
|
||||
target: /app/data
|
||||
type: bind
|
||||
|
||||
restartPolicy: unless-stopped
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Production Considerations
|
||||
|
||||
### Security
|
||||
|
||||
1. **Network Isolation**: Run behind a reverse proxy with authentication
|
||||
2. **Environment Variables**: Never commit credentials; use secrets management
|
||||
3. **Dashboard Access**: Restrict to internal network or add auth
|
||||
4. **Browser Data**: Protect `data/browser/` directory
|
||||
|
||||
### Performance
|
||||
|
||||
1. **Browser Headless**: Always use headless mode in production
|
||||
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
|
||||
|
||||
### Browser Login Fails
|
||||
|
||||
**Symptom**: "Browser session expired" or login fails.
|
||||
|
||||
**Steps**:
|
||||
1. Delete browser data: `rm -rf data/browser/`
|
||||
2. Re-run login: `npm run login`
|
||||
3. Check Reddit account is not locked
|
||||
4. Try `BROWSER_HEADLESS=false` for debugging
|
||||
|
||||
### 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
|
||||
Reference in new issue
Block a user