Add CI/CD deployment pipeline with Forgejo Actions

- Add .forgejo/workflows/deploy.yml for automated deployment
- Include rollback mechanism with image tagging
- Add health check verification (http://127.0.0.1:3100/health)
- Create manual rollback script for emergency use
- Add deployment documentation and setup instructions
- Supports auto-rollback on deployment failure
This commit is contained in:
openclawd 2026-02-15 11:02:43 +00:00
parent 0453176544
commit 7d3525fe57
4 changed files with 290 additions and 0 deletions

View file

@ -0,0 +1,100 @@
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
deploy:
name: Deploy to Server
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.1.0
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
set -e
echo "🚀 Starting deployment..."
# Navigate to project directory
cd /root/docfast
# Check current git status
echo "📋 Current status:"
git status --short || true
# Pull latest changes
echo "📥 Pulling latest changes..."
git fetch origin
git pull origin main
# Tag current running image for rollback
echo "🏷️ Tagging current image for rollback..."
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
docker tag docfast-docfast:latest docfast-docfast:rollback-$TIMESTAMP || echo "No existing image to tag"
# Build new image
echo "🔨 Building new Docker image..."
docker compose build --no-cache
# Stop services gracefully
echo "⏹️ Stopping services..."
docker compose down --timeout 30
# Start services
echo "▶️ Starting services..."
docker compose up -d
# Wait for service to be ready
echo "⏱️ Waiting for service to be ready..."
for i in {1..30}; do
if curl -f -s http://127.0.0.1:3100/health > /dev/null; then
echo "✅ Service is healthy!"
break
fi
if [ $i -eq 30 ]; then
echo "❌ Service failed to start - initiating rollback..."
docker compose down
# Try to rollback to previous image
ROLLBACK_IMAGE=$(docker images --format "table {{.Repository}}:{{.Tag}}" | grep "docfast-docfast:rollback-" | head -n1 | tr -s ' ' | cut -d' ' -f1)
if [ ! -z "$ROLLBACK_IMAGE" ]; then
echo "🔄 Rolling back to $ROLLBACK_IMAGE"
docker tag $ROLLBACK_IMAGE docfast-docfast:latest
docker compose up -d
# Wait for rollback to be healthy
sleep 10
if curl -f -s http://127.0.0.1:3100/health > /dev/null; then
echo "✅ Rollback successful"
else
echo "❌ Rollback failed - manual intervention required"
fi
else
echo "❌ No rollback image available"
fi
exit 1
fi
echo "⏳ Attempt $i/30 - waiting 5 seconds..."
sleep 5
done
# Cleanup old rollback images (keep last 5)
echo "🧹 Cleaning up old rollback images..."
docker images --format "table {{.Repository}}:{{.Tag}}" | grep "docfast-docfast:rollback-" | tail -n +6 | awk '{print $1":"$2}' | xargs -r docker rmi || true
# Final health check and status
echo "🔍 Final health check..."
HEALTH_STATUS=$(curl -f -s http://127.0.0.1:3100/health || echo "UNHEALTHY")
echo "Health status: $HEALTH_STATUS"
echo "📊 Service status:"
docker compose ps
echo "🎉 Deployment completed successfully!"

77
DEPLOYMENT.md Normal file
View file

@ -0,0 +1,77 @@
# DocFast CI/CD Deployment
This repository uses Forgejo Actions for automated deployment to production.
## Setup Instructions
### 1. Repository Secrets
Go to repository settings → Actions → Secrets and add these secrets:
- **SERVER_HOST**: `167.235.156.214`
- **SERVER_USER**: `root`
- **SSH_PRIVATE_KEY**: The private SSH key content from `/home/openclaw/.ssh/docfast`
### 2. How Deployment Works
**Trigger**: Push to `main` branch
**Process**:
1. SSH to production server
2. Pull latest code from git
3. Tag current Docker image for rollback
4. Build new Docker image
5. Stop current services
6. Start new services
7. Health check at `http://127.0.0.1:3100/health`
8. Rollback automatically if health check fails
### 3. Rollback Procedure
**Automatic Rollback**:
- Happens automatically if deployment fails health checks
- Reverts to the previously tagged image
**Manual Rollback**:
```bash
# On the production server
cd /root/docfast
./scripts/rollback.sh
```
**Emergency Rollback via SSH**:
```bash
ssh root@167.235.156.214
cd /root/docfast
docker compose down
docker tag docfast-docfast:rollback-YYYYMMDD-HHMMSS docfast-docfast:latest
docker compose up -d
```
### 4. Monitoring
- **Health Check**: `curl http://127.0.0.1:3100/health`
- **Service Status**: `docker compose ps`
- **Logs**: `docker compose logs -f`
### 5. File Structure
```
.forgejo/workflows/deploy.yml # Main deployment workflow
scripts/rollback.sh # Manual rollback script
scripts/setup-secrets.sh # Helper for setting up secrets
DEPLOYMENT.md # This documentation
```
### 6. Testing the Pipeline
1. Make a small change (e.g., bump version comment)
2. Commit and push to main branch
3. Check Actions tab in Forgejo to see deployment progress
4. Verify service is running with `curl http://127.0.0.1:3100/health`
## Troubleshooting
- **SSH Issues**: Ensure SSH key is properly added to secrets
- **Docker Build Issues**: Check server has enough disk space and memory
- **Health Check Fails**: Check if service is binding to correct port (3100)
- **Permission Issues**: Ensure user has Docker privileges on server

72
scripts/rollback.sh Executable file
View file

@ -0,0 +1,72 @@
#!/bin/bash
set -e
echo "🔄 DocFast Rollback Script"
echo "=========================="
# Check if we're on the server
if [ ! -d "/root/docfast" ]; then
echo "❌ This script should be run on the production server"
exit 1
fi
cd /root/docfast
# List available rollback images
echo "📋 Available rollback images:"
ROLLBACK_IMAGES=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}" | grep "docfast-docfast:rollback-" | head -10)
if [ -z "$ROLLBACK_IMAGES" ]; then
echo "❌ No rollback images available"
exit 1
fi
echo "$ROLLBACK_IMAGES"
echo ""
# Get the most recent rollback image
LATEST_ROLLBACK=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "docfast-docfast:rollback-" | head -n1)
if [ -z "$LATEST_ROLLBACK" ]; then
echo "❌ No rollback image found"
exit 1
fi
echo "🎯 Will rollback to: $LATEST_ROLLBACK"
echo ""
# Confirm rollback
read -p "⚠️ Are you sure you want to rollback? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "❌ Rollback cancelled"
exit 1
fi
echo "🛑 Stopping current services..."
docker compose down --timeout 30
echo "🔄 Rolling back to $LATEST_ROLLBACK..."
docker tag $LATEST_ROLLBACK docfast-docfast:latest
echo "▶️ Starting services..."
docker compose up -d
echo "⏱️ Waiting for service to be ready..."
for i in {1..20}; do
if curl -f -s http://127.0.0.1:3100/health > /dev/null; then
echo "✅ Rollback successful! Service is healthy."
break
fi
if [ $i -eq 20 ]; then
echo "❌ Rollback failed - service is not responding"
exit 1
fi
echo "⏳ Attempt $i/20 - waiting 3 seconds..."
sleep 3
done
echo "📊 Service status:"
docker compose ps
echo "🎉 Rollback completed successfully!"

