frappe_docker/.github/workflows/deploy.yml
2025-06-27 10:50:06 +03:00

192 lines
5.9 KiB
YAML

name: Deploy Academy LMS to Hetzner
on:
# Manual trigger
workflow_dispatch:
inputs:
force_rebuild:
description: 'Force rebuild all images'
required: false
default: 'false'
type: boolean
environment:
description: 'Deployment environment'
required: false
default: 'production'
type: choice
options:
- production
- test
# Webhook triggers from watched repositories
repository_dispatch:
types: [academy-lms-updated, academy-ai-tutor-updated, academy-langchain-updated]
# Push to master branch of this repo
push:
branches: [ master ]
paths:
- 'compose.yaml'
- 'images/**'
- '.github/workflows/**'
- 'nginx/**'
env:
REGISTRY: ghcr.io
HETZNER_HOST: 188.245.211.114
HETZNER_USER: frappe
DEPLOY_PATH: /opt/frappe-deployment
jobs:
build-and-deploy:
runs-on: ubuntu-latest
# Use environment for secrets management
environment: ${{ github.event.inputs.environment || 'production' }}
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Frappe image
id: meta-frappe
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/exarlabs/ignis-academy-lms
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Frappe image
uses: docker/build-push-action@v5
with:
context: .
file: ./images/custom/Containerfile
push: true
tags: ${{ steps.meta-frappe.outputs.tags }}
labels: ${{ steps.meta-frappe.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
LMS_REPO_URL=https://github.com/ExarLabs/academy-lms
AI_TUTOR_REPO_URL=https://github.com/ExarLabs/academy-ai-tutor-chat
- name: Clone and prepare LangChain service
run: |
# Clone private repository using PAT (Personal Access Token)
git clone https://${{ secrets.ACADEMY_DOCKER_PAT }}@github.com/ExarLabs/academy-LangChain.git langchain-temp
- name: Extract metadata for LangChain image
id: meta-langchain
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/exarlabs/academy-langchain
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push LangChain image
uses: docker/build-push-action@v5
with:
context: ./langchain-temp
push: true
tags: ${{ steps.meta-langchain.outputs.tags }}
labels: ${{ steps.meta-langchain.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# - name: Setup SSH key
# uses: webfactory/ssh-agent@v0.8.0
# with:
# ssh-private-key: ${{ secrets.HETZNER_SSH_KEY }}
# - name: Add Hetzner server to known hosts
# run: |
# ssh-keyscan -H ${{ env.HETZNER_HOST }} >> ~/.ssh/known_hosts
# - name: Deploy to Hetzner
# run: |
# # Copy deployment files to server
# scp -r compose.yaml nginx/ scripts/ ${{ env.HETZNER_USER }}@${{ env.HETZNER_HOST }}:${{ env.DEPLOY_PATH }}/
# # Copy environment file if it doesn't exist
# ssh ${{ env.HETZNER_USER }}@${{ env.HETZNER_HOST }} "
# cd ${{ env.DEPLOY_PATH }}
# if [ ! -f .env ]; then
# cp .env.example .env
# echo 'Please update .env file with your configuration'
# fi
# "
# # Login to private registry
# ssh ${{ env.HETZNER_USER }}@${{ env.HETZNER_HOST }} "
# echo '${{ secrets.GITHUB_TOKEN }}' | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin
# "
# - name: Update and restart services
# run: |
# ssh ${{ env.HETZNER_USER }}@${{ env.HETZNER_HOST }} "
# cd ${{ env.DEPLOY_PATH }}
# # Pull latest images
# docker compose pull
# # Stop services gracefully
# docker compose down --timeout 30
# # Start services
# docker compose up -d
# # Wait for services to be ready
# sleep 30
# # Run migrations on all sites
# ./scripts/migrate-all-sites.sh
# # Show status
# docker compose ps
# "
# - name: Health check
# run: |
# # Wait a bit more for services to fully start
# sleep 60
# # Check if nginx-proxy is responding
# if curl -f http://${{ env.HETZNER_HOST }}/health; then
# echo "✅ Deployment successful - Health check passed"
# else
# echo "❌ Health check failed"
# # Show logs for debugging
# ssh ${{ env.HETZNER_USER }}@${{ env.HETZNER_HOST }} "
# cd ${{ env.DEPLOY_PATH }}
# docker compose logs --tail=50
# "
# exit 1
# fi
# - name: Notify deployment status
# if: always()
# run: |
# if [ "${{ job.status }}" == "success" ]; then
# echo "🚀 Deployment to Hetzner completed successfully!"
# echo "🌐 Access your application at: http://${{ env.HETZNER_HOST }}"
# else
# echo "💥 Deployment failed. Check the logs above for details."
# fi