mnemo_cards/.forgejo/workflows/deploy.yaml

474 lines
22 KiB
YAML
Raw Normal View History

name: Deploy Mnemo Cards
on:
workflow_dispatch:
push:
branches:
- master
2025-11-20 21:38:15 +00:00
paths:
- 'mnemo_cards_web_v2/**'
- 'mnemo_cards_backend/**'
- 'mnemo_cards_common/**'
- 'mnemo_cards_common_backend/**'
jobs:
deploy-backend:
name: Deploy Backend
runs-on: ubuntu-latest
steps:
2025-11-22 21:14:18 +00:00
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Checkout code
uses: actions/checkout@v3
- name: Install Dependencies
run: |
apt-get update && apt-get install -y rsync openssh-client
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Sync Source Code
run: |
# Sync common packages
rsync -avz --delete --exclude '.*' --exclude 'build' --exclude 'doc' \
mnemo_cards_common \
mnemo_cards_common_backend \
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:~/
# Sync backend project
rsync -avz --delete --exclude '.*' --exclude 'build' --exclude 'server.exe' --exclude 'isar' \
mnemo_cards_backend \
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:~/
2025-11-22 21:14:18 +00:00
- name: Obtain Certificates
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
echo "🔐 Checking Let's Encrypt certificates..."
2025-11-22 21:34:29 +00:00
2025-11-22 21:14:18 +00:00
# Проверяем наличие multi-domain сертификата
if [ -d "/etc/letsencrypt/live/mnemo-cards.online" ] && [ -f "/etc/letsencrypt/live/mnemo-cards.online/fullchain.pem" ]; then
echo "✅ Let's Encrypt multi-domain сертификаты уже существуют"
2025-11-22 21:34:29 +00:00
# Проверяем что nginx работает
if ! sudo systemctl is-active --quiet nginx; then
echo "🚨 nginx не работает! Запускаем..."
sudo systemctl start nginx
sleep 2
if ! sudo systemctl is-active --quiet nginx; then
echo "❌ Критическая ошибка: не удалось запустить nginx!"
exit 1
fi
fi
2025-11-22 21:14:18 +00:00
else
echo "⚠️ Сертификаты не найдены. Пытаемся получить через webroot (nginx продолжает работать)..."
2025-11-22 21:34:29 +00:00
2025-11-22 21:14:18 +00:00
# Убеждаемся, что nginx запущен
if ! sudo systemctl is-active --quiet nginx; then
echo "🚀 Запускаем nginx для webroot режима..."
sudo systemctl start nginx
2025-11-22 21:34:29 +00:00
sleep 2
if ! sudo systemctl is-active --quiet nginx; then
echo "❌ Критическая ошибка: не удалось запустить nginx для получения сертификатов!"
exit 1
fi
2025-11-22 21:14:18 +00:00
fi
2025-11-22 21:34:29 +00:00
2025-11-22 21:14:18 +00:00
# Создаем директорию для webroot challenge
sudo mkdir -p /var/www/html/.well-known/acme-challenge
sudo chown -R www-data:www-data /var/www/html
2025-11-22 21:34:29 +00:00
2025-11-22 21:14:18 +00:00
# Убеждаемся, что nginx может обслуживать ACME challenge
# Проверяем, есть ли конфигурация для /.well-known
if ! grep -q "\.well-known" /etc/nginx/sites-enabled/* 2>/dev/null; then
echo "📝 Добавляем поддержку ACME challenge в nginx..."
# Создаем временную конфигурацию для ACME challenge
2025-11-22 21:17:49 +00:00
sudo printf 'server {\n listen 80;\n server_name _;\n location /.well-known/acme-challenge/ {\n root /var/www/html;\n try_files $uri =404;\n }\n location / {\n return 404;\n }\n}\n' > /etc/nginx/sites-available/acme-challenge
2025-11-22 21:14:18 +00:00
sudo ln -sf /etc/nginx/sites-available/acme-challenge /etc/nginx/sites-enabled/acme-challenge
sudo nginx -t && sudo systemctl reload nginx
fi
2025-11-22 21:34:29 +00:00
2025-11-22 21:14:18 +00:00
# Получаем multi-domain сертификат через webroot
echo "🔐 Получаем Let's Encrypt multi-domain сертификат через webroot..."
if sudo certbot certonly --webroot \
-w /var/www/html \
-d mnemo-cards.online \
-d api.mnemo-cards.online \
-d code.mnemo-cards.online \
-d vscode.mnemo-cards.online \
--cert-name mnemo-cards.online \
--non-interactive --agree-tos --email admin@mnemo-cards.online; then
echo "✅ Let's Encrypt multi-domain сертификат успешно получен через webroot!"
else
echo "⚠️ Не удалось получить сертификат через webroot. Продолжаем без HTTPS..."
fi
fi
ENDSSH
- name: Get Dependencies
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
cd ~/mnemo_cards_backend
echo "📦 Getting dependencies..."
dart pub get
ENDSSH
- name: Compile Server
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
cd ~/mnemo_cards_backend
echo "🔨 Compiling server..."
dart compile exe --verbose lib/main.dart -o server_build.exe
ENDSSH
- name: Stop Service
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
2025-11-22 21:34:29 +00:00
echo "🛑 Stopping backend service..."
2025-11-22 21:14:18 +00:00
sudo systemctl stop mnemo_cards_server || true
2025-11-22 21:34:29 +00:00
echo "✅ Backend service stopped"
echo "🔍 Checking nginx status after stopping backend..."
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx still running"
else
echo "🚨 nginx also stopped! This is the problem!"
echo "🚀 Starting nginx..."
sudo systemctl start nginx
sleep 2
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx restarted"
else
echo "❌ Failed to restart nginx!"
exit 1
fi
fi
2025-11-22 21:14:18 +00:00
ENDSSH
- name: Update Service Configuration
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
cd ~/mnemo_cards_backend
echo "⚙️ Updating service configuration..."
sudo chmod 777 mnemo_cards_server.service
sudo cp mnemo_cards_server.service /etc/systemd/system/
ENDSSH
- name: Update Executable
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
cd ~/mnemo_cards_backend
echo "🔄 Replacing executable..."
sudo cp server_build.exe server.exe
rm server_build.exe
ENDSSH
- name: Configure Certificates
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
# Check certificates and configure mode
# Используем multi-domain сертификат mnemo-cards.online (если есть)
if [ -d "/etc/letsencrypt/live/mnemo-cards.online" ] && [ -f "/etc/letsencrypt/live/mnemo-cards.online/fullchain.pem" ]; then
echo "✅ Let's Encrypt multi-domain сертификат найден. Настраиваем HTTPS режим..."
sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe --certs /etc/letsencrypt/live/mnemo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service
elif [ -d "/etc/letsencrypt/live/api.mnemo-cards.online" ]; then
echo "✅ Let's Encrypt сертификат для API найден. Настраиваем dual mode..."
sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe --dual --certs /etc/letsencrypt/live/api.mnemo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service
else
echo "⚠️ No certificates found. Configuring HTTP mode..."
sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service
fi
ENDSSH
- name: Restart Service
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
echo "🚀 Restarting service..."
sudo systemctl daemon-reload
sudo systemctl start mnemo_cards_server
sleep 2
systemctl status mnemo_cards_server --no-pager
ENDSSH
2025-11-23 00:00:32 +00:00
- name: Generate and Deploy Nginx Configs
run: |
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
set -e
echo "🔧 Generating and deploying nginx configurations..."
cd ~/tools/deploy
./generate-nginx-configs.sh
./deploy-nginx-configs.sh
./check-nginx.sh
ENDSSH
2025-11-22 21:14:18 +00:00
- name: Ensure Nginx Running
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:14:18 +00:00
set -e
echo "🔍 Проверяем статус nginx..."
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx уже запущен"
# Перезагружаем конфигурацию на всякий случай
if sudo nginx -t 2>/dev/null; then
sudo systemctl reload nginx
echo "✅ Конфигурация nginx перезагружена"
fi
else
echo "⚠️ nginx не запущен, запускаем..."
if sudo nginx -t 2>/dev/null; then
sudo systemctl start nginx
sleep 2
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx успешно запущен"
else
echo "❌ Ошибка: не удалось запустить nginx!"
sudo systemctl status nginx --no-pager || true
2025-11-22 21:34:29 +00:00
exit 1
2025-11-22 21:14:18 +00:00
fi
else
echo "❌ Ошибка в конфигурации nginx!"
sudo nginx -t || true
2025-11-22 21:34:29 +00:00
exit 1
fi
fi
ENDSSH
ensure-nginx-running:
name: Ensure Nginx Running After Backend
runs-on: ubuntu-latest
needs: deploy-backend
if: always() && needs.deploy-backend.result == 'success'
steps:
2025-11-22 21:37:33 +00:00
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
2025-11-22 21:34:29 +00:00
- name: Check Nginx Status
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:34:29 +00:00
set -e
echo "🔍 Проверяем статус nginx после деплоя backend..."
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx запущен"
# Тестируем доступность сайтов
if curl -I --max-time 10 https://code.mnemo-cards.online/ 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ code.mnemo-cards.online доступен"
else
echo "⚠️ code.mnemo-cards.online недоступен"
fi
if curl -I --max-time 10 https://vscode.mnemo-cards.online/ 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ vscode.mnemo-cards.online доступен"
else
echo "⚠️ vscode.mnemo-cards.online недоступен"
fi
else
echo "❌ nginx не запущен! Запускаем..."
sudo systemctl start nginx
sleep 2
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx запущен"
else
echo "❌ Не удалось запустить nginx!"
sudo systemctl status nginx --no-pager || true
exit 1
2025-11-22 21:14:18 +00:00
fi
fi
ENDSSH
deploy-web:
name: Deploy Web App
runs-on: ubuntu-latest
2025-11-21 00:21:48 +00:00
container: ghcr.io/cirruslabs/flutter:3.35.5
2025-11-22 21:34:29 +00:00
needs: ensure-nginx-running
2025-11-22 21:43:40 +00:00
if: always() && needs.ensure-nginx-running.result == 'success'
steps:
2025-11-22 21:52:39 +00:00
- name: Install System Dependencies
run: |
apt-get update && apt-get install -y rsync openssh-client jq git curl wget gnupg2 software-properties-common ca-certificates
2025-11-22 21:22:56 +00:00
2025-11-22 21:52:39 +00:00
- name: Setup Node.js
2025-11-22 21:43:40 +00:00
run: |
2025-11-22 21:52:39 +00:00
# Install Node.js manually in container
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
echo "Node.js version: $(node --version)"
echo "NPM version: $(npm --version)"
2025-11-22 21:43:40 +00:00
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Checkout code
uses: actions/checkout@v3
with:
2025-11-19 22:11:36 +00:00
fetch-depth: 0
lfs: false
- name: Configure Git
run: |
2025-11-22 20:22:44 +00:00
git config --global http.postBuffer 52428800
git config --global http.maxRequestBuffer 100M
git config --global core.compression 0
2025-11-22 21:43:40 +00:00
- name: Check Nginx Before Web Deploy
run: |
2025-11-22 21:43:40 +00:00
echo "🔍 Проверяем статус nginx перед деплоем web..."
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:43:40 +00:00
set -e
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx работает перед web деплоем"
# Тестируем доступность
if curl -I --max-time 5 https://mnemo-cards.online/ 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ mnemo-cards.online доступен"
else
echo "⚠️ mnemo-cards.online недоступен"
fi
if curl -I --max-time 5 https://code.mnemo-cards.online/ 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ code.mnemo-cards.online доступен"
else
echo "⚠️ code.mnemo-cards.online недоступен"
fi
else
echo "❌ nginx не работает перед web деплоем!"
exit 1
fi
ENDSSH
- name: Build Web App
2025-11-19 22:11:36 +00:00
working-directory: mnemo_cards_web_v2
run: |
2025-11-22 22:14:58 +00:00
echo "🔍 Проверяем Flutter..."
2025-11-22 21:52:39 +00:00
which flutter || echo "Flutter not found in PATH"
flutter --version || echo "Flutter command failed"
2025-11-22 22:14:58 +00:00
echo "📦 Получаем зависимости..."
timeout 300 flutter pub get || (echo "❌ Flutter pub get failed" && exit 1)
echo "🔨 Собираем веб-приложение..."
timeout 600 flutter build web --release \
2025-11-20 18:41:09 +00:00
--dart-define=API_BASE_URL=https://api.mnemo-cards.online \
2025-11-22 22:14:58 +00:00
--dart2js-optimization=O4 || (echo "❌ Flutter build failed" && exit 1)
echo "✅ Сборка завершена"
- name: Deploy Web App
run: |
2025-11-22 21:43:40 +00:00
echo "📦 Копируем веб-приложение..."
2025-11-22 22:14:58 +00:00
timeout 120 rsync -avz --delete mnemo_cards_web_v2/build/web/ \
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/var/www/mnemo_cards/ || (echo "❌ Rsync failed" && exit 1)
2025-11-22 21:43:40 +00:00
echo "✅ Веб-приложение скопировано"
2025-11-22 21:43:40 +00:00
- name: Fix Permissions and Verify
run: |
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:43:40 +00:00
set -e
echo "🔧 Исправляем права доступа..."
chown -R www-data:www-data /var/www/mnemo_cards
chmod -R 755 /var/www/mnemo_cards
echo "✅ Права исправлены"
echo "🔍 Проверяем nginx после деплоя web..."
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx работает"
# Перезагружаем nginx для применения новых файлов
echo "🔄 Перезагружаем nginx..."
if sudo nginx -t 2>/dev/null; then
sudo systemctl reload nginx
echo "✅ nginx перезагружен"
sleep 2
# Тестируем доступность
if curl -I --max-time 10 https://mnemo-cards.online/ 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ mnemo-cards.online доступен"
else
echo "⚠️ mnemo-cards.online недоступен"
fi
if curl -I --max-time 10 https://code.mnemo-cards.online/ 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ code.mnemo-cards.online доступен"
else
echo "⚠️ code.mnemo-cards.online недоступен"
fi
else
echo "❌ Ошибка в конфигурации nginx!"
sudo nginx -t || true
exit 1
fi
else
echo "❌ nginx не работает! Запускаем..."
sudo systemctl start nginx
sleep 2
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx запущен"
else
echo "❌ Не удалось запустить nginx!"
sudo systemctl status nginx --no-pager || true
exit 1
fi
fi
2025-11-22 21:52:39 +00:00
ENDSSH
final-verification:
name: Final Verification
runs-on: ubuntu-latest
needs: [deploy-backend, deploy-web]
if: always()
steps:
- name: Wait and Verify All Services
run: |
echo "⏳ Ждем завершения всех операций..."
sleep 10
echo "🔍 Финальная проверка доступности всех сайтов..."
2025-11-22 22:14:58 +00:00
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=30 -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
2025-11-22 21:52:39 +00:00
set -e
echo "📊 Статус всех сервисов:"
# Проверяем nginx
if sudo systemctl is-active --quiet nginx; then
echo "✅ nginx: работает"
else
echo "❌ nginx: НЕ работает!"
sudo systemctl status nginx --no-pager || true
fi
# Проверяем backend
if sudo systemctl is-active --quiet mnemo_cards_server; then
echo "✅ backend: работает"
else
echo "❌ backend: НЕ работает!"
sudo systemctl status mnemo_cards_server --no-pager || true
fi
echo ""
echo "🌐 Тестируем доступность сайтов:"
# Тестируем все сайты
sites=("https://mnemo-cards.online/" "https://api.mnemo-cards.online/" "https://code.mnemo-cards.online/" "https://vscode.mnemo-cards.online/")
for site in "${sites[@]}"; do
if curl -I --max-time 10 "$site" 2>/dev/null | grep -q "200\|301\|302"; then
echo "✅ $site доступен"
else
echo "❌ $site НЕДОСТУПЕН!"
curl -I --max-time 5 "$site" || true
fi
done
echo ""
echo "🎉 Проверка завершена!"
ENDSSH