codenuk_backend_mine/Jenkinsfile
2025-10-10 08:56:39 +05:30

461 lines
18 KiB
Groovy

pipeline {
agent any
environment {
SSH_CREDENTIALS = 'cloudtopiaa'
REMOTE_SERVER = 'ubuntu@160.187.166.39'
REMOTE_WORKSPACE = '/home/ubuntu'
PROJECT_NAME = 'codenuk-backend-live'
DEPLOY_PATH = '/home/ubuntu/codenuk-backend-live'
GIT_CREDENTIALS = 'git-cred'
REPO_URL = 'https://git.tech4biz.wiki/Tech4Biz-Services/codenuk-backend-live.git'
EMAIL_RECIPIENT = 'jassim.mohammed@tech4biz.io, chandini.pachigunta@tech4biz.org'
COMPOSE_FILE = 'docker-compose.yml'
ENV_FILE = '.env'
}
options {
timeout(time: 45, unit: 'MINUTES')
retry(2)
timestamps()
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
stage('Preparation') {
steps {
script {
echo "Starting ${PROJECT_NAME} microservices deployment pipeline"
echo "Server: ${REMOTE_SERVER}"
echo "Deploy Path: ${DEPLOY_PATH}"
echo "Docker Compose deployment with persistent data"
}
}
}
stage('Git Operations on Remote Server') {
steps {
script {
sshagent(credentials: [SSH_CREDENTIALS]) {
withCredentials([usernamePassword(credentialsId: GIT_CREDENTIALS, usernameVariable: 'GIT_USER', passwordVariable: 'GIT_PASS')]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
echo "Checking Git repo..."
if [ -d "${DEPLOY_PATH}/.git" ]; then
echo "Pulling latest code..."
cd ${DEPLOY_PATH}
# Fix ownership issues
sudo chown -R ubuntu:ubuntu ${DEPLOY_PATH}
git config --global --add safe.directory ${DEPLOY_PATH}
git reset --hard
git clean -fd
git config pull.rebase false
git pull https://${GIT_USER}:${GIT_PASS}@git.tech4biz.wiki/Tech4Biz-Services/codenuk-backend-live.git main
else
echo "Cloning fresh repo..."
sudo rm -rf ${DEPLOY_PATH}
sudo mkdir -p ${DEPLOY_PATH}
sudo git clone https://${GIT_USER}:${GIT_PASS}@git.tech4biz.wiki/Tech4Biz-Services/codenuk-backend-live.git ${DEPLOY_PATH}
sudo chown -R ubuntu:ubuntu ${DEPLOY_PATH}
git config --global --add safe.directory ${DEPLOY_PATH}
fi
cd ${DEPLOY_PATH}
echo "Current commit: \$(git rev-parse HEAD)"
echo "Branch: \$(git branch --show-current)"
'
"""
}
}
}
}
}
stage('Environment Setup') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
# Verify Docker and Docker Compose are available
echo "Checking Docker installation..."
docker --version
docker compose version
# Create persistent data directories
echo "Creating persistent data directories..."
mkdir -p data/postgres
mkdir -p data/redis
mkdir -p data/mongodb
mkdir -p data/rabbitmq/data
mkdir -p data/rabbitmq/logs
mkdir -p data/neo4j/data
mkdir -p data/neo4j/logs
mkdir -p data/chromadb
mkdir -p data/n8n
mkdir -p generated-projects
mkdir -p generation-logs
mkdir -p dashboard-exports
mkdir -p logs/api-gateway
echo "Setting proper permissions..."
sudo chown -R ubuntu:ubuntu ${DEPLOY_PATH}
chmod +x ${DEPLOY_PATH}/scripts/* || echo "No scripts directory found"
'
"""
}
}
}
stage('Pre-deployment Backup') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
# Create backup directory with timestamp
BACKUP_DIR="backups/\$(date +%Y%m%d_%H%M%S)"
mkdir -p \$BACKUP_DIR
# Backup database volumes if they exist
if [ -d "data" ]; then
echo "Creating backup of persistent data..."
sudo tar -czf "\$BACKUP_DIR/data_backup.tar.gz" data/ || echo "Backup failed, continuing..."
fi
# Keep only last 5 backups
ls -t backups/ | tail -n +6 | xargs -r rm -rf
echo "Backup completed"
'
"""
}
}
}
stage('Stop Services Gracefully') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Stopping services gracefully..."
docker compose down --timeout 30 || echo "No running services found"
# Clean up orphaned containers
docker container prune -f || true
echo "Services stopped"
'
"""
}
}
}
stage('Build Services') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Building all services..."
docker compose build --no-cache --parallel
echo "Listing built images..."
docker images | grep codenuk || echo "No codenuk images found"
'
"""
}
}
}
stage('Start Infrastructure Services') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Starting infrastructure services..."
# Start databases and infrastructure first
docker compose up -d postgres redis mongodb rabbitmq neo4j chromadb
echo "Infrastructure services status:"
docker compose ps
'
"""
}
}
}
stage('Deploy Application Services') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Starting application services..."
docker compose up -d
echo "Waiting for application services to be ready..."
sleep 60
echo "All services status:"
docker compose ps
echo "Checking service health..."
docker compose ps --format "table {{.Name}}\\t{{.Status}}\\t{{.Ports}}"
'
"""
}
}
}
stage('Health Check') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Performing comprehensive health check..."
# Check if all services are running
FAILED_SERVICES=\$(docker compose ps --services --filter "status=exited")
if [ -n "\$FAILED_SERVICES" ]; then
echo "Failed services: \$FAILED_SERVICES"
docker compose logs \$FAILED_SERVICES
exit 1
fi
# Test database connectivity
echo "Testing database connectivity..."
docker compose exec -T postgres pg_isready -U pipeline_admin -d dev_pipeline || exit 1
# Test Redis connectivity
echo "Testing Redis connectivity..."
docker compose exec -T redis redis-cli ping || exit 1
# Test API Gateway endpoint (if available)
echo "Testing API Gateway health..."
timeout 30 bash -c "until curl -f https://dashboard.codenuk.com/health 2>/dev/null; do echo \\"Waiting for API Gateway...\\"; sleep 5; done" || echo "API Gateway health check timeout"
echo "Container resource usage:"
docker stats --no-stream --format "table {{.Container}}\\t{{.CPUPerc}}\\t{{.MemUsage}}"
echo "Volume usage:"
docker volume ls | grep -E "(postgres|redis|mongodb|rabbitmq|neo4j|chromadb|n8n)_data"
echo "Network connectivity:"
docker network ls | grep pipeline_network
echo "Deployment verification completed successfully"
'
"""
}
}
}
stage('Service Logs Check') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Checking recent logs for critical errors..."
# Check for critical errors in all services
SERVICES=\$(docker compose ps --services --filter "status=running")
for service in \$SERVICES; do
echo "=== \$service logs ==="
docker compose logs --tail=10 \$service || echo "No logs for \$service"
done
echo "Log check completed"
'
"""
}
}
}
stage('Performance Verification') {
steps {
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
set -e
cd ${DEPLOY_PATH}
echo "Performance and resource verification..."
# Check system resources
echo "System resources:"
free -h
df -h
# Check Docker system usage
echo "Docker system usage:"
docker system df
# Verify persistent volumes
echo "Persistent volume verification:"
docker volume inspect \${PROJECT_NAME}_postgres_data > /dev/null 2>&1 && echo "PostgreSQL data volume: OK" || echo "PostgreSQL data volume: MISSING"
docker volume inspect \${PROJECT_NAME}_redis_data > /dev/null 2>&1 && echo "Redis data volume: OK" || echo "Redis data volume: MISSING"
docker volume inspect \${PROJECT_NAME}_mongodb_data > /dev/null 2>&1 && echo "MongoDB data volume: OK" || echo "MongoDB data volume: MISSING"
echo "Performance verification completed"
'
"""
}
}
}
}
post {
always {
script {
// Collect logs from remote server for debugging
sshagent(credentials: [SSH_CREDENTIALS]) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
cd ${DEPLOY_PATH}
echo "=== Final Service Status ==="
docker compose ps || echo "Could not get service status"
echo "=== Docker System Info ==="
docker system df || echo "Could not get system info"
' || echo "Failed to collect final status"
"""
}
}
cleanWs()
}
success {
script {
sshagent(credentials: [SSH_CREDENTIALS]) {
def serviceStatus = sh(
script: """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
cd ${DEPLOY_PATH}
docker compose ps --format "table {{.Name}}\\t{{.Status}}\\t{{.Ports}}"
'
""",
returnStdout: true
).trim()
mail to: "${EMAIL_RECIPIENT}",
subject: "✅ Jenkins - ${PROJECT_NAME} Microservices Deployment Successful",
body: """The deployment of '${PROJECT_NAME}' microservices to ${REMOTE_SERVER} was successful.
Build Number: ${BUILD_NUMBER}
Build URL: ${BUILD_URL}
Deployment Time: ${new Date()}
Commit: ${env.GIT_COMMIT ?: 'Unknown'}
All microservices have been deployed using Docker Compose with persistent data volumes.
Service Status:
${serviceStatus}
Key Features:
- Database persistence maintained across deployments
- All services deployed and running
- Health checks passed
- Graceful service restart completed
Access URLs:
- API Gateway: http://${REMOTE_SERVER.split('@')[1]}:8000
- Dashboard: http://${REMOTE_SERVER.split('@')[1]}:8008
- N8N Workflow: http://${REMOTE_SERVER.split('@')[1]}:5678
For detailed logs, visit: ${BUILD_URL}console
"""
}
}
}
failure {
script {
def errorLogs = ""
try {
sshagent(credentials: [SSH_CREDENTIALS]) {
errorLogs = sh(
script: """
ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} '
cd ${DEPLOY_PATH}
echo "=== Failed Services ==="
docker compose ps --filter "status=exited"
echo "=== Recent Error Logs ==="
docker compose logs --tail=50 2>&1 || echo "Could not fetch logs"
'
""",
returnStdout: true
).trim()
}
} catch (Exception e) {
errorLogs = "Could not fetch error logs: ${e.message}"
}
mail to: "${EMAIL_RECIPIENT}",
subject: "❌ Jenkins - ${PROJECT_NAME} Microservices Deployment Failed",
body: """Microservices deployment failed for '${PROJECT_NAME}' on ${REMOTE_SERVER}.
Build Number: ${BUILD_NUMBER}
Build URL: ${BUILD_URL}console
Failure Time: ${new Date()}
Error Details:
${errorLogs}
Please review the full logs at: ${BUILD_URL}console
Common troubleshooting steps:
1. Check Docker service status on the server
2. Verify .env file configuration
3. Check available disk space and memory
4. Review individual service logs
5. Ensure all required ports are available
To manually investigate:
ssh ${REMOTE_SERVER}
cd ${DEPLOY_PATH}
docker compose logs [service-name]
docker compose ps
"""
}
}
unstable {
mail to: "${EMAIL_RECIPIENT}",
subject: "⚠️ Jenkins - ${PROJECT_NAME} Deployment Unstable",
body: """The deployment of '${PROJECT_NAME}' completed but some issues were detected.
Build Number: ${BUILD_NUMBER}
Build URL: ${BUILD_URL}console
Time: ${new Date()}
Please review the logs and verify all services are functioning correctly.
"""
}
}
}