41
scripts/setup-secrets.sh Executable file
View file

@ -0,0 +1,41 @@
#!/bin/bash
echo "🔐 Forgejo Repository Secrets Setup"
echo "===================================="
# Source credentials to get Forgejo token
source /home/openclaw/.openclaw/workspace/.credentials/docfast.env
# Repository secrets to set up
REPO_URL="https://git.cloonar.com/api/v1/repos/openclawd/docfast/actions/secrets"
echo "Setting up repository secrets for CI/CD..."
# Server host
echo "📡 Setting SERVER_HOST..."
curl -X PUT "$REPO_URL/SERVER_HOST" \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":"167.235.156.214"}' \
--silent
# Server user
echo "👤 Setting SERVER_USER..."
curl -X PUT "$REPO_URL/SERVER_USER" \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":"root"}' \
--silent
# SSH Private Key
echo "🔑 Setting SSH_PRIVATE_KEY..."
SSH_KEY_CONTENT=$(cat /home/openclaw/.ssh/docfast | jq -Rs .)
curl -X PUT "$REPO_URL/SSH_PRIVATE_KEY" \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"data\":$SSH_KEY_CONTENT}" \
--silent
echo "✅ Repository secrets have been configured!"
echo ""
echo "🔍 To verify, check: https://git.cloonar.com/openclawd/docfast/settings/actions/secrets"