7511f4e537
Adds .github/workflows/deploy.yml — manual workflow_dispatch trigger that: 1) checkouts requested ref (default main) 2) builds frontend (npm ci + npm run build) 3) tarballs app + db excluding .env/storage/vendor/node_modules/bootstrap-cache 4) ssh-deploys via stored secret LIDERRA_SSH_KEY to ubuntu@111.88.246.137 5) extracts overlay + runs /var/www/liderra/redeploy.sh (composer + migrate + restart) 6) backfills today's snapshot (slepok-stage-2 Task 2.12 Step 3) 7) runs smoke tests (migrate:status, snapshots count, service health, portal http) Why this is needed: My dev VM (89.144.17.119) → prod VM (111.88.246.137) traffic passes TCP-handshake but app-layer banner exchange times out. Same VPC, SG 0.0.0.0/0, iptables empty, fail2ban clean — drop happens on YC backbone between specific source/dest pair. GitHub Actions runners come from Azure IPs, NOT affected by this filter. One-time setup needed: GitHub Settings → Secrets → Actions → New secret Name: LIDERRA_SSH_KEY Value: content of ~/.ssh/liderra_deploy (private key, full file) Future deploys: `gh workflow run deploy.yml -f ref=main` from anywhere. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
147 lines
5.6 KiB
YAML
147 lines
5.6 KiB
YAML
name: Deploy to liderra.ru
|
||
|
||
# Запускается вручную через web-интерфейс GitHub или через `gh workflow run`.
|
||
# Решает проблему «дев-машина не достучится по SSH до прод-сервера через YC backbone»:
|
||
# GitHub Actions runner — внешний по отношению к YC, его IP не блокируется тем
|
||
# фильтром что блокирует мой dev-IP `89.144.17.119`.
|
||
#
|
||
# Требуемые secrets (Settings → Secrets and variables → Actions):
|
||
# LIDERRA_SSH_KEY — содержимое приватного ключа `~/.ssh/liderra_deploy`
|
||
# (начинается с `-----BEGIN OPENSSH PRIVATE KEY-----`).
|
||
# Host/user захардкожены — публичная информация, нет смысла в secrets.
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
ref:
|
||
description: 'Branch/tag/SHA для деплоя (по умолчанию main)'
|
||
required: true
|
||
default: 'main'
|
||
type: string
|
||
backfill_snapshot:
|
||
description: 'Запустить snapshot:backfill за сегодня (default yes)'
|
||
required: false
|
||
default: true
|
||
type: boolean
|
||
|
||
jobs:
|
||
deploy:
|
||
name: Deploy code + run redeploy.sh
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 20
|
||
concurrency:
|
||
group: liderra-prod-deploy
|
||
cancel-in-progress: false
|
||
|
||
env:
|
||
LIDERRA_HOST: 111.88.246.137
|
||
LIDERRA_USER: ubuntu
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
with:
|
||
ref: ${{ github.event.inputs.ref }}
|
||
|
||
- name: Setup Node 20
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '20'
|
||
cache: 'npm'
|
||
cache-dependency-path: app/package-lock.json
|
||
|
||
- name: Install frontend deps
|
||
working-directory: app
|
||
run: npm ci
|
||
|
||
- name: Build frontend
|
||
working-directory: app
|
||
run: npm run build
|
||
|
||
- name: Verify build artifacts present
|
||
run: |
|
||
test -f app/public/build/manifest.json
|
||
ls app/public/build/assets/ | head -5
|
||
du -sh app/public/build/
|
||
|
||
- name: Create deploy tarball
|
||
run: |
|
||
tar czf /tmp/deploy.tgz \
|
||
--exclude='app/.env' \
|
||
--exclude='app/.env.example' \
|
||
--exclude='app/.env.production' \
|
||
--exclude='app/storage' \
|
||
--exclude='app/vendor' \
|
||
--exclude='app/node_modules' \
|
||
--exclude='app/bootstrap/cache' \
|
||
app db
|
||
ls -lh /tmp/deploy.tgz
|
||
|
||
- name: Setup SSH key
|
||
run: |
|
||
mkdir -p ~/.ssh
|
||
echo "${{ secrets.LIDERRA_SSH_KEY }}" > ~/.ssh/liderra_deploy
|
||
chmod 600 ~/.ssh/liderra_deploy
|
||
ssh-keyscan -H ${{ env.LIDERRA_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
||
|
||
- name: Upload tarball to prod
|
||
run: |
|
||
scp -i ~/.ssh/liderra_deploy -o StrictHostKeyChecking=accept-new \
|
||
/tmp/deploy.tgz ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }}:/tmp/deploy.tgz
|
||
|
||
- name: Extract + run redeploy.sh on prod
|
||
run: |
|
||
ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} 'bash -s' <<'REMOTE'
|
||
set -euo pipefail
|
||
TS=$(date -u +%Y%m%d-%H%M%S)
|
||
echo "=== Backup current app ==="
|
||
sudo tar czf /home/ubuntu/deploy-backups/app-pre-deploy-${TS}.tgz \
|
||
--exclude='storage' --exclude='vendor' --exclude='node_modules' --exclude='public/build' \
|
||
-C /var/www/liderra app
|
||
ls -lh /home/ubuntu/deploy-backups/app-pre-deploy-${TS}.tgz
|
||
|
||
echo "=== Extract overlay ==="
|
||
cd /var/www/liderra
|
||
sudo tar xzf /tmp/deploy.tgz
|
||
sudo chown -R www-data:www-data /var/www/liderra/app /var/www/liderra/db
|
||
|
||
echo "=== redeploy.sh (composer + migrate + optimize + restart) ==="
|
||
sudo bash /var/www/liderra/redeploy.sh
|
||
|
||
rm -f /tmp/deploy.tgz
|
||
REMOTE
|
||
|
||
- name: Backfill today's snapshot
|
||
if: ${{ github.event.inputs.backfill_snapshot != 'false' }}
|
||
run: |
|
||
ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} 'bash -s' <<'REMOTE'
|
||
set -e
|
||
cd /var/www/liderra/app
|
||
sudo -u www-data php artisan snapshot:backfill --date=$(date +%Y-%m-%d) || \
|
||
echo "WARN: backfill returned non-zero — проверь вручную"
|
||
REMOTE
|
||
|
||
- name: Smoke tests
|
||
run: |
|
||
ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} 'bash -s' <<'REMOTE'
|
||
set -e
|
||
cd /var/www/liderra/app
|
||
echo '=== Migrations status (last 5) ==='
|
||
sudo -u www-data php artisan migrate:status 2>&1 | tail -5
|
||
echo '=== Snapshots count (last 3 dates) ==='
|
||
sudo -u postgres psql -d liderra -c "SELECT snapshot_date, COUNT(*) AS rows FROM project_routing_snapshots GROUP BY 1 ORDER BY 1 DESC LIMIT 3;" || true
|
||
echo '=== Service status ==='
|
||
systemctl is-active nginx php8.3-fpm postgresql liderra-queue
|
||
echo '=== Internal portal health ==='
|
||
curl -sf -o /dev/null -w 'https=%{http_code} time=%{time_total}s\n' --max-time 8 https://127.0.0.1/ -k || true
|
||
REMOTE
|
||
|
||
- name: External portal health (from runner)
|
||
run: |
|
||
curl -sf -o /dev/null -w 'external https=%{http_code} time=%{time_total}s\n' \
|
||
--max-time 15 https://liderra.ru/ || echo "external health returned non-zero"
|
||
|
||
- name: Cleanup SSH key
|
||
if: always()
|
||
run: rm -f ~/.ssh/liderra_deploy
|