Deployment Guide
Local development and production deployment configuration guide
Local Development
# Terminal 1: Backend
pnpm dev
# Terminal 2: Frontend (Next.js)
cd ui && pnpm dev
# Or use Caddy for reverse proxy
caddy run --config config/Caddyfile
Access: http://localhost:3000 (Backend API) or http://localhost:9002 (Next.js UI)
Production Deployment
Architecture
User → https://YOUR_DOMAIN (HTTPS)
↓
┌─────────────────────────────────────────┐
│ Vercel (Frontend) │
│ └─ Next.js UI (/ui) │
└─────────────────────────────────────────┘
↓ API calls
┌─────────────────────────────────────────┐
│ Docker Container (Backend) │
│ ├─ Caddy (ports 80/443) │
│ │ ├─ Auto SSL via Let's Encrypt │
│ │ └─ /api/* → Backend (localhost:3000)
│ └─ Node.js Backend (localhost:3000) │
└─────────────────────────────────────────┘
Separated frontend (Vercel) and backend (Docker) architecture.
Step 1: DNS Configuration
# Add A record
your-domain.com → YOUR_VPS_IP
# Verify
dig your-domain.com +short
Step 2: Firewall
# Ubuntu/Debian
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
Step 3: Deploy
# Create release tag
git tag v1.0.0
git push origin v1.0.0
# CI builds Docker image automatically
# Manually trigger deploy with DEPLOY_VERSION=v1.0.0
On the server:
# Create volume for SSL certificates and cache
mkdir -p /opt/firecrawl-lite/caddy-data
mkdir -p /opt/firecrawl-lite/cache
# Ensure correct permissions for the cache directory (UID 1001 is the node user in container)
chown -R 1001:1001 /opt/firecrawl-lite/cache
# Run container
docker run -d \
-p 80:80 -p 443:443 \
--name firecrawl-lite \
--restart=always \
-v /opt/firecrawl-lite/caddy-data:/data \
-v /opt/firecrawl-lite/cache:/cache \
-e CACHE_PATH="/cache" \
-e VERSION="v1.0.0" \
docker.cnb.cool/ai-alchemy-factory/firecrawl-lite:v1.0.0
Step 4: Verify
# Check container
docker ps | grep firecrawl-lite
# Test HTTPS
curl https://your-domain.com/api/health
# Verify SSL
curl -vI https://your-domain.com 2>&1 | grep "issuer"
Domain & SSL
Caddy handles SSL automatically:
- Detects domain from Caddyfile
- Requests certificate from Let's Encrypt
- Auto-renews before expiration (90-day cycle)
- Redirects HTTP to HTTPS
Troubleshooting SSL:
# Check DNS
dig your-domain.com +short
# Check ports accessible
nc -zv YOUR_VPS_IP 80
nc -zv YOUR_VPS_IP 443
# Check Caddy logs
docker logs firecrawl-lite | grep -i "acme\|certificate"
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT |
3000 | Server port |
NODE_ENV |
development | Environment |
API_KEY |
- | API auth key (optional) |
MAX_BROWSERS |
5 | Concurrent browser instances |
MAX_CRAWL_DEPTH |
3 | Max crawl depth |
MAX_CRAWL_PAGES |
50 | Max pages per crawl |
CACHE_PATH |
./data/cache | External cache directory path |
OPENAI_API_KEY |
- | For AI extraction |
Rollback
# Trigger rollback in CI with ROLLBACK_VERSION=v1.0.0
# Or manually:
docker stop firecrawl-lite
docker rm firecrawl-lite
docker run -d ... docker.cnb.cool/ai-alchemy-factory/firecrawl-lite:v1.0.0
SSL certificates are preserved in /opt/firecrawl-lite/caddy-data.
Troubleshooting
Container not starting
docker logs firecrawl-lite
# Check: port conflict, permission denied
Backend not responding
docker exec firecrawl-lite curl -sf http://localhost:3000/api/health
Browser pool exhausted
# Increase pool size
-e MAX_BROWSERS=8
Memory issues
# Limit crawl scope
-e MAX_CRAWL_PAGES=30
Cost Estimation
| Item | Cost |
|---|---|
| VPS (2GB RAM) | $10-20/month |
| Domain | $10-15/year |
| SSL Certificate | Free (Let's Encrypt) |
| Total | $10-20/month |
Puppeteer requires at least 1GB RAM. 2GB recommended.