This directory contains deployment scripts and configuration for running HED-BOT in production.
- Quick Start
- Security Setup
- Deployment Options
- Automated Deployment
- Manual Deployment
- Configuration
- Monitoring
- Troubleshooting
- Docker installed on server
- Git access to repository
- Port 38427 available
# Clone repository
git clone https://github.com/neuromechanist/hed-bot.git
cd hed-bot
# Generate API key for authentication
python scripts/generate_api_key.py
# Create .env file with your configuration
cp .env.example .env
# Edit .env with your API keys (both OPENROUTER_API_KEY and API_KEYS)
# Deploy
./deploy/deploy.sh prodImportant: See Security Setup for detailed security configuration before deploying to production.
HED-BOT implements comprehensive security features for production deployment:
- API Key Authentication: Protects endpoints from unauthorized access
- Audit Logging: Complete request/response trail for compliance
- CORS Validation: Restricts origins to approved frontends only
- Security Headers: Protects against common web attacks
-
Generate API Key:
python scripts/generate_api_key.py
-
Add to .env file:
# API Authentication API_KEYS=<your_generated_key> REQUIRE_API_AUTH=true # Audit Logging ENABLE_AUDIT_LOG=true AUDIT_LOG_FILE=/var/log/hed-bot/audit.log # CORS (optional extra origins) # EXTRA_CORS_ORIGINS=https://staging.hed-bot.pages.dev
-
Use API key in requests:
curl -H "X-API-Key: your_key_here" \ https://hedtools.ucsd.edu/hed-bot-api/annotate
Protected (require API key):
POST /annotate- Generate annotationsPOST /annotate-from-image- Image annotationsPOST /validate- Validate HED strings
Public (no authentication):
GET /health- Health checksGET /version- Version infoGET /- API documentation
For comprehensive security information including:
- OWASP Top 10 compliance
- Audit log formats and retention
- Incident response procedures
- Security checklist for auditors
See: SECURITY.md for complete security documentation.
See Also: DEPLOYMENT_ARCHITECTURE.md for architecture details and CORS configuration.
Automatically checks for and deploys new releases every hour.
Setup:
# Test the auto-update script
./deploy/auto-update.sh --check-only
# Add to crontab for hourly checks
crontab -e
# Add this line:
0 * * * * /path/to/hed-bot/deploy/auto-update.sh >> /var/log/hed-bot-update.log 2>&1How it works:
- GitHub Actions builds Docker image on every push to
main - Image is pushed to GitHub Container Registry (GHCR)
- Cron job checks for new images hourly
- Automatically pulls and deploys new version if available
- Logs all updates to
/var/log/hed-bot-update.log
Deploy manually when needed.
Production:
./deploy/deploy.sh prodDevelopment:
./deploy/deploy.sh devWhen code is pushed to main branch or a version tag is created:
- Build: Docker image is built from
deploy/Dockerfile - Test: (Future) Run tests against the image
- Push: Image is pushed to
ghcr.io/neuromechanist/hed-bot - Tag: Images are tagged with:
latest(from main branch)main(latest main branch)v1.2.3(from version tags)sha-abc123(commit hash)
The auto-update.sh script provides automated deployment:
- Automatic Updates: Checks for new Docker images
- Safe Deployment: Uses locking to prevent concurrent updates
- Rollback Ready: Keeps previous image for quick rollback
- Logging: Comprehensive logs for troubleshooting
- Cleanup: Removes old dangling images
# Check for updates without deploying
./deploy/auto-update.sh --check-only
# Force update even if no new image
./deploy/auto-update.sh --force
# Update dev environment
./deploy/auto-update.sh --env dev
# Run from cron (recommended)
0 * * * * /path/to/deploy/auto-update.sh >> /var/log/hed-bot-update.log 2>&1Edit the script to customize:
# Image registry
REGISTRY_IMAGE="ghcr.io/neuromechanist/hed-bot:latest"
# Log file location
LOG_FILE="/var/log/hed-bot-update.log"
# Lock file location
LOCK_FILE="/tmp/hed-bot-update.lock"./deploy.sh [environment] [bind_address]- environment:
prod(default) ordev - bind_address: IP to bind to (default:
127.0.0.1)
# Production deployment (127.0.0.1:38427)
./deploy.sh prod
# Development deployment (127.0.0.1:38428)
./deploy.sh dev
# Bind to all interfaces (not recommended for production)
./deploy.sh prod 0.0.0.0- Builds Docker image from
deploy/Dockerfile - Stops existing container (if running)
- Starts new container with:
- Port mapping (host:38427 → container:38427)
- Environment variables from
.env - Auto-restart policy
- Health checks enabled
- Shows logs and verifies health
- Displays useful management commands
Create a .env file in the project root:
# API Authentication (REQUIRED for production)
API_KEYS=your_generated_key_here
REQUIRE_API_AUTH=true
# Audit Logging (recommended for production)
ENABLE_AUDIT_LOG=true
AUDIT_LOG_FILE=/var/log/hed-bot/audit.log
# CORS Configuration (optional extra origins)
# EXTRA_CORS_ORIGINS=https://staging.hed-bot.pages.dev,https://dev.hed-bot.pages.dev
# LLM Configuration (Cerebras + OpenRouter for ultra-fast inference)
LLM_PROVIDER=openrouter
OPENROUTER_API_KEY=your_openrouter_key_here
LLM_PROVIDER_PREFERENCE=Cerebras
LLM_TEMPERATURE=0.1
# Model configuration (Cerebras-optimized defaults)
ANNOTATION_MODEL=openai/gpt-oss-120b
EVALUATION_MODEL=qwen/qwen3-235b-a22b-2507
ASSESSMENT_MODEL=openai/gpt-oss-120b
FEEDBACK_MODEL=openai/gpt-oss-120b
# Optional: HED Schema and Validator paths (if not using defaults)
# HED_SCHEMA_DIR=/path/to/hed-schemas
# HED_VALIDATOR_PATH=/path/to/hed-javascript
# USE_JS_VALIDATOR=trueSecurity Note: Generate API keys using python scripts/generate_api_key.py. Never commit .env to Git.
Add to your Apache virtual host configuration:
# HED-BOT API Backend
ProxyPass /hed-bot-api/ http://localhost:38427/
ProxyPassReverse /hed-bot-api/ http://localhost:38427/Reload Apache:
sudo apache2ctl configtest
sudo systemctl reload apache2location /hed-bot-api/ {
proxy_pass http://127.0.0.1:38427/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}Reload Nginx:
sudo nginx -t
sudo systemctl reload nginx# Check if container is running
docker ps | grep hed-bot
# Check container health
docker inspect --format='{{.State.Health.Status}}' hed-bot
# View resource usage
docker stats hed-bot# View real-time logs
docker logs -f hed-bot
# View last 100 lines
docker logs --tail 100 hed-bot
# View logs with timestamps
docker logs -t hed-bot
# Auto-update logs
tail -f /var/log/hed-bot-update.log# Manual health check
curl http://localhost:38427/health
# Through reverse proxy
curl https://your-domain.com/hed-bot/healthExpected response:
{
"status": "healthy",
"version": "0.4.2-alpha",
"llm_available": true,
"validator_available": true
}Check logs:
docker logs hed-botCommon issues:
- Missing
.envfile → Copy from.env.example - Invalid API key → Check OPENROUTER_API_KEY
- Port already in use →
sudo lsof -i :38427
Check cron job:
crontab -lCheck permissions:
chmod +x deploy/auto-update.shCheck logs:
tail -f /var/log/hed-bot-update.logTest manually:
./deploy/auto-update.sh --check-onlyCheck health:
docker inspect --format='{{.State.Health}}' hed-botCheck network:
curl http://127.0.0.1:38427/healthRestart container:
docker restart hed-botIf auto-update caused issues:
# Stop current container
docker stop hed-bot
docker rm hed-bot
# Find previous image
docker images | grep hed-bot
# Run previous image
docker run -d \
--name hed-bot \
--restart unless-stopped \
-p 127.0.0.1:38427:38427 \
--env-file .env \
hed-bot:previous-tagLogin to GitHub Container Registry:
# Create personal access token with read:packages scope
# https://github.com/settings/tokens
echo YOUR_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdinManually pull image:
docker pull ghcr.io/neuromechanist/hed-bot:latestModify cron schedule for different update frequencies:
# Every 15 minutes
*/15 * * * * /path/to/auto-update.sh >> /var/log/hed-bot-update.log 2>&1
# Every 6 hours
0 */6 * * * /path/to/auto-update.sh >> /var/log/hed-bot-update.log 2>&1
# Once daily at 2 AM
0 2 * * * /path/to/auto-update.sh >> /var/log/hed-bot-update.log 2>&1
# Weekdays at 6 AM
0 6 * * 1-5 /path/to/auto-update.sh >> /var/log/hed-bot-update.log 2>&1Add notification to auto-update.sh:
send_notification() {
MESSAGE="$1"
# Slack webhook
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}" \
YOUR_SLACK_WEBHOOK_URL
# Email
echo "$MESSAGE" | mail -s "HED-BOT Update" admin@example.com
}Run both old and new versions simultaneously:
# Deploy new version on alternate port
./deploy.sh dev # Runs on port 38428
# Test new version
curl http://localhost:38428/health
# Switch reverse proxy to new version
# Update Nginx configuration
# Remove old version
docker stop hed-bot
docker rm hed-bot| File | Purpose |
|---|---|
Dockerfile |
Container build configuration |
deploy.sh |
Manual deployment script |
auto-update.sh |
Automated update script |
nginx-hedtools.conf |
Nginx reverse proxy configuration |
SECURITY.md |
Security documentation for auditors |
DEPLOYMENT_ARCHITECTURE.md |
Architecture and CORS setup guide |
README.md |
This documentation |
- Issues: https://github.com/neuromechanist/hed-bot/issues
- Documentation: https://github.com/neuromechanist/hed-bot/tree/main/docs
Last Updated: December 2, 2025