ci/cd #12
64
.env.testing.example
Normal file
64
.env.testing.example
Normal file
@ -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!
|
||||||
247
.gitea/workflows/deploy-testing.yml
Normal file
247
.gitea/workflows/deploy-testing.yml
Normal file
@ -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
|
||||||
|
});
|
||||||
237
.gitea/workflows/test-deployment.yml
Normal file
237
.gitea/workflows/test-deployment.yml
Normal file
@ -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
|
||||||
238
DEPLOYMENT-README.md
Normal file
238
DEPLOYMENT-README.md
Normal file
@ -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) для подробной конфигурации.
|
||||||
209
DEPLOYMENT.md
Normal file
209
DEPLOYMENT.md
Normal file
@ -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-(?<pr_number>\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
|
||||||
|
```
|
||||||
178
QUICK-START.md
Normal file
178
QUICK-START.md
Normal file
@ -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%)
|
||||||
|
```
|
||||||
293
scripts/setup-testing-server.sh
Executable file
293
scripts/setup-testing-server.sh
Executable file
@ -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 <<EOF
|
||||||
|
# Configuration for testing deployments
|
||||||
|
# This allows access via pr-123.testing.yourdomain.com
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name ~^pr-(?<pr_number>\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
|
||||||
Reference in New Issue
Block a user