From 41f1c402edba195299f3a7b629d6c09e30f22156 Mon Sep 17 00:00:00 2001 From: lborv Date: Mon, 13 Oct 2025 20:59:12 +0300 Subject: [PATCH 1/4] feat: Add test deployment workflow and setup documentation - Implemented a new GitHub Actions workflow for testing deployments (`test-deployment.yml`). - Created detailed deployment documentation (`DEPLOYMENT-README.md`, `DEPLOYMENT.md`, `QUICK-START.md`) for setting up the testing server and configuring GitHub secrets. - Added a setup script (`setup-testing-server.sh`) for automating the environment setup on the testing server, including Docker, Nginx, and user configurations. - Included monitoring and cleanup scripts for managing deployments on the server. --- .env.testing.example | 64 ++++++ .gitea/workflows/deploy-testing.yml | 247 ++++++++++++++++++++++ .gitea/workflows/test-deployment.yml | 237 ++++++++++++++++++++++ DEPLOYMENT-README.md | 238 ++++++++++++++++++++++ DEPLOYMENT.md | 209 +++++++++++++++++++ QUICK-START.md | 178 ++++++++++++++++ scripts/setup-testing-server.sh | 293 +++++++++++++++++++++++++++ 7 files changed, 1466 insertions(+) create mode 100644 .env.testing.example create mode 100644 .gitea/workflows/deploy-testing.yml create mode 100644 .gitea/workflows/test-deployment.yml create mode 100644 DEPLOYMENT-README.md create mode 100644 DEPLOYMENT.md create mode 100644 QUICK-START.md create mode 100755 scripts/setup-testing-server.sh diff --git a/.env.testing.example b/.env.testing.example new file mode 100644 index 0000000..8df2c2e --- /dev/null +++ b/.env.testing.example @@ -0,0 +1,64 @@ +# Environment Variables for Testing Deployments + +# Copy this file to .env in your deployment directory + +# ================================ +# APPLICATION SETTINGS +# ================================ +NODE_ENV=testing +APP_PORT=3123 # Will be dynamically set to 3000 + PR_NUMBER + +# ================================ +# DATABASE CONFIGURATION +# ================================ +DB_HOST=mariadb +DB_PORT=3306 +DB_DATABASE=low_code_engine_pr_123 # Will be dynamically set +DB_USERNAME=app_user +DB_PASSWORD=your_strong_password_here +DB_ROOT_PASSWORD=your_strong_root_password_here + +# ================================ +# REDIS CONFIGURATION +# ================================ +REDIS_HOST=redis +REDIS_PORT=6379 + +# ================================ +# API TOKENS (if needed) +# ================================ +# API_TOKEN_SECRET=your_api_token_secret +# ADMIN_TOKEN=your_admin_token + +# ================================ +# EXTERNAL SERVICES (if any) +# ================================ +# EXTERNAL_API_URL=https://api.example.com +# EXTERNAL_API_KEY=your_external_api_key + +# ================================ +# LOGGING & MONITORING +# ================================ +LOG_LEVEL=debug +# SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-id + +# ================================ +# PERFORMANCE SETTINGS +# ================================ +# MAX_CONNECTIONS=100 +# TIMEOUT=30000 + +# ================================ +# FEATURE FLAGS (if any) +# ================================ +# ENABLE_FEATURE_X=true +# ENABLE_DEBUG_MODE=true + +# ================================ +# NOTES FOR DEPLOYMENT +# ================================ +# - This file is automatically generated by GitHub Actions +# - PR_NUMBER will be substituted with actual PR number +# - Ports will be calculated as BASE_PORT + PR_NUMBER +# - Database name will include PR number for isolation +# - Do not commit this file with real secrets! \ No newline at end of file diff --git a/.gitea/workflows/deploy-testing.yml b/.gitea/workflows/deploy-testing.yml new file mode 100644 index 0000000..1c6e0e3 --- /dev/null +++ b/.gitea/workflows/deploy-testing.yml @@ -0,0 +1,247 @@ +name: Deploy to Testing Server + +on: + pull_request: + branches: + - develop + types: [opened, synchronize, reopened] + +jobs: + deploy: + name: Deploy to Testing Server + runs-on: ubuntu-latest + if: github.event.pull_request.merged == false # Только для открытых PR + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "18" + cache: "yarn" + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Run linting + run: yarn lint:check + + - name: Build application + run: yarn build + + - name: Build Docker image + run: | + docker build -t low-code-engine:testing-${{ github.event.pull_request.number }} . + + - name: Save Docker image + run: | + docker save low-code-engine:testing-${{ github.event.pull_request.number }} | gzip > low-code-engine-testing.tar.gz + + - name: Deploy to Testing Server + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + # Создаем директорию для приложения если её нет + mkdir -p /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + + # Останавливаем существующие контейнеры если они есть + docker-compose down || true + + # Удаляем старые образы + docker image prune -f || true + + - name: Copy files to server + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + source: "low-code-engine-testing.tar.gz,docker-compose.yml,docker/" + target: "/opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}/" + + - name: Load and run Docker containers + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + + # Загружаем Docker образ + gunzip -c low-code-engine-testing.tar.gz | docker load + + # Создаем .env файл для тестового окружения + cat > .env << EOF + NODE_ENV=testing + DB_ROOT_PASSWORD=${{ secrets.TESTING_DB_ROOT_PASSWORD }} + DB_DATABASE=low_code_engine_pr_${{ github.event.pull_request.number }} + DB_USERNAME=${{ secrets.TESTING_DB_USERNAME }} + DB_PASSWORD=${{ secrets.TESTING_DB_PASSWORD }} + DB_PORT=3306 + APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }} + REDIS_HOST=redis + REDIS_PORT=6379 + EOF + + # Создаем docker-compose.override.yml для тестового окружения + cat > docker-compose.override.yml << EOF + version: "3.8" + services: + app: + image: low-code-engine:testing-${{ github.event.pull_request.number }} + ports: + - "\${APP_PORT}:3000" + environment: + NODE_ENV: testing + DB_HOST: mariadb + DB_PORT: 3306 + DB_USERNAME: \${DB_USERNAME} + DB_PASSWORD: \${DB_PASSWORD} + DB_DATABASE: \${DB_DATABASE} + REDIS_HOST: redis + REDIS_PORT: 6379 + + mariadb: + ports: + - "${{ vars.TESTING_BASE_DB_PORT || 3306 }}${{ github.event.pull_request.number }}:3306" + environment: + MYSQL_DATABASE: \${DB_DATABASE} + + redis: + image: redis:7-alpine + ports: + - "${{ vars.TESTING_BASE_REDIS_PORT || 6379 }}${{ github.event.pull_request.number }}:6379" + EOF + + # Запускаем контейнеры + docker-compose up -d + + # Ждем пока база данных запустится + sleep 30 + + # Запускаем миграции + docker-compose exec -T app yarn migration:run || true + + # Проверяем статус контейнеров + docker-compose ps + + - name: Health check + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + + # Проверяем доступность приложения + APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }} + + for i in {1..10}; do + if curl -f http://localhost:$APP_PORT/health > /dev/null 2>&1; then + echo "✅ Application is healthy on port $APP_PORT" + break + fi + echo "⏳ Waiting for application to start... (attempt $i/10)" + sleep 10 + done + + - name: Comment PR with deployment info + uses: actions/github-script@v7 + with: + script: | + const prNumber = context.payload.pull_request.number; + const appPort = ${{ vars.TESTING_BASE_PORT || 3000 }} + prNumber; + const dbPort = ${{ vars.TESTING_BASE_DB_PORT || 3306 }} + prNumber; + const redisPort = ${{ vars.TESTING_BASE_REDIS_PORT || 6379 }} + prNumber; + + const comment = `## 🚀 Testing Deployment + + Your PR has been deployed to the testing server! + + **Deployment Details:** + - 🌐 Application URL: http://${{ secrets.TESTING_SERVER_HOST }}:${appPort} + - 🗄️ Database Port: ${dbPort} + - 🔴 Redis Port: ${redisPort} + - 📁 Server Path: \`/opt/low-code-engine/testing-pr-${prNumber}\` + + **Available Commands on Server:** + \`\`\`bash + cd /opt/low-code-engine/testing-pr-${prNumber} + docker-compose logs app # View application logs + docker-compose logs mariadb # View database logs + docker-compose ps # Check container status + docker-compose exec app yarn migration:run # Run migrations + \`\`\` + + > **Note:** This deployment will be automatically cleaned up when the PR is closed or merged. + `; + + github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + cleanup: + name: Cleanup on PR Close + runs-on: ubuntu-latest + if: github.event.pull_request.state == 'closed' + + steps: + - name: Cleanup testing environment + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + + # Останавливаем и удаляем контейнеры + docker-compose down -v || true + + # Удаляем Docker образ + docker rmi low-code-engine:testing-${{ github.event.pull_request.number }} || true + + # Удаляем директорию развертывания + cd .. + rm -rf testing-pr-${{ github.event.pull_request.number }} + + echo "✅ Cleanup completed for PR #${{ github.event.pull_request.number }}" + + - name: Comment PR with cleanup info + uses: actions/github-script@v7 + with: + script: | + const comment = `## 🧹 Testing Environment Cleaned Up + + The testing deployment for this PR has been cleaned up: + - ✅ Docker containers stopped and removed + - ✅ Docker images cleaned up + - ✅ Server files removed + + Thank you for testing! 🎉 + `; + + github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); diff --git a/.gitea/workflows/test-deployment.yml b/.gitea/workflows/test-deployment.yml new file mode 100644 index 0000000..d1c6032 --- /dev/null +++ b/.gitea/workflows/test-deployment.yml @@ -0,0 +1,237 @@ +name: Test Deployment Workflow + +# Этот workflow можно запустить вручную для тестирования процесса развертывания +on: + workflow_dispatch: + inputs: + pr_number: + description: "PR number to simulate" + required: true + default: "999" + type: string + cleanup: + description: "Run cleanup after deployment" + required: false + default: false + type: boolean + +jobs: + test-deployment: + name: Test Deployment Process + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "18" + cache: "yarn" + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Run tests + run: | + # Add your test commands here + echo "Running tests..." + yarn lint:check || echo "Linting completed with warnings" + + - name: Build application + run: yarn build + + - name: Build Docker image + run: | + docker build -t low-code-engine:test-${{ inputs.pr_number }} . + echo "Docker image built successfully" + + - name: Test Docker image + run: | + # Test that the image runs correctly + docker run -d --name test-app -p 3000:3000 low-code-engine:test-${{ inputs.pr_number }} + sleep 10 + + # Try to connect to the app + if curl -f http://localhost:3000/health > /dev/null 2>&1; then + echo "✅ Application is responding" + else + echo "❌ Application is not responding" + docker logs test-app + fi + + docker stop test-app + docker rm test-app + + - name: Save Docker image + run: | + docker save low-code-engine:test-${{ inputs.pr_number }} | gzip > low-code-engine-test.tar.gz + ls -lh low-code-engine-test.tar.gz + + - name: Test SSH connection + if: ${{ secrets.TESTING_SERVER_HOST }} + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + echo "✅ SSH connection successful" + echo "Server info:" + uname -a + docker --version + docker-compose --version + df -h /opt/low-code-engine + echo "Available ports for testing:" + netstat -tln | grep ":30[0-9][0-9]" | head -5 || echo "No testing ports in use" + + - name: Test file transfer + if: ${{ secrets.TESTING_SERVER_HOST }} + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + source: "low-code-engine-test.tar.gz" + target: "/tmp/" + + - name: Test deployment simulation + if: ${{ secrets.TESTING_SERVER_HOST }} + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + echo "Testing deployment simulation for PR #${{ inputs.pr_number }}" + + # Create test directory + mkdir -p /opt/low-code-engine/test-pr-${{ inputs.pr_number }} + cd /opt/low-code-engine/test-pr-${{ inputs.pr_number }} + + # Copy test file + cp /tmp/low-code-engine-test.tar.gz . + + # Test image loading + gunzip -c low-code-engine-test.tar.gz | docker load + + echo "✅ Test deployment simulation completed" + + # Cleanup test files + rm -f low-code-engine-test.tar.gz /tmp/low-code-engine-test.tar.gz + docker rmi low-code-engine:test-${{ inputs.pr_number }} || true + cd .. + rm -rf test-pr-${{ inputs.pr_number }} + + - name: Cleanup on failure + if: failure() && secrets.TESTING_SERVER_HOST + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + # Cleanup any test artifacts + rm -f /tmp/low-code-engine-test.tar.gz + rm -rf /opt/low-code-engine/test-pr-${{ inputs.pr_number }} + docker rmi low-code-engine:test-${{ inputs.pr_number }} || true + echo "🧹 Cleanup completed" + + test-health-endpoints: + name: Test Health Endpoints + runs-on: ubuntu-latest + needs: test-deployment + if: ${{ secrets.TESTING_SERVER_HOST }} + + steps: + - name: Test server health endpoints + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.TESTING_SERVER_HOST }} + username: ${{ secrets.TESTING_SERVER_USER }} + key: ${{ secrets.TESTING_SERVER_SSH_KEY }} + port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + script: | + echo "Testing health check endpoints..." + + # Test monitoring script + if [ -f /usr/local/bin/monitor-deployments ]; then + echo "✅ Monitor script exists" + /usr/local/bin/monitor-deployments | head -20 + else + echo "❌ Monitor script not found" + fi + + # Test cleanup script + if [ -f /usr/local/bin/cleanup-old-deployments ]; then + echo "✅ Cleanup script exists" + else + echo "❌ Cleanup script not found" + fi + + # Test nginx configuration + if command -v nginx &> /dev/null; then + echo "✅ Nginx is installed" + nginx -t 2>&1 | head -5 + else + echo "❌ Nginx not installed" + fi + + # Test docker access + docker ps | head -5 + echo "Docker system info:" + docker system df + + security-check: + name: Security Check + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run security audit + run: | + echo "Running security checks..." + + # Check for secrets in code + if grep -r "password\|secret\|key" --include="*.ts" --include="*.js" --include="*.json" src/ | grep -v "// TODO\|console.log"; then + echo "❌ Potential secrets found in code" + exit 1 + else + echo "✅ No secrets found in source code" + fi + + # Check Docker image for security issues + echo "Building secure Docker image..." + docker build -t security-test . + + # Basic security checks + echo "Checking Docker image user..." + docker run --rm security-test whoami | grep -v root || echo "✅ Not running as root" + + docker rmi security-test + + - name: Check workflow security + run: | + echo "Checking workflow file security..." + + # Check that secrets are properly referenced + if grep -E '\$\{\{\s*secrets\.' .github/workflows/*.yml > /dev/null; then + echo "✅ Secrets properly referenced" + else + echo "❌ No secrets found in workflows" + fi + + # Check for hardcoded values + if grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' .github/workflows/*.yml; then + echo "❌ Hardcoded IP addresses found" + exit 1 + else + echo "✅ No hardcoded IP addresses" + fi diff --git a/DEPLOYMENT-README.md b/DEPLOYMENT-README.md new file mode 100644 index 0000000..5d30bec --- /dev/null +++ b/DEPLOYMENT-README.md @@ -0,0 +1,238 @@ +# 🚀 Автоматическое развертывание на тестовом сервере + +## Обзор + +Этот репозиторий содержит GitHub Actions workflow для автоматического развертывания приложения на тестовом сервере при создании Pull Request в ветку `develop`. Каждый PR получает свою изолированную среду тестирования. + +## 📁 Структура файлов + +``` +.github/workflows/ +├── deploy-testing.yml # Основной workflow для развертывания +└── test-deployment.yml # Workflow для тестирования развертывания + +scripts/ +└── setup-testing-server.sh # Скрипт настройки тестового сервера + +DEPLOYMENT.md # Подробная документация по настройке +QUICK-START.md # Быстрый старт +.env.testing.example # Пример переменных окружения +``` + +## ⚡ Быстрый старт + +### 1. Настройте тестовый сервер + +```bash +# На вашем тестовом сервере выполните: +curl -sSL https://raw.githubusercontent.com/YOUR_USERNAME/YOUR_REPO/main/scripts/setup-testing-server.sh | bash +``` + +### 2. Добавьте GitHub Secrets + +В настройках репозитория добавьте следующие секреты: + +``` +TESTING_SERVER_HOST=your.server.ip.address +TESTING_SERVER_USER=deploy +TESTING_SERVER_SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY----- +your private SSH key content +-----END OPENSSH PRIVATE KEY----- +TESTING_DB_ROOT_PASSWORD=strong_root_password +TESTING_DB_USERNAME=app_user +TESTING_DB_PASSWORD=strong_user_password +``` + +### 3. Создайте Pull Request + +1. Создайте новую ветку от `develop` +2. Внесите изменения +3. Создайте Pull Request в ветку `develop` +4. GitHub Actions автоматически развернет ваше приложение +5. Проверьте комментарий в PR с ссылкой на развертывание + +## 🏗️ Как это работает + +### Workflow процесс + +1. **Триггер**: Pull Request в ветку `develop` +2. **Сборка**: Установка зависимостей, линтинг, сборка приложения +3. **Docker**: Создание Docker образа +4. **Развертывание**: Копирование файлов на сервер и запуск контейнеров +5. **Проверка**: Health check и уведомление в PR +6. **Очистка**: Автоматическая очистка при закрытии PR + +### Архитектура развертывания + +``` +Тестовый сервер +├── /opt/low-code-engine/ +│ ├── testing-pr-123/ # Изолированная среда для PR #123 +│ │ ├── docker-compose.yml +│ │ ├── docker-compose.override.yml +│ │ ├── .env +│ │ └── docker/ +│ ├── testing-pr-124/ # Изолированная среда для PR #124 +│ └── ... +└── Порты: + ├── Приложение: 3000 + PR_NUMBER + ├── База данных: 3300 + PR_NUMBER + └── Redis: 6300 + PR_NUMBER +``` + +## 🔧 Конфигурация + +### Порты по умолчанию + +- **Приложение**: 3000 + номер PR (например, PR #123 → порт 3123) +- **База данных**: 3300 + номер PR (например, PR #123 → порт 3423) +- **Redis**: 6300 + номер PR (например, PR #123 → порт 6423) + +### Переменные окружения + +Можно настроить базовые порты через GitHub Variables: + +``` +TESTING_BASE_PORT=3000 # Базовый порт приложения +TESTING_BASE_DB_PORT=3300 # Базовый порт БД +TESTING_BASE_REDIS_PORT=6300 # Базовый порт Redis +``` + +## 📊 Мониторинг + +### Команды на сервере + +```bash +# Мониторинг всех развертываний +sudo /usr/local/bin/monitor-deployments + +# Очистка старых развертываний (старше 7 дней) +sudo /usr/local/bin/cleanup-old-deployments + +# Просмотр логов конкретного PR +cd /opt/low-code-engine/testing-pr-123 +docker-compose logs -f app + +# Проверка статуса +docker-compose ps +``` + +### Пример вывода мониторинга + +``` +=== Testing Deployments Status === +Date: Mon Oct 13 10:30:00 UTC 2025 + +Active Deployments: + PR #123: Running on port 3123 + Status: ✅ Healthy + PR #124: Running on port 3124 + Status: ❌ Unhealthy + +=== System Resources === +Disk Usage: +/dev/sda1 20G 8.5G 11G 45% /opt/low-code-engine +``` + +## 🔒 Безопасность + +### Рекомендации + +1. **SSH ключи**: Используйте отдельный SSH ключ только для развертывания +2. **Пользователь**: Создайте отдельного пользователя `deploy` с минимальными правами +3. **Firewall**: Настройте фаервол для ограничения доступа +4. **Пароли**: Используйте сильные пароли для базы данных +5. **Автоочистка**: Включена автоматическая очистка старых развертываний + +### Настройка firewall + +```bash +sudo ufw enable +sudo ufw allow ssh +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +sudo ufw allow 3000:3999/tcp # Порты приложений +sudo ufw allow 3300:3999/tcp # Порты БД +sudo ufw allow 6300:6999/tcp # Порты Redis +``` + +## 🧪 Тестирование + +### Тестирование самого процесса развертывания + +Запустите тестовый workflow вручную: + +1. Перейдите в Actions → Test Deployment Workflow +2. Нажмите "Run workflow" +3. Укажите номер PR для симуляции (например, 999) +4. Запустите тест + +### Локальное тестирование + +```bash +# Сборка и тест Docker образа локально +docker build -t low-code-engine:local . +docker run -d --name test-app -p 3000:3000 low-code-engine:local + +# Проверка health endpoint +curl http://localhost:3000/health + +# Очистка +docker stop test-app && docker rm test-app +``` + +## 📚 Дополнительная документация + +- [DEPLOYMENT.md](./DEPLOYMENT.md) - Подробная документация по настройке +- [QUICK-START.md](./QUICK-START.md) - Краткое руководство по быстрому старту +- [.env.testing.example](./.env.testing.example) - Пример переменных окружения + +## 🛠️ Troubleshooting + +### Часто встречающиеся проблемы + +#### "Permission denied" при SSH + +```bash +# Проверьте права на сервере +sudo ls -la /home/deploy/.ssh/ +sudo chmod 700 /home/deploy/.ssh/ +sudo chmod 600 /home/deploy/.ssh/authorized_keys +``` + +#### Порт уже занят + +```bash +# Найдите процесс +sudo netstat -tulpn | grep :3123 + +# Остановите развертывание +cd /opt/low-code-engine/testing-pr-123 +docker-compose down +``` + +#### Нехватка места на диске + +```bash +# Очистка Docker +docker system prune -a -f + +# Очистка старых развертываний +sudo /usr/local/bin/cleanup-old-deployments +``` + +## 🤝 Вклад в развитие + +1. Создайте форк репозитория +2. Создайте ветку для новой функции +3. Внесите изменения +4. Создайте Pull Request +5. Протестируйте развертывание + +## 📝 Лицензия + +Этот проект использует лицензию, указанную в основном проекте. + +--- + +💡 **Совет**: Начните с [QUICK-START.md](./QUICK-START.md) для быстрой настройки, затем обратитесь к [DEPLOYMENT.md](./DEPLOYMENT.md) для подробной конфигурации. diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..8e5567b --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,209 @@ +# GitHub Actions Deployment Setup + +Этот документ описывает настройку автоматического развертывания на тестовом сервере при создании Pull Request в ветку `develop`. + +## Требуемые GitHub Secrets + +Перейдите в настройки репозитория → Settings → Secrets and variables → Actions и добавьте следующие секреты: + +### SSH Connection + +- `TESTING_SERVER_HOST` - IP адрес или домен тестового сервера +- `TESTING_SERVER_USER` - Пользователь для SSH подключения (например: `deploy`) +- `TESTING_SERVER_SSH_KEY` - Приватный SSH ключ для подключения к серверу +- `TESTING_SERVER_PORT` - (опционально) Порт SSH (по умолчанию 22) + +### Database Configuration + +- `TESTING_DB_ROOT_PASSWORD` - Root пароль для MariaDB +- `TESTING_DB_USERNAME` - Пользователь базы данных +- `TESTING_DB_PASSWORD` - Пароль пользователя базы данных + +## Требуемые GitHub Variables + +Перейдите в настройки репозитория → Settings → Secrets and variables → Actions → Variables и добавьте: + +- `TESTING_BASE_PORT` - Базовый порт для приложений (по умолчанию: 3000) +- `TESTING_BASE_DB_PORT` - Базовый порт для баз данных (по умолчанию: 3306) +- `TESTING_BASE_REDIS_PORT` - Базовый порт для Redis (по умолчанию: 6379) + +## Настройка тестового сервера + +### 1. Установка Docker и Docker Compose + +```bash +# Обновление системы +sudo apt update && sudo apt upgrade -y + +# Установка Docker +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh + +# Добавление пользователя в группу docker +sudo usermod -aG docker $USER + +# Установка Docker Compose +sudo apt install docker-compose-plugin -y +``` + +### 2. Создание пользователя для развертывания + +```bash +# Создание пользователя +sudo useradd -m -s /bin/bash deploy +sudo usermod -aG docker deploy + +# Создание директории для SSH ключей +sudo mkdir -p /home/deploy/.ssh +sudo chmod 700 /home/deploy/.ssh + +# Добавление публичного SSH ключа +sudo nano /home/deploy/.ssh/authorized_keys +# Вставьте публичный ключ, соответствующий приватному ключу в TESTING_SERVER_SSH_KEY + +sudo chmod 600 /home/deploy/.ssh/authorized_keys +sudo chown -R deploy:deploy /home/deploy/.ssh + +# Создание директории для приложений +sudo mkdir -p /opt/low-code-engine +sudo chown deploy:deploy /opt/low-code-engine +``` + +### 3. Настройка Nginx (опционально) + +Если хотите использовать доменные имена вместо портов: + +```bash +sudo apt install nginx -y + +# Создание конфигурации для тестовых приложений +sudo nano /etc/nginx/sites-available/testing-apps +``` + +Содержимое файла: + +```nginx +server { + listen 80; + server_name ~^pr-(?\d+)\.testing\.yourdomain\.com$; + + location / { + set $app_port 3000$pr_number; + proxy_pass http://127.0.0.1:$app_port; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +```bash +# Активация конфигурации +sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl reload nginx +``` + +## Как работает развертывание + +### Процесс развертывания + +1. **Trigger**: Создание или обновление Pull Request в ветку `develop` +2. **Build**: Сборка приложения и создание Docker образа +3. **Deploy**: Копирование файлов на сервер и запуск контейнеров +4. **Health Check**: Проверка доступности приложения +5. **Comment**: Добавление комментария в PR с информацией о развертывании + +### Структура на сервере + +``` +/opt/low-code-engine/ +├── testing-pr-123/ # Отдельная директория для каждого PR +│ ├── docker-compose.yml # Основной docker-compose файл +│ ├── docker-compose.override.yml # Переопределения для тестинга +│ ├── .env # Переменные окружения +│ ├── docker/ # Docker конфигурации +│ └── low-code-engine-testing.tar.gz # Docker образ +├── testing-pr-124/ +└── ... +``` + +### Порты + +Каждому PR назначаются уникальные порты: + +- Приложение: `TESTING_BASE_PORT + PR_NUMBER` (например: 3000 + 123 = 3123) +- База данных: `TESTING_BASE_DB_PORT + PR_NUMBER` (например: 3306 + 123 = 3429) +- Redis: `TESTING_BASE_REDIS_PORT + PR_NUMBER` (например: 6379 + 123 = 6502) + +### Cleanup + +При закрытии или мердже PR автоматически происходит: + +1. Остановка и удаление контейнеров +2. Удаление Docker образов +3. Удаление файлов на сервере +4. Добавление комментария об очистке + +## Безопасность + +1. **SSH ключи**: Используйте отдельный SSH ключ только для развертывания +2. **Пользователь**: Создайте отдельного пользователя с минимальными правами +3. **Firewall**: Настройте фаервол для ограничения доступа к портам +4. **SSL/TLS**: Рассмотрите использование SSL сертификатов для HTTPS + +## Мониторинг и логи + +### Просмотр логов приложения + +```bash +cd /opt/low-code-engine/testing-pr-{PR_NUMBER} +docker-compose logs -f app +``` + +### Просмотр статуса контейнеров + +```bash +docker-compose ps +``` + +### Мониторинг ресурсов + +```bash +docker stats +``` + +## Troubleshooting + +### Проблемы с портами + +Если порт занят, проверьте какие приложения его используют: + +```bash +sudo netstat -tulpn | grep :{PORT} +``` + +### Проблемы с Docker + +Очистка неиспользуемых ресурсов: + +```bash +docker system prune -f +``` + +### Проблемы с базой данных + +Проверка подключения к базе данных: + +```bash +docker-compose exec mariadb mysql -u root -p -e "SHOW DATABASES;" +``` + +### Проблемы с миграциями + +Ручной запуск миграций: + +```bash +docker-compose exec app yarn migration:run +``` diff --git a/QUICK-START.md b/QUICK-START.md new file mode 100644 index 0000000..508d9ea --- /dev/null +++ b/QUICK-START.md @@ -0,0 +1,178 @@ +# Quick Start Guide для GitHub Actions Deploy + +## 🚀 Быстрая настройка + +### 1. Настройка тестового сервера + +Запустите на своем тестовом сервере: + +```bash +# Скачать и запустить скрипт настройки +curl -sSL https://raw.githubusercontent.com/YOUR_USERNAME/YOUR_REPO/main/scripts/setup-testing-server.sh | bash +``` + +Или вручную: + +```bash +git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git +cd YOUR_REPO +./scripts/setup-testing-server.sh +``` + +### 2. Настройка SSH ключей + +На тестовом сервере добавьте свой публичный SSH ключ: + +```bash +# Генерация нового SSH ключа (если нужно) +ssh-keygen -t ed25519 -C "github-actions@yourdomain.com" -f ~/.ssh/github_actions + +# Добавление публичного ключа на сервер +sudo -u deploy tee -a /home/deploy/.ssh/authorized_keys < ~/.ssh/github_actions.pub +``` + +### 3. Настройка GitHub Secrets + +В настройках GitHub репозитория (Settings → Secrets and variables → Actions) добавьте: + +**Required Secrets:** + +``` +TESTING_SERVER_HOST=your.server.ip.address +TESTING_SERVER_USER=deploy +TESTING_SERVER_SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY----- +your private key content here +-----END OPENSSH PRIVATE KEY----- +TESTING_DB_ROOT_PASSWORD=your_strong_root_password +TESTING_DB_USERNAME=app_user +TESTING_DB_PASSWORD=your_strong_user_password +``` + +**Optional Variables:** + +``` +TESTING_BASE_PORT=3000 +TESTING_BASE_DB_PORT=3300 +TESTING_BASE_REDIS_PORT=6300 +``` + +### 4. Тестирование + +1. Создайте новую ветку и сделайте изменения +2. Создайте Pull Request в ветку `develop` +3. GitHub Actions автоматически развернет приложение +4. Проверьте комментарий в PR с информацией о развертывании + +## 📝 Полезные команды на сервере + +```bash +# Мониторинг всех развертываний +sudo /usr/local/bin/monitor-deployments + +# Очистка старых развертываний +sudo /usr/local/bin/cleanup-old-deployments + +# Просмотр логов конкретного PR +cd /opt/low-code-engine/testing-pr-123 +docker-compose logs -f app + +# Проверка статуса контейнеров +docker-compose ps + +# Запуск миграций вручную +docker-compose exec app yarn migration:run +``` + +## 🔧 Troubleshooting + +### Проблема: "Permission denied" при SSH подключении + +```bash +# На сервере проверьте права доступа +sudo ls -la /home/deploy/.ssh/ +sudo cat /home/deploy/.ssh/authorized_keys + +# Права должны быть: +# drwx------ deploy deploy .ssh/ +# -rw------- deploy deploy authorized_keys +``` + +### Проблема: Порт уже занят + +```bash +# Найти процесс использующий порт +sudo netstat -tulpn | grep :3123 + +# Остановить все контейнеры для PR +cd /opt/low-code-engine/testing-pr-123 +docker-compose down +``` + +### Проблема: Не хватает места на диске + +```bash +# Очистить Docker ресурсы +docker system prune -a -f + +# Очистить старые развертывания +sudo /usr/local/bin/cleanup-old-deployments +``` + +### Проблема: База данных не запускается + +```bash +# Проверить логи MariaDB +docker-compose logs mariadb + +# Пересоздать контейнер базы данных +docker-compose down +docker-compose up -d mariadb +``` + +## 🌐 Доступ к приложениям + +### По портам (прямой доступ): + +- Приложение: `http://YOUR_SERVER_IP:3000{PR_NUMBER}` +- База данных: `YOUR_SERVER_IP:3300{PR_NUMBER}` +- Redis: `YOUR_SERVER_IP:6300{PR_NUMBER}` + +### Через домены (если настроен Nginx): + +- Приложение: `http://pr-{PR_NUMBER}.testing.yourdomain.com` + +Пример для PR #123: + +- Приложение: `http://your.server.ip:3123` или `http://pr-123.testing.yourdomain.com` +- База данных: `your.server.ip:3423` +- Redis: `your.server.ip:6423` + +## 📊 Мониторинг + +Проверить статус всех развертываний: + +```bash +sudo /usr/local/bin/monitor-deployments +``` + +Вывод будет примерно таким: + +``` +=== Testing Deployments Status === +Date: Mon Oct 13 10:30:00 UTC 2025 + +Active Deployments: + PR #123: Running on port 3123 + Status: ✅ Healthy + PR #124: Running on port 3124 + Status: ❌ Unhealthy + +=== System Resources === +Disk Usage: +/dev/sda1 20G 8.5G 11G 45% /opt/low-code-engine + +Docker Usage: +TYPE TOTAL ACTIVE SIZE RECLAIMABLE +Images 15 8 2.5GB 1.2GB (48%) +Containers 16 8 150MB 80MB (53%) +``` diff --git a/scripts/setup-testing-server.sh b/scripts/setup-testing-server.sh new file mode 100755 index 0000000..e579134 --- /dev/null +++ b/scripts/setup-testing-server.sh @@ -0,0 +1,293 @@ +#!/bin/bash + +# Quick setup script for testing server +# Run this script on your testing server to set up the environment + +set -e + +echo "🚀 Setting up testing server for Low Code Engine deployments..." + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Function to print colored output +print_status() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Check if running as root +if [[ $EUID -eq 0 ]]; then + print_error "This script should not be run as root for security reasons" + exit 1 +fi + +# Update system +print_status "Updating system packages..." +sudo apt update && sudo apt upgrade -y + +# Install Docker +print_status "Installing Docker..." +if ! command -v docker &> /dev/null; then + curl -fsSL https://get.docker.com -o get-docker.sh + sudo sh get-docker.sh + sudo usermod -aG docker $USER + rm get-docker.sh + print_status "Docker installed successfully" +else + print_status "Docker is already installed" +fi + +# Install Docker Compose +print_status "Installing Docker Compose..." +if ! command -v docker-compose &> /dev/null; then + sudo apt install docker-compose-plugin -y + print_status "Docker Compose installed successfully" +else + print_status "Docker Compose is already installed" +fi + +# Create deploy user +print_status "Creating deploy user..." +if ! id "deploy" &>/dev/null; then + sudo useradd -m -s /bin/bash deploy + sudo usermod -aG docker deploy + print_status "Deploy user created successfully" +else + print_status "Deploy user already exists" +fi + +# Setup SSH directory for deploy user +print_status "Setting up SSH for deploy user..." +sudo mkdir -p /home/deploy/.ssh +sudo chmod 700 /home/deploy/.ssh +sudo touch /home/deploy/.ssh/authorized_keys +sudo chmod 600 /home/deploy/.ssh/authorized_keys +sudo chown -R deploy:deploy /home/deploy/.ssh + +# Create application directory +print_status "Creating application directory..." +sudo mkdir -p /opt/low-code-engine +sudo chown deploy:deploy /opt/low-code-engine + +# Install nginx (optional) +print_status "Installing Nginx..." +if ! command -v nginx &> /dev/null; then + sudo apt install nginx -y + print_status "Nginx installed successfully" +else + print_status "Nginx is already installed" +fi + +# Create nginx configuration for testing apps +print_status "Creating Nginx configuration..." +sudo tee /etc/nginx/sites-available/testing-apps > /dev/null <\d+)\.testing\.(.+)$; + + # Health check endpoint + location /health { + set \$app_port 3000\$pr_number; + proxy_pass http://127.0.0.1:\$app_port; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + + # Add CORS headers for API calls + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always; + } + + # Main application + location / { + set \$app_port 3000\$pr_number; + proxy_pass http://127.0.0.1:\$app_port; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} + +# Direct port access (fallback) +server { + listen 80 default_server; + server_name _; + + location / { + return 200 'Testing Server is running. Use pr-{NUMBER}.testing.yourdomain.com to access deployments.'; + add_header Content-Type text/plain; + } +} +EOF + +# Enable nginx configuration +if [ ! -L /etc/nginx/sites-enabled/testing-apps ]; then + sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/ +fi + +# Remove default nginx site +if [ -L /etc/nginx/sites-enabled/default ]; then + sudo rm /etc/nginx/sites-enabled/default +fi + +# Test and reload nginx +sudo nginx -t && sudo systemctl reload nginx +print_status "Nginx configured successfully" + +# Install useful tools +print_status "Installing additional tools..." +sudo apt install -y curl wget htop netstat-nat jq + +# Create cleanup script +print_status "Creating cleanup script..." +sudo tee /usr/local/bin/cleanup-old-deployments > /dev/null <<'EOF' +#!/bin/bash +# Cleanup script for old testing deployments + +DAYS_OLD=7 +DEPLOYMENT_DIR="/opt/low-code-engine" + +echo "Cleaning up deployments older than ${DAYS_OLD} days..." + +find ${DEPLOYMENT_DIR} -name "testing-pr-*" -type d -mtime +${DAYS_OLD} | while read dir; do + echo "Cleaning up: $dir" + + # Stop containers if running + if [ -f "$dir/docker-compose.yml" ]; then + cd "$dir" + docker-compose down -v 2>/dev/null || true + fi + + # Remove directory + rm -rf "$dir" + echo "Removed: $dir" +done + +# Clean up unused Docker resources +docker system prune -f +docker image prune -f + +echo "Cleanup completed" +EOF + +sudo chmod +x /usr/local/bin/cleanup-old-deployments + +# Create cron job for cleanup +print_status "Setting up automatic cleanup..." +(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/cleanup-old-deployments") | crontab - + +# Create monitoring script +print_status "Creating monitoring script..." +sudo tee /usr/local/bin/monitor-deployments > /dev/null <<'EOF' +#!/bin/bash +# Monitoring script for testing deployments + +DEPLOYMENT_DIR="/opt/low-code-engine" + +echo "=== Testing Deployments Status ===" +echo "Date: $(date)" +echo + +# Show active deployments +echo "Active Deployments:" +find ${DEPLOYMENT_DIR} -name "testing-pr-*" -type d | sort | while read dir; do + pr_number=$(basename "$dir" | sed 's/testing-pr-//') + if [ -f "$dir/docker-compose.yml" ]; then + cd "$dir" + status=$(docker-compose ps -q | wc -l) + if [ "$status" -gt 0 ]; then + app_port=$((3000 + pr_number)) + echo " PR #${pr_number}: Running on port ${app_port}" + # Check if app is responding + if curl -s --max-time 5 "http://localhost:${app_port}/health" > /dev/null 2>&1; then + echo " Status: ✅ Healthy" + else + echo " Status: ❌ Unhealthy" + fi + else + echo " PR #${pr_number}: Stopped" + fi + fi +done + +echo +echo "=== System Resources ===" +echo "Disk Usage:" +df -h /opt/low-code-engine +echo +echo "Docker Usage:" +docker system df +echo +echo "Memory Usage:" +free -h +EOF + +sudo chmod +x /usr/local/bin/monitor-deployments + +# Setup firewall (optional but recommended) +print_status "Configuring firewall..." +if command -v ufw &> /dev/null; then + sudo ufw --force enable + sudo ufw allow ssh + sudo ufw allow 80/tcp + sudo ufw allow 443/tcp + # Allow port range for testing apps (3000-3999) + sudo ufw allow 3000:3999/tcp + # Allow port range for databases (3300-3999) + sudo ufw allow 3300:3999/tcp + # Allow port range for redis (6300-6999) + sudo ufw allow 6300:6999/tcp + print_status "Firewall configured" +else + print_warning "UFW not found, skipping firewall configuration" +fi + +print_status "Setup completed successfully!" +echo +echo "🎉 Your testing server is ready!" +echo +echo "Next steps:" +echo "1. Add your public SSH key to /home/deploy/.ssh/authorized_keys" +echo "2. Configure your GitHub repository secrets:" +echo " - TESTING_SERVER_HOST: $(curl -s ifconfig.me 2>/dev/null || echo 'YOUR_SERVER_IP')" +echo " - TESTING_SERVER_USER: deploy" +echo " - TESTING_SERVER_SSH_KEY: (your private SSH key)" +echo " - TESTING_DB_ROOT_PASSWORD: (choose a strong password)" +echo " - TESTING_DB_USERNAME: app_user" +echo " - TESTING_DB_PASSWORD: (choose a strong password)" +echo +echo "Useful commands:" +echo " - Monitor deployments: sudo /usr/local/bin/monitor-deployments" +echo " - Cleanup old deployments: sudo /usr/local/bin/cleanup-old-deployments" +echo " - Check nginx status: sudo systemctl status nginx" +echo " - View nginx logs: sudo journalctl -u nginx -f" +echo +print_warning "Please reboot the server or run 'newgrp docker' to apply Docker group changes" +EOF \ No newline at end of file From aaa86804211d6b8884291c01d9c292f3bb1aa66c Mon Sep 17 00:00:00 2001 From: lborv Date: Mon, 13 Oct 2025 21:00:50 +0300 Subject: [PATCH 2/4] chore: Remove outdated deployment documentation files --- DEPLOYMENT-README.md | 238 ------------------------------------------- QUICK-START.md | 178 -------------------------------- 2 files changed, 416 deletions(-) delete mode 100644 DEPLOYMENT-README.md delete mode 100644 QUICK-START.md diff --git a/DEPLOYMENT-README.md b/DEPLOYMENT-README.md deleted file mode 100644 index 5d30bec..0000000 --- a/DEPLOYMENT-README.md +++ /dev/null @@ -1,238 +0,0 @@ -# 🚀 Автоматическое развертывание на тестовом сервере - -## Обзор - -Этот репозиторий содержит GitHub Actions workflow для автоматического развертывания приложения на тестовом сервере при создании Pull Request в ветку `develop`. Каждый PR получает свою изолированную среду тестирования. - -## 📁 Структура файлов - -``` -.github/workflows/ -├── deploy-testing.yml # Основной workflow для развертывания -└── test-deployment.yml # Workflow для тестирования развертывания - -scripts/ -└── setup-testing-server.sh # Скрипт настройки тестового сервера - -DEPLOYMENT.md # Подробная документация по настройке -QUICK-START.md # Быстрый старт -.env.testing.example # Пример переменных окружения -``` - -## ⚡ Быстрый старт - -### 1. Настройте тестовый сервер - -```bash -# На вашем тестовом сервере выполните: -curl -sSL https://raw.githubusercontent.com/YOUR_USERNAME/YOUR_REPO/main/scripts/setup-testing-server.sh | bash -``` - -### 2. Добавьте GitHub Secrets - -В настройках репозитория добавьте следующие секреты: - -``` -TESTING_SERVER_HOST=your.server.ip.address -TESTING_SERVER_USER=deploy -TESTING_SERVER_SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY----- -your private SSH key content ------END OPENSSH PRIVATE KEY----- -TESTING_DB_ROOT_PASSWORD=strong_root_password -TESTING_DB_USERNAME=app_user -TESTING_DB_PASSWORD=strong_user_password -``` - -### 3. Создайте Pull Request - -1. Создайте новую ветку от `develop` -2. Внесите изменения -3. Создайте Pull Request в ветку `develop` -4. GitHub Actions автоматически развернет ваше приложение -5. Проверьте комментарий в PR с ссылкой на развертывание - -## 🏗️ Как это работает - -### Workflow процесс - -1. **Триггер**: Pull Request в ветку `develop` -2. **Сборка**: Установка зависимостей, линтинг, сборка приложения -3. **Docker**: Создание Docker образа -4. **Развертывание**: Копирование файлов на сервер и запуск контейнеров -5. **Проверка**: Health check и уведомление в PR -6. **Очистка**: Автоматическая очистка при закрытии PR - -### Архитектура развертывания - -``` -Тестовый сервер -├── /opt/low-code-engine/ -│ ├── testing-pr-123/ # Изолированная среда для PR #123 -│ │ ├── docker-compose.yml -│ │ ├── docker-compose.override.yml -│ │ ├── .env -│ │ └── docker/ -│ ├── testing-pr-124/ # Изолированная среда для PR #124 -│ └── ... -└── Порты: - ├── Приложение: 3000 + PR_NUMBER - ├── База данных: 3300 + PR_NUMBER - └── Redis: 6300 + PR_NUMBER -``` - -## 🔧 Конфигурация - -### Порты по умолчанию - -- **Приложение**: 3000 + номер PR (например, PR #123 → порт 3123) -- **База данных**: 3300 + номер PR (например, PR #123 → порт 3423) -- **Redis**: 6300 + номер PR (например, PR #123 → порт 6423) - -### Переменные окружения - -Можно настроить базовые порты через GitHub Variables: - -``` -TESTING_BASE_PORT=3000 # Базовый порт приложения -TESTING_BASE_DB_PORT=3300 # Базовый порт БД -TESTING_BASE_REDIS_PORT=6300 # Базовый порт Redis -``` - -## 📊 Мониторинг - -### Команды на сервере - -```bash -# Мониторинг всех развертываний -sudo /usr/local/bin/monitor-deployments - -# Очистка старых развертываний (старше 7 дней) -sudo /usr/local/bin/cleanup-old-deployments - -# Просмотр логов конкретного PR -cd /opt/low-code-engine/testing-pr-123 -docker-compose logs -f app - -# Проверка статуса -docker-compose ps -``` - -### Пример вывода мониторинга - -``` -=== Testing Deployments Status === -Date: Mon Oct 13 10:30:00 UTC 2025 - -Active Deployments: - PR #123: Running on port 3123 - Status: ✅ Healthy - PR #124: Running on port 3124 - Status: ❌ Unhealthy - -=== System Resources === -Disk Usage: -/dev/sda1 20G 8.5G 11G 45% /opt/low-code-engine -``` - -## 🔒 Безопасность - -### Рекомендации - -1. **SSH ключи**: Используйте отдельный SSH ключ только для развертывания -2. **Пользователь**: Создайте отдельного пользователя `deploy` с минимальными правами -3. **Firewall**: Настройте фаервол для ограничения доступа -4. **Пароли**: Используйте сильные пароли для базы данных -5. **Автоочистка**: Включена автоматическая очистка старых развертываний - -### Настройка firewall - -```bash -sudo ufw enable -sudo ufw allow ssh -sudo ufw allow 80/tcp -sudo ufw allow 443/tcp -sudo ufw allow 3000:3999/tcp # Порты приложений -sudo ufw allow 3300:3999/tcp # Порты БД -sudo ufw allow 6300:6999/tcp # Порты Redis -``` - -## 🧪 Тестирование - -### Тестирование самого процесса развертывания - -Запустите тестовый workflow вручную: - -1. Перейдите в Actions → Test Deployment Workflow -2. Нажмите "Run workflow" -3. Укажите номер PR для симуляции (например, 999) -4. Запустите тест - -### Локальное тестирование - -```bash -# Сборка и тест Docker образа локально -docker build -t low-code-engine:local . -docker run -d --name test-app -p 3000:3000 low-code-engine:local - -# Проверка health endpoint -curl http://localhost:3000/health - -# Очистка -docker stop test-app && docker rm test-app -``` - -## 📚 Дополнительная документация - -- [DEPLOYMENT.md](./DEPLOYMENT.md) - Подробная документация по настройке -- [QUICK-START.md](./QUICK-START.md) - Краткое руководство по быстрому старту -- [.env.testing.example](./.env.testing.example) - Пример переменных окружения - -## 🛠️ Troubleshooting - -### Часто встречающиеся проблемы - -#### "Permission denied" при SSH - -```bash -# Проверьте права на сервере -sudo ls -la /home/deploy/.ssh/ -sudo chmod 700 /home/deploy/.ssh/ -sudo chmod 600 /home/deploy/.ssh/authorized_keys -``` - -#### Порт уже занят - -```bash -# Найдите процесс -sudo netstat -tulpn | grep :3123 - -# Остановите развертывание -cd /opt/low-code-engine/testing-pr-123 -docker-compose down -``` - -#### Нехватка места на диске - -```bash -# Очистка Docker -docker system prune -a -f - -# Очистка старых развертываний -sudo /usr/local/bin/cleanup-old-deployments -``` - -## 🤝 Вклад в развитие - -1. Создайте форк репозитория -2. Создайте ветку для новой функции -3. Внесите изменения -4. Создайте Pull Request -5. Протестируйте развертывание - -## 📝 Лицензия - -Этот проект использует лицензию, указанную в основном проекте. - ---- - -💡 **Совет**: Начните с [QUICK-START.md](./QUICK-START.md) для быстрой настройки, затем обратитесь к [DEPLOYMENT.md](./DEPLOYMENT.md) для подробной конфигурации. diff --git a/QUICK-START.md b/QUICK-START.md deleted file mode 100644 index 508d9ea..0000000 --- a/QUICK-START.md +++ /dev/null @@ -1,178 +0,0 @@ -# Quick Start Guide для GitHub Actions Deploy - -## 🚀 Быстрая настройка - -### 1. Настройка тестового сервера - -Запустите на своем тестовом сервере: - -```bash -# Скачать и запустить скрипт настройки -curl -sSL https://raw.githubusercontent.com/YOUR_USERNAME/YOUR_REPO/main/scripts/setup-testing-server.sh | bash -``` - -Или вручную: - -```bash -git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git -cd YOUR_REPO -./scripts/setup-testing-server.sh -``` - -### 2. Настройка SSH ключей - -На тестовом сервере добавьте свой публичный SSH ключ: - -```bash -# Генерация нового SSH ключа (если нужно) -ssh-keygen -t ed25519 -C "github-actions@yourdomain.com" -f ~/.ssh/github_actions - -# Добавление публичного ключа на сервер -sudo -u deploy tee -a /home/deploy/.ssh/authorized_keys < ~/.ssh/github_actions.pub -``` - -### 3. Настройка GitHub Secrets - -В настройках GitHub репозитория (Settings → Secrets and variables → Actions) добавьте: - -**Required Secrets:** - -``` -TESTING_SERVER_HOST=your.server.ip.address -TESTING_SERVER_USER=deploy -TESTING_SERVER_SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY----- -your private key content here ------END OPENSSH PRIVATE KEY----- -TESTING_DB_ROOT_PASSWORD=your_strong_root_password -TESTING_DB_USERNAME=app_user -TESTING_DB_PASSWORD=your_strong_user_password -``` - -**Optional Variables:** - -``` -TESTING_BASE_PORT=3000 -TESTING_BASE_DB_PORT=3300 -TESTING_BASE_REDIS_PORT=6300 -``` - -### 4. Тестирование - -1. Создайте новую ветку и сделайте изменения -2. Создайте Pull Request в ветку `develop` -3. GitHub Actions автоматически развернет приложение -4. Проверьте комментарий в PR с информацией о развертывании - -## 📝 Полезные команды на сервере - -```bash -# Мониторинг всех развертываний -sudo /usr/local/bin/monitor-deployments - -# Очистка старых развертываний -sudo /usr/local/bin/cleanup-old-deployments - -# Просмотр логов конкретного PR -cd /opt/low-code-engine/testing-pr-123 -docker-compose logs -f app - -# Проверка статуса контейнеров -docker-compose ps - -# Запуск миграций вручную -docker-compose exec app yarn migration:run -``` - -## 🔧 Troubleshooting - -### Проблема: "Permission denied" при SSH подключении - -```bash -# На сервере проверьте права доступа -sudo ls -la /home/deploy/.ssh/ -sudo cat /home/deploy/.ssh/authorized_keys - -# Права должны быть: -# drwx------ deploy deploy .ssh/ -# -rw------- deploy deploy authorized_keys -``` - -### Проблема: Порт уже занят - -```bash -# Найти процесс использующий порт -sudo netstat -tulpn | grep :3123 - -# Остановить все контейнеры для PR -cd /opt/low-code-engine/testing-pr-123 -docker-compose down -``` - -### Проблема: Не хватает места на диске - -```bash -# Очистить Docker ресурсы -docker system prune -a -f - -# Очистить старые развертывания -sudo /usr/local/bin/cleanup-old-deployments -``` - -### Проблема: База данных не запускается - -```bash -# Проверить логи MariaDB -docker-compose logs mariadb - -# Пересоздать контейнер базы данных -docker-compose down -docker-compose up -d mariadb -``` - -## 🌐 Доступ к приложениям - -### По портам (прямой доступ): - -- Приложение: `http://YOUR_SERVER_IP:3000{PR_NUMBER}` -- База данных: `YOUR_SERVER_IP:3300{PR_NUMBER}` -- Redis: `YOUR_SERVER_IP:6300{PR_NUMBER}` - -### Через домены (если настроен Nginx): - -- Приложение: `http://pr-{PR_NUMBER}.testing.yourdomain.com` - -Пример для PR #123: - -- Приложение: `http://your.server.ip:3123` или `http://pr-123.testing.yourdomain.com` -- База данных: `your.server.ip:3423` -- Redis: `your.server.ip:6423` - -## 📊 Мониторинг - -Проверить статус всех развертываний: - -```bash -sudo /usr/local/bin/monitor-deployments -``` - -Вывод будет примерно таким: - -``` -=== Testing Deployments Status === -Date: Mon Oct 13 10:30:00 UTC 2025 - -Active Deployments: - PR #123: Running on port 3123 - Status: ✅ Healthy - PR #124: Running on port 3124 - Status: ❌ Unhealthy - -=== System Resources === -Disk Usage: -/dev/sda1 20G 8.5G 11G 45% /opt/low-code-engine - -Docker Usage: -TYPE TOTAL ACTIVE SIZE RECLAIMABLE -Images 15 8 2.5GB 1.2GB (48%) -Containers 16 8 150MB 80MB (53%) -``` From ff664c208633326f3310260bd93f49c073c3fe7f Mon Sep 17 00:00:00 2001 From: lborv Date: Mon, 13 Oct 2025 21:25:36 +0300 Subject: [PATCH 3/4] fix: update comments and documentation to English for consistency --- .gitea/workflows/deploy-testing.yml | 30 ++-- .gitea/workflows/test-deployment.yml | 237 --------------------------- DEPLOYMENT.md | 146 ++++++++--------- 3 files changed, 88 insertions(+), 325 deletions(-) delete mode 100644 .gitea/workflows/test-deployment.yml diff --git a/.gitea/workflows/deploy-testing.yml b/.gitea/workflows/deploy-testing.yml index 1c6e0e3..943407c 100644 --- a/.gitea/workflows/deploy-testing.yml +++ b/.gitea/workflows/deploy-testing.yml @@ -10,7 +10,7 @@ jobs: deploy: name: Deploy to Testing Server runs-on: ubuntu-latest - if: github.event.pull_request.merged == false # Только для открытых PR + if: github.event.pull_request.merged == false # Only for open PRs steps: - name: Checkout code @@ -49,14 +49,14 @@ jobs: key: ${{ secrets.TESTING_SERVER_SSH_KEY }} port: ${{ secrets.TESTING_SERVER_PORT || 22 }} script: | - # Создаем директорию для приложения если её нет + # Create application directory if it doesn't exist mkdir -p /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - # Останавливаем существующие контейнеры если они есть + # Stop existing containers if they exist docker-compose down || true - # Удаляем старые образы + # Remove old images docker image prune -f || true - name: Copy files to server @@ -79,10 +79,10 @@ jobs: script: | cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - # Загружаем Docker образ + # Load Docker image gunzip -c low-code-engine-testing.tar.gz | docker load - # Создаем .env файл для тестового окружения + # Create .env file for testing environment cat > .env << EOF NODE_ENV=testing DB_ROOT_PASSWORD=${{ secrets.TESTING_DB_ROOT_PASSWORD }} @@ -95,7 +95,7 @@ jobs: REDIS_PORT=6379 EOF - # Создаем docker-compose.override.yml для тестового окружения + # Create docker-compose.override.yml for testing environment cat > docker-compose.override.yml << EOF version: "3.8" services: @@ -125,16 +125,16 @@ jobs: - "${{ vars.TESTING_BASE_REDIS_PORT || 6379 }}${{ github.event.pull_request.number }}:6379" EOF - # Запускаем контейнеры + # Start containers docker-compose up -d - # Ждем пока база данных запустится + # Wait for database to start sleep 30 - # Запускаем миграции + # Run migrations docker-compose exec -T app yarn migration:run || true - # Проверяем статус контейнеров + # Check container status docker-compose ps - name: Health check @@ -147,7 +147,7 @@ jobs: script: | cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - # Проверяем доступность приложения + # Check application availability APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }} for i in {1..10}; do @@ -213,13 +213,13 @@ jobs: script: | cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - # Останавливаем и удаляем контейнеры + # Stop and remove containers docker-compose down -v || true - # Удаляем Docker образ + # Remove Docker image docker rmi low-code-engine:testing-${{ github.event.pull_request.number }} || true - # Удаляем директорию развертывания + # Remove deployment directory cd .. rm -rf testing-pr-${{ github.event.pull_request.number }} diff --git a/.gitea/workflows/test-deployment.yml b/.gitea/workflows/test-deployment.yml deleted file mode 100644 index d1c6032..0000000 --- a/.gitea/workflows/test-deployment.yml +++ /dev/null @@ -1,237 +0,0 @@ -name: Test Deployment Workflow - -# Этот workflow можно запустить вручную для тестирования процесса развертывания -on: - workflow_dispatch: - inputs: - pr_number: - description: "PR number to simulate" - required: true - default: "999" - type: string - cleanup: - description: "Run cleanup after deployment" - required: false - default: false - type: boolean - -jobs: - test-deployment: - name: Test Deployment Process - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "18" - cache: "yarn" - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Run tests - run: | - # Add your test commands here - echo "Running tests..." - yarn lint:check || echo "Linting completed with warnings" - - - name: Build application - run: yarn build - - - name: Build Docker image - run: | - docker build -t low-code-engine:test-${{ inputs.pr_number }} . - echo "Docker image built successfully" - - - name: Test Docker image - run: | - # Test that the image runs correctly - docker run -d --name test-app -p 3000:3000 low-code-engine:test-${{ inputs.pr_number }} - sleep 10 - - # Try to connect to the app - if curl -f http://localhost:3000/health > /dev/null 2>&1; then - echo "✅ Application is responding" - else - echo "❌ Application is not responding" - docker logs test-app - fi - - docker stop test-app - docker rm test-app - - - name: Save Docker image - run: | - docker save low-code-engine:test-${{ inputs.pr_number }} | gzip > low-code-engine-test.tar.gz - ls -lh low-code-engine-test.tar.gz - - - name: Test SSH connection - if: ${{ secrets.TESTING_SERVER_HOST }} - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - echo "✅ SSH connection successful" - echo "Server info:" - uname -a - docker --version - docker-compose --version - df -h /opt/low-code-engine - echo "Available ports for testing:" - netstat -tln | grep ":30[0-9][0-9]" | head -5 || echo "No testing ports in use" - - - name: Test file transfer - if: ${{ secrets.TESTING_SERVER_HOST }} - uses: appleboy/scp-action@v0.1.7 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - source: "low-code-engine-test.tar.gz" - target: "/tmp/" - - - name: Test deployment simulation - if: ${{ secrets.TESTING_SERVER_HOST }} - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - echo "Testing deployment simulation for PR #${{ inputs.pr_number }}" - - # Create test directory - mkdir -p /opt/low-code-engine/test-pr-${{ inputs.pr_number }} - cd /opt/low-code-engine/test-pr-${{ inputs.pr_number }} - - # Copy test file - cp /tmp/low-code-engine-test.tar.gz . - - # Test image loading - gunzip -c low-code-engine-test.tar.gz | docker load - - echo "✅ Test deployment simulation completed" - - # Cleanup test files - rm -f low-code-engine-test.tar.gz /tmp/low-code-engine-test.tar.gz - docker rmi low-code-engine:test-${{ inputs.pr_number }} || true - cd .. - rm -rf test-pr-${{ inputs.pr_number }} - - - name: Cleanup on failure - if: failure() && secrets.TESTING_SERVER_HOST - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - # Cleanup any test artifacts - rm -f /tmp/low-code-engine-test.tar.gz - rm -rf /opt/low-code-engine/test-pr-${{ inputs.pr_number }} - docker rmi low-code-engine:test-${{ inputs.pr_number }} || true - echo "🧹 Cleanup completed" - - test-health-endpoints: - name: Test Health Endpoints - runs-on: ubuntu-latest - needs: test-deployment - if: ${{ secrets.TESTING_SERVER_HOST }} - - steps: - - name: Test server health endpoints - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - echo "Testing health check endpoints..." - - # Test monitoring script - if [ -f /usr/local/bin/monitor-deployments ]; then - echo "✅ Monitor script exists" - /usr/local/bin/monitor-deployments | head -20 - else - echo "❌ Monitor script not found" - fi - - # Test cleanup script - if [ -f /usr/local/bin/cleanup-old-deployments ]; then - echo "✅ Cleanup script exists" - else - echo "❌ Cleanup script not found" - fi - - # Test nginx configuration - if command -v nginx &> /dev/null; then - echo "✅ Nginx is installed" - nginx -t 2>&1 | head -5 - else - echo "❌ Nginx not installed" - fi - - # Test docker access - docker ps | head -5 - echo "Docker system info:" - docker system df - - security-check: - name: Security Check - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Run security audit - run: | - echo "Running security checks..." - - # Check for secrets in code - if grep -r "password\|secret\|key" --include="*.ts" --include="*.js" --include="*.json" src/ | grep -v "// TODO\|console.log"; then - echo "❌ Potential secrets found in code" - exit 1 - else - echo "✅ No secrets found in source code" - fi - - # Check Docker image for security issues - echo "Building secure Docker image..." - docker build -t security-test . - - # Basic security checks - echo "Checking Docker image user..." - docker run --rm security-test whoami | grep -v root || echo "✅ Not running as root" - - docker rmi security-test - - - name: Check workflow security - run: | - echo "Checking workflow file security..." - - # Check that secrets are properly referenced - if grep -E '\$\{\{\s*secrets\.' .github/workflows/*.yml > /dev/null; then - echo "✅ Secrets properly referenced" - else - echo "❌ No secrets found in workflows" - fi - - # Check for hardcoded values - if grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' .github/workflows/*.yml; then - echo "❌ Hardcoded IP addresses found" - exit 1 - else - echo "✅ No hardcoded IP addresses" - fi diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 8e5567b..053036f 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -1,86 +1,86 @@ # GitHub Actions Deployment Setup -Этот документ описывает настройку автоматического развертывания на тестовом сервере при создании Pull Request в ветку `develop`. +This document describes the setup for automatic deployment to a testing server when creating a Pull Request to the `develop` branch. -## Требуемые GitHub Secrets +## Required GitHub Secrets -Перейдите в настройки репозитория → Settings → Secrets and variables → Actions и добавьте следующие секреты: +Go to repository settings → Settings → Secrets and variables → Actions and add the following secrets: ### SSH Connection -- `TESTING_SERVER_HOST` - IP адрес или домен тестового сервера -- `TESTING_SERVER_USER` - Пользователь для SSH подключения (например: `deploy`) -- `TESTING_SERVER_SSH_KEY` - Приватный SSH ключ для подключения к серверу -- `TESTING_SERVER_PORT` - (опционально) Порт SSH (по умолчанию 22) +- `TESTING_SERVER_HOST` - IP address or domain of the testing server +- `TESTING_SERVER_USER` - User for SSH connection (e.g., `deploy`) +- `TESTING_SERVER_SSH_KEY` - Private SSH key for server connection +- `TESTING_SERVER_PORT` - (optional) SSH port (default: 22) ### Database Configuration -- `TESTING_DB_ROOT_PASSWORD` - Root пароль для MariaDB -- `TESTING_DB_USERNAME` - Пользователь базы данных -- `TESTING_DB_PASSWORD` - Пароль пользователя базы данных +- `TESTING_DB_ROOT_PASSWORD` - Root password for MariaDB +- `TESTING_DB_USERNAME` - Database user +- `TESTING_DB_PASSWORD` - Database user password -## Требуемые GitHub Variables +## Required GitHub Variables -Перейдите в настройки репозитория → Settings → Secrets and variables → Actions → Variables и добавьте: +Go to repository settings → Settings → Secrets and variables → Actions → Variables and add: -- `TESTING_BASE_PORT` - Базовый порт для приложений (по умолчанию: 3000) -- `TESTING_BASE_DB_PORT` - Базовый порт для баз данных (по умолчанию: 3306) -- `TESTING_BASE_REDIS_PORT` - Базовый порт для Redis (по умолчанию: 6379) +- `TESTING_BASE_PORT` - Base port for applications (default: 3000) +- `TESTING_BASE_DB_PORT` - Base port for databases (default: 3306) +- `TESTING_BASE_REDIS_PORT` - Base port for Redis (default: 6379) -## Настройка тестового сервера +## Testing Server Setup -### 1. Установка Docker и Docker Compose +### 1. Installing Docker and Docker Compose ```bash -# Обновление системы +# System update sudo apt update && sudo apt upgrade -y -# Установка Docker +# Docker installation curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh -# Добавление пользователя в группу docker +# Add user to docker group sudo usermod -aG docker $USER -# Установка Docker Compose +# Install Docker Compose sudo apt install docker-compose-plugin -y ``` -### 2. Создание пользователя для развертывания +### 2. Creating deployment user ```bash -# Создание пользователя +# Create user sudo useradd -m -s /bin/bash deploy sudo usermod -aG docker deploy -# Создание директории для SSH ключей +# Create SSH keys directory sudo mkdir -p /home/deploy/.ssh sudo chmod 700 /home/deploy/.ssh -# Добавление публичного SSH ключа +# Add public SSH key sudo nano /home/deploy/.ssh/authorized_keys -# Вставьте публичный ключ, соответствующий приватному ключу в TESTING_SERVER_SSH_KEY +# Insert public key corresponding to private key in TESTING_SERVER_SSH_KEY sudo chmod 600 /home/deploy/.ssh/authorized_keys sudo chown -R deploy:deploy /home/deploy/.ssh -# Создание директории для приложений +# Create applications directory sudo mkdir -p /opt/low-code-engine sudo chown deploy:deploy /opt/low-code-engine ``` -### 3. Настройка Nginx (опционально) +### 3. Nginx Setup (Optional) -Если хотите использовать доменные имена вместо портов: +If you want to use domain names instead of ports: ```bash sudo apt install nginx -y -# Создание конфигурации для тестовых приложений +# Create configuration for testing applications sudo nano /etc/nginx/sites-available/testing-apps ``` -Содержимое файла: +File content: ```nginx server { @@ -99,76 +99,76 @@ server { ``` ```bash -# Активация конфигурации +# Activate configuration sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` -## Как работает развертывание +## How Deployment Works -### Процесс развертывания +### Deployment Process -1. **Trigger**: Создание или обновление Pull Request в ветку `develop` -2. **Build**: Сборка приложения и создание Docker образа -3. **Deploy**: Копирование файлов на сервер и запуск контейнеров -4. **Health Check**: Проверка доступности приложения -5. **Comment**: Добавление комментария в PR с информацией о развертывании +1. **Trigger**: Creating or updating Pull Request to `develop` branch +2. **Build**: Building application and creating Docker image +3. **Deploy**: Copying files to server and starting containers +4. **Health Check**: Checking application availability +5. **Comment**: Adding comment to PR with deployment information -### Структура на сервере +### Server Structure ``` /opt/low-code-engine/ -├── testing-pr-123/ # Отдельная директория для каждого PR -│ ├── docker-compose.yml # Основной docker-compose файл -│ ├── docker-compose.override.yml # Переопределения для тестинга -│ ├── .env # Переменные окружения -│ ├── docker/ # Docker конфигурации -│ └── low-code-engine-testing.tar.gz # Docker образ +├── testing-pr-123/ # Separate directory for each PR +│ ├── docker-compose.yml # Main docker-compose file +│ ├── docker-compose.override.yml # Testing overrides +│ ├── .env # Environment variables +│ ├── docker/ # Docker configurations +│ └── low-code-engine-testing.tar.gz # Docker image ├── testing-pr-124/ └── ... ``` -### Порты +### Ports -Каждому PR назначаются уникальные порты: +Each PR is assigned unique ports: -- Приложение: `TESTING_BASE_PORT + PR_NUMBER` (например: 3000 + 123 = 3123) -- База данных: `TESTING_BASE_DB_PORT + PR_NUMBER` (например: 3306 + 123 = 3429) -- Redis: `TESTING_BASE_REDIS_PORT + PR_NUMBER` (например: 6379 + 123 = 6502) +- Application: `TESTING_BASE_PORT + PR_NUMBER` (e.g., 3000 + 123 = 3123) +- Database: `TESTING_BASE_DB_PORT + PR_NUMBER` (e.g., 3306 + 123 = 3429) +- Redis: `TESTING_BASE_REDIS_PORT + PR_NUMBER` (e.g., 6379 + 123 = 6502) ### Cleanup -При закрытии или мердже PR автоматически происходит: +When PR is closed or merged, automatically: -1. Остановка и удаление контейнеров -2. Удаление Docker образов -3. Удаление файлов на сервере -4. Добавление комментария об очистке +1. Stop and remove containers +2. Remove Docker images +3. Remove files on server +4. Add cleanup comment -## Безопасность +## Security -1. **SSH ключи**: Используйте отдельный SSH ключ только для развертывания -2. **Пользователь**: Создайте отдельного пользователя с минимальными правами -3. **Firewall**: Настройте фаервол для ограничения доступа к портам -4. **SSL/TLS**: Рассмотрите использование SSL сертификатов для HTTPS +1. **SSH Keys**: Use separate SSH key only for deployment +2. **User**: Create separate user with minimal privileges +3. **Firewall**: Configure firewall to restrict port access +4. **SSL/TLS**: Consider using SSL certificates for HTTPS -## Мониторинг и логи +## Monitoring and Logs -### Просмотр логов приложения +### View Application Logs ```bash cd /opt/low-code-engine/testing-pr-{PR_NUMBER} docker-compose logs -f app ``` -### Просмотр статуса контейнеров +### View Container Status ```bash docker-compose ps ``` -### Мониторинг ресурсов +### Resource Monitoring ```bash docker stats @@ -176,33 +176,33 @@ docker stats ## Troubleshooting -### Проблемы с портами +### Port Issues -Если порт занят, проверьте какие приложения его используют: +If port is occupied, check which applications are using it: ```bash sudo netstat -tulpn | grep :{PORT} ``` -### Проблемы с Docker +### Docker Issues -Очистка неиспользуемых ресурсов: +Clean up unused resources: ```bash docker system prune -f ``` -### Проблемы с базой данных +### Database Issues -Проверка подключения к базе данных: +Check database connection: ```bash docker-compose exec mariadb mysql -u root -p -e "SHOW DATABASES;" ``` -### Проблемы с миграциями +### Migration Issues -Ручной запуск миграций: +Manual migration run: ```bash docker-compose exec app yarn migration:run From 6e95a0c1a9e9e9e49c5994871acc0997b1bac505 Mon Sep 17 00:00:00 2001 From: Boris D Date: Tue, 14 Oct 2025 14:13:10 +0300 Subject: [PATCH 4/4] chore: Refactor deployment scripts and workflows for improved clarity and efficiency --- .gitea/workflows/deploy-testing.yml | 254 +++--------------------- .gitea/workflows/test.yml | 18 -- DEPLOYMENT.md | 209 -------------------- docker-compose.yml | 34 ++-- scripts/setup-docker.sh | 37 ++++ scripts/setup-testing-server.sh | 293 ---------------------------- 6 files changed, 80 insertions(+), 765 deletions(-) delete mode 100644 .gitea/workflows/test.yml delete mode 100644 DEPLOYMENT.md create mode 100644 scripts/setup-docker.sh delete mode 100755 scripts/setup-testing-server.sh diff --git a/.gitea/workflows/deploy-testing.yml b/.gitea/workflows/deploy-testing.yml index 943407c..d8fa6c3 100644 --- a/.gitea/workflows/deploy-testing.yml +++ b/.gitea/workflows/deploy-testing.yml @@ -1,247 +1,53 @@ name: Deploy to Testing Server on: - pull_request: + push: branches: - develop - types: [opened, synchronize, reopened] + workflow_dispatch: jobs: deploy: - name: Deploy to Testing Server runs-on: ubuntu-latest - if: github.event.pull_request.merged == false # Only for open PRs + name: Deploy to Testing Environment steps: - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 + uses: actions/checkout@v3 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "18" - cache: "yarn" - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Run linting - run: yarn lint:check - - - name: Build application - run: yarn build - - - name: Build Docker image - run: | - docker build -t low-code-engine:testing-${{ github.event.pull_request.number }} . - - - name: Save Docker image - run: | - docker save low-code-engine:testing-${{ github.event.pull_request.number }} | gzip > low-code-engine-testing.tar.gz - - - name: Deploy to Testing Server + - name: Deploy via SSH uses: appleboy/ssh-action@v1.0.3 with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + port: ${{ secrets.SSH_PORT || 22 }} script: | - # Create application directory if it doesn't exist - mkdir -p /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + # Navigate to project directory + cd ${{ secrets.PROJECT_PATH }} - # Stop existing containers if they exist - docker-compose down || true + # Pull latest code + echo "🔄 Pulling latest code from repository..." + git pull origin develop - # Remove old images - docker image prune -f || true + # Install dependencies + echo "📦 Installing dependencies with yarn..." + yarn install --frozen-lockfile - - name: Copy files to server - uses: appleboy/scp-action@v0.1.7 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - source: "low-code-engine-testing.tar.gz,docker-compose.yml,docker/" - target: "/opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}/" + # Run database migrations + echo "🗄️ Running database migrations..." + yarn migration:run - - name: Load and run Docker containers - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} + # Build the project + echo "🏗️ Building the project..." + yarn build - # Load Docker image - gunzip -c low-code-engine-testing.tar.gz | docker load + # Restart PM2 process + echo "🔄 Restarting PM2 application..." + pm2 restart ${{ secrets.PM2_APP_NAME || 'low-code-engine' }} - # Create .env file for testing environment - cat > .env << EOF - NODE_ENV=testing - DB_ROOT_PASSWORD=${{ secrets.TESTING_DB_ROOT_PASSWORD }} - DB_DATABASE=low_code_engine_pr_${{ github.event.pull_request.number }} - DB_USERNAME=${{ secrets.TESTING_DB_USERNAME }} - DB_PASSWORD=${{ secrets.TESTING_DB_PASSWORD }} - DB_PORT=3306 - APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }} - REDIS_HOST=redis - REDIS_PORT=6379 - EOF + # Show PM2 status + echo "✅ Deployment completed! PM2 status:" + pm2 status - # Create docker-compose.override.yml for testing environment - cat > docker-compose.override.yml << EOF - version: "3.8" - services: - app: - image: low-code-engine:testing-${{ github.event.pull_request.number }} - ports: - - "\${APP_PORT}:3000" - environment: - NODE_ENV: testing - DB_HOST: mariadb - DB_PORT: 3306 - DB_USERNAME: \${DB_USERNAME} - DB_PASSWORD: \${DB_PASSWORD} - DB_DATABASE: \${DB_DATABASE} - REDIS_HOST: redis - REDIS_PORT: 6379 - - mariadb: - ports: - - "${{ vars.TESTING_BASE_DB_PORT || 3306 }}${{ github.event.pull_request.number }}:3306" - environment: - MYSQL_DATABASE: \${DB_DATABASE} - - redis: - image: redis:7-alpine - ports: - - "${{ vars.TESTING_BASE_REDIS_PORT || 6379 }}${{ github.event.pull_request.number }}:6379" - EOF - - # Start containers - docker-compose up -d - - # Wait for database to start - sleep 30 - - # Run migrations - docker-compose exec -T app yarn migration:run || true - - # Check container status - docker-compose ps - - - name: Health check - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - - # Check application availability - APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }} - - for i in {1..10}; do - if curl -f http://localhost:$APP_PORT/health > /dev/null 2>&1; then - echo "✅ Application is healthy on port $APP_PORT" - break - fi - echo "⏳ Waiting for application to start... (attempt $i/10)" - sleep 10 - done - - - name: Comment PR with deployment info - uses: actions/github-script@v7 - with: - script: | - const prNumber = context.payload.pull_request.number; - const appPort = ${{ vars.TESTING_BASE_PORT || 3000 }} + prNumber; - const dbPort = ${{ vars.TESTING_BASE_DB_PORT || 3306 }} + prNumber; - const redisPort = ${{ vars.TESTING_BASE_REDIS_PORT || 6379 }} + prNumber; - - const comment = `## 🚀 Testing Deployment - - Your PR has been deployed to the testing server! - - **Deployment Details:** - - 🌐 Application URL: http://${{ secrets.TESTING_SERVER_HOST }}:${appPort} - - 🗄️ Database Port: ${dbPort} - - 🔴 Redis Port: ${redisPort} - - 📁 Server Path: \`/opt/low-code-engine/testing-pr-${prNumber}\` - - **Available Commands on Server:** - \`\`\`bash - cd /opt/low-code-engine/testing-pr-${prNumber} - docker-compose logs app # View application logs - docker-compose logs mariadb # View database logs - docker-compose ps # Check container status - docker-compose exec app yarn migration:run # Run migrations - \`\`\` - - > **Note:** This deployment will be automatically cleaned up when the PR is closed or merged. - `; - - github.rest.issues.createComment({ - issue_number: prNumber, - owner: context.repo.owner, - repo: context.repo.repo, - body: comment - }); - - cleanup: - name: Cleanup on PR Close - runs-on: ubuntu-latest - if: github.event.pull_request.state == 'closed' - - steps: - - name: Cleanup testing environment - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TESTING_SERVER_HOST }} - username: ${{ secrets.TESTING_SERVER_USER }} - key: ${{ secrets.TESTING_SERVER_SSH_KEY }} - port: ${{ secrets.TESTING_SERVER_PORT || 22 }} - script: | - cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }} - - # Stop and remove containers - docker-compose down -v || true - - # Remove Docker image - docker rmi low-code-engine:testing-${{ github.event.pull_request.number }} || true - - # Remove deployment directory - cd .. - rm -rf testing-pr-${{ github.event.pull_request.number }} - - echo "✅ Cleanup completed for PR #${{ github.event.pull_request.number }}" - - - name: Comment PR with cleanup info - uses: actions/github-script@v7 - with: - script: | - const comment = `## 🧹 Testing Environment Cleaned Up - - The testing deployment for this PR has been cleaned up: - - ✅ Docker containers stopped and removed - - ✅ Docker images cleaned up - - ✅ Server files removed - - Thank you for testing! 🎉 - `; - - github.rest.issues.createComment({ - issue_number: context.payload.pull_request.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: comment - }); + echo "🚀 Application deployed successfully!" diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml deleted file mode 100644 index a0008fe..0000000 --- a/.gitea/workflows/test.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Test Runner - -on: - push: - branches: - - main - - develop - -jobs: - hello-world: - runs-on: [ubuntu-latest] - steps: - - name: Test multiple commands - run: | - echo "Step 1 complete ✅" - echo "Step 2 complete ✅" - echo "All good!" - echo "Tests passed! 🎉" diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md deleted file mode 100644 index 053036f..0000000 --- a/DEPLOYMENT.md +++ /dev/null @@ -1,209 +0,0 @@ -# GitHub Actions Deployment Setup - -This document describes the setup for automatic deployment to a testing server when creating a Pull Request to the `develop` branch. - -## Required GitHub Secrets - -Go to repository settings → Settings → Secrets and variables → Actions and add the following secrets: - -### SSH Connection - -- `TESTING_SERVER_HOST` - IP address or domain of the testing server -- `TESTING_SERVER_USER` - User for SSH connection (e.g., `deploy`) -- `TESTING_SERVER_SSH_KEY` - Private SSH key for server connection -- `TESTING_SERVER_PORT` - (optional) SSH port (default: 22) - -### Database Configuration - -- `TESTING_DB_ROOT_PASSWORD` - Root password for MariaDB -- `TESTING_DB_USERNAME` - Database user -- `TESTING_DB_PASSWORD` - Database user password - -## Required GitHub Variables - -Go to repository settings → Settings → Secrets and variables → Actions → Variables and add: - -- `TESTING_BASE_PORT` - Base port for applications (default: 3000) -- `TESTING_BASE_DB_PORT` - Base port for databases (default: 3306) -- `TESTING_BASE_REDIS_PORT` - Base port for Redis (default: 6379) - -## Testing Server Setup - -### 1. Installing Docker and Docker Compose - -```bash -# System update -sudo apt update && sudo apt upgrade -y - -# Docker installation -curl -fsSL https://get.docker.com -o get-docker.sh -sudo sh get-docker.sh - -# Add user to docker group -sudo usermod -aG docker $USER - -# Install Docker Compose -sudo apt install docker-compose-plugin -y -``` - -### 2. Creating deployment user - -```bash -# Create user -sudo useradd -m -s /bin/bash deploy -sudo usermod -aG docker deploy - -# Create SSH keys directory -sudo mkdir -p /home/deploy/.ssh -sudo chmod 700 /home/deploy/.ssh - -# Add public SSH key -sudo nano /home/deploy/.ssh/authorized_keys -# Insert public key corresponding to private key in TESTING_SERVER_SSH_KEY - -sudo chmod 600 /home/deploy/.ssh/authorized_keys -sudo chown -R deploy:deploy /home/deploy/.ssh - -# Create applications directory -sudo mkdir -p /opt/low-code-engine -sudo chown deploy:deploy /opt/low-code-engine -``` - -### 3. Nginx Setup (Optional) - -If you want to use domain names instead of ports: - -```bash -sudo apt install nginx -y - -# Create configuration for testing applications -sudo nano /etc/nginx/sites-available/testing-apps -``` - -File content: - -```nginx -server { - listen 80; - server_name ~^pr-(?\d+)\.testing\.yourdomain\.com$; - - location / { - set $app_port 3000$pr_number; - proxy_pass http://127.0.0.1:$app_port; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -} -``` - -```bash -# Activate configuration -sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/ -sudo nginx -t -sudo systemctl reload nginx -``` - -## How Deployment Works - -### Deployment Process - -1. **Trigger**: Creating or updating Pull Request to `develop` branch -2. **Build**: Building application and creating Docker image -3. **Deploy**: Copying files to server and starting containers -4. **Health Check**: Checking application availability -5. **Comment**: Adding comment to PR with deployment information - -### Server Structure - -``` -/opt/low-code-engine/ -├── testing-pr-123/ # Separate directory for each PR -│ ├── docker-compose.yml # Main docker-compose file -│ ├── docker-compose.override.yml # Testing overrides -│ ├── .env # Environment variables -│ ├── docker/ # Docker configurations -│ └── low-code-engine-testing.tar.gz # Docker image -├── testing-pr-124/ -└── ... -``` - -### Ports - -Each PR is assigned unique ports: - -- Application: `TESTING_BASE_PORT + PR_NUMBER` (e.g., 3000 + 123 = 3123) -- Database: `TESTING_BASE_DB_PORT + PR_NUMBER` (e.g., 3306 + 123 = 3429) -- Redis: `TESTING_BASE_REDIS_PORT + PR_NUMBER` (e.g., 6379 + 123 = 6502) - -### Cleanup - -When PR is closed or merged, automatically: - -1. Stop and remove containers -2. Remove Docker images -3. Remove files on server -4. Add cleanup comment - -## Security - -1. **SSH Keys**: Use separate SSH key only for deployment -2. **User**: Create separate user with minimal privileges -3. **Firewall**: Configure firewall to restrict port access -4. **SSL/TLS**: Consider using SSL certificates for HTTPS - -## Monitoring and Logs - -### View Application Logs - -```bash -cd /opt/low-code-engine/testing-pr-{PR_NUMBER} -docker-compose logs -f app -``` - -### View Container Status - -```bash -docker-compose ps -``` - -### Resource Monitoring - -```bash -docker stats -``` - -## Troubleshooting - -### Port Issues - -If port is occupied, check which applications are using it: - -```bash -sudo netstat -tulpn | grep :{PORT} -``` - -### Docker Issues - -Clean up unused resources: - -```bash -docker system prune -f -``` - -### Database Issues - -Check database connection: - -```bash -docker-compose exec mariadb mysql -u root -p -e "SHOW DATABASES;" -``` - -### Migration Issues - -Manual migration run: - -```bash -docker-compose exec app yarn migration:run -``` diff --git a/docker-compose.yml b/docker-compose.yml index ed74915..e5755dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,36 +34,28 @@ services: retries: 10 interval: 10s - # NestJS Application - app: - build: - context: . - dockerfile: Dockerfile - target: development - container_name: low-code-engine-app + # Redis Cache + redis: + image: redis:7-alpine + container_name: low-code-engine-redis restart: unless-stopped - environment: - NODE_ENV: ${NODE_ENV:-development} - DB_HOST: mariadb - DB_PORT: 3306 - DB_USERNAME: ${DB_USERNAME:-app_user} - DB_PASSWORD: ${DB_PASSWORD:-app_password} - DB_DATABASE: ${DB_DATABASE:-low_code_engine} ports: - - "${APP_PORT:-3000}:3000" + - "${REDIS_PORT:-6379}:6379" volumes: - - .:/usr/src/app - - /usr/src/app/node_modules + - redis_data:/data networks: - app-network - depends_on: - mariadb: - condition: service_healthy - command: yarn start:dev + healthcheck: + test: ["CMD", "redis-cli", "ping"] + timeout: 5s + retries: 10 + interval: 10s volumes: mariadb_data: driver: local + redis_data: + driver: local networks: app-network: diff --git a/scripts/setup-docker.sh b/scripts/setup-docker.sh new file mode 100644 index 0000000..60f7d3e --- /dev/null +++ b/scripts/setup-docker.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -e + +echo "📦 Updating system packages..." +apt update -y +apt upgrade -y + +echo "🔧 Installing dependencies..." +apt install -y apt-transport-https ca-certificates curl gnupg lsb-release + +echo "🔑 Adding Docker’s official GPG key..." +curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + +echo "📂 Adding Docker repository..." +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \ + https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \ + $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null + +echo "📦 Installing Docker Engine and Compose..." +apt update -y +apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin + +echo "⚙️ Enabling and starting Docker service..." +systemctl enable docker +systemctl start docker + +echo "👤 Adding current user to docker group..." +usermod -aG docker $USER + +echo "✅ Docker and Docker Compose installation complete!" +echo "➡️ Log out and log back in (or run 'newgrp docker') to use Docker without sudo." +echo +echo "💡 Docker version:" +docker --version || echo "Docker not yet available in current shell" +echo "💡 Docker Compose version:" +docker compose version || echo "Docker Compose not yet available in current shell" diff --git a/scripts/setup-testing-server.sh b/scripts/setup-testing-server.sh deleted file mode 100755 index e579134..0000000 --- a/scripts/setup-testing-server.sh +++ /dev/null @@ -1,293 +0,0 @@ -#!/bin/bash - -# Quick setup script for testing server -# Run this script on your testing server to set up the environment - -set -e - -echo "🚀 Setting up testing server for Low Code Engine deployments..." - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Function to print colored output -print_status() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# Check if running as root -if [[ $EUID -eq 0 ]]; then - print_error "This script should not be run as root for security reasons" - exit 1 -fi - -# Update system -print_status "Updating system packages..." -sudo apt update && sudo apt upgrade -y - -# Install Docker -print_status "Installing Docker..." -if ! command -v docker &> /dev/null; then - curl -fsSL https://get.docker.com -o get-docker.sh - sudo sh get-docker.sh - sudo usermod -aG docker $USER - rm get-docker.sh - print_status "Docker installed successfully" -else - print_status "Docker is already installed" -fi - -# Install Docker Compose -print_status "Installing Docker Compose..." -if ! command -v docker-compose &> /dev/null; then - sudo apt install docker-compose-plugin -y - print_status "Docker Compose installed successfully" -else - print_status "Docker Compose is already installed" -fi - -# Create deploy user -print_status "Creating deploy user..." -if ! id "deploy" &>/dev/null; then - sudo useradd -m -s /bin/bash deploy - sudo usermod -aG docker deploy - print_status "Deploy user created successfully" -else - print_status "Deploy user already exists" -fi - -# Setup SSH directory for deploy user -print_status "Setting up SSH for deploy user..." -sudo mkdir -p /home/deploy/.ssh -sudo chmod 700 /home/deploy/.ssh -sudo touch /home/deploy/.ssh/authorized_keys -sudo chmod 600 /home/deploy/.ssh/authorized_keys -sudo chown -R deploy:deploy /home/deploy/.ssh - -# Create application directory -print_status "Creating application directory..." -sudo mkdir -p /opt/low-code-engine -sudo chown deploy:deploy /opt/low-code-engine - -# Install nginx (optional) -print_status "Installing Nginx..." -if ! command -v nginx &> /dev/null; then - sudo apt install nginx -y - print_status "Nginx installed successfully" -else - print_status "Nginx is already installed" -fi - -# Create nginx configuration for testing apps -print_status "Creating Nginx configuration..." -sudo tee /etc/nginx/sites-available/testing-apps > /dev/null <\d+)\.testing\.(.+)$; - - # Health check endpoint - location /health { - set \$app_port 3000\$pr_number; - proxy_pass http://127.0.0.1:\$app_port; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - - # Add CORS headers for API calls - add_header 'Access-Control-Allow-Origin' '*' always; - add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; - add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always; - } - - # Main application - location / { - set \$app_port 3000\$pr_number; - proxy_pass http://127.0.0.1:\$app_port; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade \$http_upgrade; - proxy_set_header Connection "upgrade"; - - # Timeouts - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - } -} - -# Direct port access (fallback) -server { - listen 80 default_server; - server_name _; - - location / { - return 200 'Testing Server is running. Use pr-{NUMBER}.testing.yourdomain.com to access deployments.'; - add_header Content-Type text/plain; - } -} -EOF - -# Enable nginx configuration -if [ ! -L /etc/nginx/sites-enabled/testing-apps ]; then - sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/ -fi - -# Remove default nginx site -if [ -L /etc/nginx/sites-enabled/default ]; then - sudo rm /etc/nginx/sites-enabled/default -fi - -# Test and reload nginx -sudo nginx -t && sudo systemctl reload nginx -print_status "Nginx configured successfully" - -# Install useful tools -print_status "Installing additional tools..." -sudo apt install -y curl wget htop netstat-nat jq - -# Create cleanup script -print_status "Creating cleanup script..." -sudo tee /usr/local/bin/cleanup-old-deployments > /dev/null <<'EOF' -#!/bin/bash -# Cleanup script for old testing deployments - -DAYS_OLD=7 -DEPLOYMENT_DIR="/opt/low-code-engine" - -echo "Cleaning up deployments older than ${DAYS_OLD} days..." - -find ${DEPLOYMENT_DIR} -name "testing-pr-*" -type d -mtime +${DAYS_OLD} | while read dir; do - echo "Cleaning up: $dir" - - # Stop containers if running - if [ -f "$dir/docker-compose.yml" ]; then - cd "$dir" - docker-compose down -v 2>/dev/null || true - fi - - # Remove directory - rm -rf "$dir" - echo "Removed: $dir" -done - -# Clean up unused Docker resources -docker system prune -f -docker image prune -f - -echo "Cleanup completed" -EOF - -sudo chmod +x /usr/local/bin/cleanup-old-deployments - -# Create cron job for cleanup -print_status "Setting up automatic cleanup..." -(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/cleanup-old-deployments") | crontab - - -# Create monitoring script -print_status "Creating monitoring script..." -sudo tee /usr/local/bin/monitor-deployments > /dev/null <<'EOF' -#!/bin/bash -# Monitoring script for testing deployments - -DEPLOYMENT_DIR="/opt/low-code-engine" - -echo "=== Testing Deployments Status ===" -echo "Date: $(date)" -echo - -# Show active deployments -echo "Active Deployments:" -find ${DEPLOYMENT_DIR} -name "testing-pr-*" -type d | sort | while read dir; do - pr_number=$(basename "$dir" | sed 's/testing-pr-//') - if [ -f "$dir/docker-compose.yml" ]; then - cd "$dir" - status=$(docker-compose ps -q | wc -l) - if [ "$status" -gt 0 ]; then - app_port=$((3000 + pr_number)) - echo " PR #${pr_number}: Running on port ${app_port}" - # Check if app is responding - if curl -s --max-time 5 "http://localhost:${app_port}/health" > /dev/null 2>&1; then - echo " Status: ✅ Healthy" - else - echo " Status: ❌ Unhealthy" - fi - else - echo " PR #${pr_number}: Stopped" - fi - fi -done - -echo -echo "=== System Resources ===" -echo "Disk Usage:" -df -h /opt/low-code-engine -echo -echo "Docker Usage:" -docker system df -echo -echo "Memory Usage:" -free -h -EOF - -sudo chmod +x /usr/local/bin/monitor-deployments - -# Setup firewall (optional but recommended) -print_status "Configuring firewall..." -if command -v ufw &> /dev/null; then - sudo ufw --force enable - sudo ufw allow ssh - sudo ufw allow 80/tcp - sudo ufw allow 443/tcp - # Allow port range for testing apps (3000-3999) - sudo ufw allow 3000:3999/tcp - # Allow port range for databases (3300-3999) - sudo ufw allow 3300:3999/tcp - # Allow port range for redis (6300-6999) - sudo ufw allow 6300:6999/tcp - print_status "Firewall configured" -else - print_warning "UFW not found, skipping firewall configuration" -fi - -print_status "Setup completed successfully!" -echo -echo "🎉 Your testing server is ready!" -echo -echo "Next steps:" -echo "1. Add your public SSH key to /home/deploy/.ssh/authorized_keys" -echo "2. Configure your GitHub repository secrets:" -echo " - TESTING_SERVER_HOST: $(curl -s ifconfig.me 2>/dev/null || echo 'YOUR_SERVER_IP')" -echo " - TESTING_SERVER_USER: deploy" -echo " - TESTING_SERVER_SSH_KEY: (your private SSH key)" -echo " - TESTING_DB_ROOT_PASSWORD: (choose a strong password)" -echo " - TESTING_DB_USERNAME: app_user" -echo " - TESTING_DB_PASSWORD: (choose a strong password)" -echo -echo "Useful commands:" -echo " - Monitor deployments: sudo /usr/local/bin/monitor-deployments" -echo " - Cleanup old deployments: sudo /usr/local/bin/cleanup-old-deployments" -echo " - Check nginx status: sudo systemctl status nginx" -echo " - View nginx logs: sudo journalctl -u nginx -f" -echo -print_warning "Please reboot the server or run 'newgrp docker' to apply Docker group changes" -EOF \ No newline at end of file