Add automated deployment script template
Created deploy-to-coolify.example.sh script that: - Reads configuration from .env file - Creates Coolify application via API - Configures domain and Traefik labels - Sets up GitHub webhook for automatic deployments - Generates deployment secrets automatically - Provides step-by-step deployment feedback Updated .gitignore to exclude: - deploy-to-coolify.sh (customized copy) - deployment-info.txt (contains secrets) Users copy the example script and customize for their deployment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
254
deploy-to-coolify.example.sh
Executable file
254
deploy-to-coolify.example.sh
Executable file
@@ -0,0 +1,254 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ========================================
|
||||
# AI Recruitment Site - Coolify Deployment Script
|
||||
# ========================================
|
||||
# This script automatically deploys your customized recruitment site to Coolify
|
||||
#
|
||||
# IMPORTANT: Copy this file to deploy-to-coolify.sh and customize it
|
||||
# DO NOT commit deploy-to-coolify.sh to git (it's in .gitignore)
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. Set environment variables: COOLIFY_API_TOKEN and GITEA_API_TOKEN
|
||||
# 2. Customize your .env file with company information
|
||||
# 3. Ensure you have jq and curl installed
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# Load environment variables from .env
|
||||
if [ ! -f .env ]; then
|
||||
echo "❌ Error: .env file not found. Copy .env.example to .env and customize it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source .env
|
||||
|
||||
# Check required environment variables (from shell environment, not .env)
|
||||
if [ -z "$COOLIFY_API_TOKEN" ]; then
|
||||
echo "❌ Error: COOLIFY_API_TOKEN environment variable not set"
|
||||
echo " Export it: export COOLIFY_API_TOKEN='your-token-here'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$GITEA_API_TOKEN" ]; then
|
||||
echo "❌ Error: GITEA_API_TOKEN environment variable not set"
|
||||
echo " Export it: export GITEA_API_TOKEN='your-token-here'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check required .env variables
|
||||
if [ -z "$COMPANY_NAME" ]; then
|
||||
echo "❌ Error: COMPANY_NAME not set in .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$SUBDOMAIN" ]; then
|
||||
echo "❌ Error: SUBDOMAIN not set in .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$GITEA_USERNAME" ]; then
|
||||
echo "❌ Error: GITEA_USERNAME not set in .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$GITEA_REPO_NAME" ]; then
|
||||
echo "❌ Error: GITEA_REPO_NAME not set in .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate secrets if not provided
|
||||
if [ -z "$DB_PASSWORD" ]; then
|
||||
DB_PASSWORD=$(openssl rand -hex 16)
|
||||
echo "Generated DB_PASSWORD: $DB_PASSWORD"
|
||||
echo "DB_PASSWORD=\"$DB_PASSWORD\"" >> .env
|
||||
fi
|
||||
|
||||
if [ -z "$SESSION_SECRET" ]; then
|
||||
SESSION_SECRET=$(openssl rand -hex 32)
|
||||
echo "Generated SESSION_SECRET: $SESSION_SECRET"
|
||||
echo "SESSION_SECRET=\"$SESSION_SECRET\"" >> .env
|
||||
fi
|
||||
|
||||
# Coolify configuration
|
||||
COOLIFY_API="https://app.coolify.io/api/v1"
|
||||
COOLIFY_PROJECT_UUID="y8804s80goowsccwk8400kwo" # RecruitAI project
|
||||
COOLIFY_SERVER_UUID="ngkwo8css8og0s00c4ows44o" # h001 server
|
||||
COOLIFY_DESTINATION_UUID="eg0g8s04soo84ock8kw4wkgo" # coolify destination
|
||||
|
||||
# Repository URL
|
||||
REPO_URL="https://git.startanaicompany.com/${GITEA_USERNAME}/${GITEA_REPO_NAME}.git"
|
||||
|
||||
# Domain
|
||||
FULL_DOMAIN="${SUBDOMAIN}.recruitai.startanaicompany.com"
|
||||
|
||||
echo "========================================="
|
||||
echo " AI Recruitment Site Deployment"
|
||||
echo "========================================="
|
||||
echo "📦 Configuration:"
|
||||
echo " Company: $COMPANY_NAME"
|
||||
echo " Repository: $REPO_URL"
|
||||
echo " Domain: https://$FULL_DOMAIN"
|
||||
echo ""
|
||||
|
||||
# Create Coolify application
|
||||
echo "📝 Creating Coolify application..."
|
||||
APP_RESPONSE=$(curl -s -X POST "${COOLIFY_API}/applications" \
|
||||
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"project_uuid\": \"${COOLIFY_PROJECT_UUID}\",
|
||||
\"server_uuid\": \"${COOLIFY_SERVER_UUID}\",
|
||||
\"environment_name\": \"production\",
|
||||
\"destination_uuid\": \"${COOLIFY_DESTINATION_UUID}\",
|
||||
\"git_repository\": \"${REPO_URL}\",
|
||||
\"git_branch\": \"master\",
|
||||
\"build_pack\": \"dockercompose\",
|
||||
\"docker_compose_location\": \"/docker-compose.yml\",
|
||||
\"name\": \"${SUBDOMAIN}-recruit\",
|
||||
\"ports_exposes\": \"3000\"
|
||||
}")
|
||||
|
||||
APP_UUID=$(echo "$APP_RESPONSE" | jq -r '.uuid')
|
||||
|
||||
if [ "$APP_UUID" == "null" ] || [ -z "$APP_UUID" ]; then
|
||||
echo "❌ Failed to create application"
|
||||
echo "$APP_RESPONSE" | jq '.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Application created: $APP_UUID"
|
||||
echo " Save this UUID for future reference!"
|
||||
|
||||
# Configure domain
|
||||
echo "🌐 Configuring domain..."
|
||||
curl -s -X PATCH "${COOLIFY_API}/applications/${APP_UUID}" \
|
||||
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"docker_compose_domains\": {
|
||||
\"app\": {
|
||||
\"domain\": \"https://${FULL_DOMAIN}\"
|
||||
}
|
||||
}
|
||||
}" > /dev/null
|
||||
|
||||
echo "✅ Domain configured: https://$FULL_DOMAIN"
|
||||
|
||||
# Configure custom labels for Traefik
|
||||
echo "🏷️ Configuring Traefik labels..."
|
||||
LABELS=$(cat <<LABELS_EOF
|
||||
traefik.enable=true
|
||||
traefik.http.middlewares.gzip.compress=true
|
||||
traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
|
||||
traefik.http.services.https-0-${APP_UUID}-app.loadbalancer.server.port=3000
|
||||
LABELS_EOF
|
||||
)
|
||||
|
||||
LABELS_BASE64=$(echo "$LABELS" | base64 -w 0)
|
||||
|
||||
curl -s -X PATCH "${COOLIFY_API}/applications/${APP_UUID}" \
|
||||
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"custom_labels\": \"${LABELS_BASE64}\"
|
||||
}" > /dev/null
|
||||
|
||||
echo "✅ Traefik labels configured"
|
||||
|
||||
# Configure webhook for automatic deployments
|
||||
echo "🪝 Setting up deployment webhook..."
|
||||
|
||||
# Generate webhook secret
|
||||
WEBHOOK_SECRET=$(openssl rand -hex 16)
|
||||
WEBHOOK_URL="https://app.coolify.io/webhooks/source/gitea/events/manual/${APP_UUID}"
|
||||
|
||||
# Configure webhook in Coolify
|
||||
curl -s -X PATCH "${COOLIFY_API}/applications/${APP_UUID}" \
|
||||
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"manual_webhook_secret_gitea\": \"${WEBHOOK_SECRET}\"
|
||||
}" > /dev/null
|
||||
|
||||
# Create webhook in Gitea
|
||||
GITEA_API="https://git.startanaicompany.com/api/v1"
|
||||
WEBHOOK_RESPONSE=$(curl -s -X POST "${GITEA_API}/repos/${GITEA_USERNAME}/${GITEA_REPO_NAME}/hooks" \
|
||||
-H "Authorization: token ${GITEA_API_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"type\": \"gitea\",
|
||||
\"config\": {
|
||||
\"url\": \"${WEBHOOK_URL}?secret=${WEBHOOK_SECRET}\",
|
||||
\"content_type\": \"json\",
|
||||
\"secret\": \"${WEBHOOK_SECRET}\"
|
||||
},
|
||||
\"events\": [\"push\"],
|
||||
\"active\": true
|
||||
}")
|
||||
|
||||
WEBHOOK_ID=$(echo "$WEBHOOK_RESPONSE" | jq -r '.id')
|
||||
|
||||
if [ "$WEBHOOK_ID" == "null" ] || [ -z "$WEBHOOK_ID" ]; then
|
||||
echo "⚠️ Warning: Failed to create Gitea webhook (may already exist)"
|
||||
else
|
||||
echo "✅ Webhook configured for automatic deployments"
|
||||
fi
|
||||
|
||||
# Configure DNS with Cloudflare
|
||||
echo "🌍 Configuring DNS (Cloudflare)..."
|
||||
echo " Manual step required:"
|
||||
echo " 1. Go to Cloudflare DNS settings for startanaicompany.com"
|
||||
echo " 2. Add CNAME record: ${SUBDOMAIN}.recruitai -> app.coolify.io"
|
||||
echo " 3. Set Proxy status to 'Proxied'"
|
||||
echo ""
|
||||
|
||||
# Trigger initial deployment
|
||||
echo "🚀 Triggering initial deployment..."
|
||||
curl -s -X POST "${COOLIFY_API}/applications/${APP_UUID}/restart" \
|
||||
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" > /dev/null
|
||||
|
||||
echo "✅ Deployment triggered"
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Deployment Complete!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "📋 Deployment Details:"
|
||||
echo " Application UUID: $APP_UUID"
|
||||
echo " Domain: https://$FULL_DOMAIN"
|
||||
echo " Webhook Secret: $WEBHOOK_SECRET"
|
||||
echo ""
|
||||
echo "⏳ Your site will be available in 2-3 minutes at:"
|
||||
echo " https://$FULL_DOMAIN"
|
||||
echo ""
|
||||
echo "📝 Next Steps:"
|
||||
echo " 1. Configure Cloudflare DNS (see above)"
|
||||
echo " 2. Wait 2-3 minutes for deployment to complete"
|
||||
echo " 3. Visit https://$FULL_DOMAIN"
|
||||
echo " 4. Create your first admin account via the login page"
|
||||
echo ""
|
||||
echo "🔍 Monitor deployment:"
|
||||
echo " Coolify Dashboard: https://app.coolify.io"
|
||||
echo " Application: https://app.coolify.io/project/${COOLIFY_PROJECT_UUID}/${COOLIFY_SERVER_UUID}/application/${APP_UUID}"
|
||||
echo ""
|
||||
|
||||
# Save deployment info
|
||||
cat > deployment-info.txt <<DEPLOYMENT_INFO
|
||||
Deployment Information
|
||||
======================
|
||||
Date: $(date)
|
||||
Company: $COMPANY_NAME
|
||||
Domain: https://$FULL_DOMAIN
|
||||
Application UUID: $APP_UUID
|
||||
Repository: $REPO_URL
|
||||
|
||||
Database Password: $DB_PASSWORD
|
||||
Session Secret: $SESSION_SECRET
|
||||
Webhook Secret: $WEBHOOK_SECRET
|
||||
|
||||
Coolify Dashboard: https://app.coolify.io/project/${COOLIFY_PROJECT_UUID}/${COOLIFY_SERVER_UUID}/application/${APP_UUID}
|
||||
DEPLOYMENT_INFO
|
||||
|
||||
echo "💾 Deployment information saved to deployment-info.txt"
|
||||
echo " ⚠️ Keep this file secure - it contains sensitive information!"
|
||||
Reference in New Issue
Block a user