Added complete guide for migrating from containerized PostgreSQL to standalone server with production-grade backup strategies. New files: - docs/DATABASE-MIGRATION-GUIDE.md - Complete migration guide with step-by-step instructions, troubleshooting, and rollback procedures - scripts/backup-standalone-postgres.sh - Automated backup script with daily, weekly, and monthly retention policies - scripts/restore-standalone-postgres.sh - Safe restore script with verification and pre-restore safety backup Features: - Hybrid backup strategy (PostgreSQL native + Basil API) - Automated retention policy (30/90/365 days) - Integrity verification - Safety backups before restore - Complete troubleshooting guide - Rollback procedures Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Basil Deployment Scripts
This directory contains scripts for automated deployment of Basil.
Scripts Overview
deploy.sh
Main deployment script that handles the complete deployment process.
Features:
- Pre-deployment backup creation
- Docker image pulling from registry
- Container restart with health checks
- Automatic cleanup of old images
- Comprehensive logging
Usage:
# With environment variables
DOCKER_USERNAME=myuser DOCKER_REGISTRY=docker.io IMAGE_TAG=latest ./deploy.sh
# Or source from .env.deploy
source ../.env.deploy && ./deploy.sh
Environment Variables:
DOCKER_USERNAME(required): Docker registry usernameDOCKER_REGISTRY(optional, default: docker.io): Registry URLIMAGE_TAG(optional, default: latest): Image tag to pull
manual-deploy.sh
Interactive wrapper around deploy.sh with user prompts.
Features:
- Interactive prompts for configuration
- Saves configuration to
.env.deployfor future use - Confirmation before deployment
Usage:
./manual-deploy.sh
The script will prompt for:
- Docker Hub username
- Docker registry (default: docker.io)
- Image tag (default: latest)
- Confirmation to proceed
webhook-receiver.sh
Webhook server that listens for deployment triggers from CI/CD.
Features:
- HTTP webhook endpoint
- Secret-based authentication
- Automatic deployment on webhook call
- Systemd service support
Usage:
# Manual run (foreground)
WEBHOOK_PORT=9000 WEBHOOK_SECRET=mysecret ./webhook-receiver.sh
# Or install as systemd service (recommended)
sudo cp basil-webhook.service /etc/systemd/system/
sudo systemctl enable basil-webhook
sudo systemctl start basil-webhook
Environment Variables:
WEBHOOK_PORT(optional, default: 9000): Port to listen onWEBHOOK_SECRET(optional, default: changeme): Authentication secret
Webhook Endpoint:
POST http://localhost:9000/hooks/basil-deploy
Header: X-Webhook-Secret: your-secret
basil-webhook.service
Systemd service file for running webhook receiver as a system service.
Installation:
# 1. Copy service file
sudo cp basil-webhook.service /etc/systemd/system/
# 2. Edit environment variables in the file
sudo nano /etc/systemd/system/basil-webhook.service
# 3. Reload systemd
sudo systemctl daemon-reload
# 4. Enable and start service
sudo systemctl enable basil-webhook
sudo systemctl start basil-webhook
# 5. Check status
sudo systemctl status basil-webhook
Service Management:
# Start service
sudo systemctl start basil-webhook
# Stop service
sudo systemctl stop basil-webhook
# Restart service
sudo systemctl restart basil-webhook
# View logs
sudo journalctl -u basil-webhook -f
# Check status
sudo systemctl status basil-webhook
Deployment Workflow
Automatic Deployment (CI/CD)
- Developer pushes to
mainbranch - Gitea Actions runs tests and builds images
- Images pushed to Docker registry
- Gitea Actions calls webhook endpoint
- Webhook server receives call and executes
deploy.sh - Production server pulls new images and restarts
Manual Deployment
- Run
./manual-deploy.sh - Enter configuration when prompted
- Confirm deployment
- Script executes deployment process
Logs
All scripts log to the parent directory:
deploy.log- Deployment script logswebhook.log- Webhook server logswebhook-error.log- Webhook server errors
View logs:
# Deployment logs
tail -f ../deploy.log
# Webhook logs
tail -f ../webhook.log
# Webhook errors
tail -f ../webhook-error.log
# Systemd service logs
sudo journalctl -u basil-webhook -f
Configuration Files
.env.deploy (in parent directory)
Stores deployment configuration. Created from .env.deploy.example.
DOCKER_USERNAME=your-dockerhub-username
DOCKER_REGISTRY=docker.io
IMAGE_TAG=latest
WEBHOOK_PORT=9000
WEBHOOK_SECRET=your-random-secret
Important: This file is gitignored and should never be committed.
webhook-config.json (auto-generated)
Generated by webhook-receiver.sh. Configures the webhook endpoint.
Location: Created in scripts directory when webhook-receiver.sh runs.
Troubleshooting
Script Permission Denied
chmod +x *.sh
Docker Pull Fails
# Check credentials
docker login -u $DOCKER_USERNAME
# Check image exists
docker pull $DOCKER_REGISTRY/$DOCKER_USERNAME/basil-api:$IMAGE_TAG
Webhook Not Responding
# Check service status
sudo systemctl status basil-webhook
# Check if port is listening
sudo netstat -tlnp | grep 9000
# Check firewall
sudo ufw status
Health Check Fails
# Check API logs
docker-compose logs api
# Check API manually
curl http://localhost:3001/health
# Check database connection
docker-compose exec api npx prisma studio
Security Notes
- Never commit secrets:
.env.deployis gitignored - Use strong webhook secret: 32+ character random string
- Firewall webhook port: Allow only from known IPs if possible
- Use HTTPS: Configure reverse proxy for webhook in production
- Backup before deploy: Script creates automatic backups
Directory Structure
scripts/
├── README.md # This file
├── deploy.sh # Main deployment script
├── manual-deploy.sh # Interactive deployment
├── webhook-receiver.sh # Webhook server
├── basil-webhook.service # Systemd service file
└── webhook-config.json # Generated webhook config (auto-created)
Parent directory:
├── .env.deploy # Deployment config (gitignored)
├── .env.deploy.example # Example config
├── deploy.log # Deployment logs (gitignored)
├── webhook.log # Webhook logs (gitignored)
└── backups/ # Automatic backups (gitignored)