Database Backup #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Database Backup | |
| # Scheduled and on-demand PostgreSQL backups. | |
| # - Runs every day at 03:00 UTC. | |
| # - Can be triggered manually via the "Run workflow" button (workflow_dispatch). | |
| # - Streams a compressed pg_dump to S3, enforces the retention policy, and | |
| # verifies the freshest backup by restoring it into a throwaway database. | |
| # - On failure, posts an alert to Slack (if SLACK_WEBHOOK_URL is configured). | |
| on: | |
| schedule: | |
| # 03:00 UTC daily. | |
| - cron: '0 3 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| verify: | |
| description: 'Verify the latest backup after creating it' | |
| type: boolean | |
| default: true | |
| verify_only: | |
| description: 'Skip the backup and only verify the latest existing backup' | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: db-backup | |
| cancel-in-progress: false | |
| jobs: | |
| backup: | |
| name: Backup PostgreSQL | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| env: | |
| DATABASE_URL: ${{ secrets.BACKUP_DATABASE_URL }} | |
| BACKUP_S3_BUCKET: ${{ secrets.BACKUP_S3_BUCKET }} | |
| BACKUP_S3_PREFIX: ${{ vars.BACKUP_S3_PREFIX || 'aethermint/db' }} | |
| BACKUP_S3_ENDPOINT: ${{ vars.BACKUP_S3_ENDPOINT }} | |
| AWS_ACCESS_KEY_ID: ${{ secrets.BACKUP_AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.BACKUP_AWS_SECRET_ACCESS_KEY }} | |
| AWS_REGION: ${{ vars.BACKUP_AWS_REGION || 'us-east-1' }} | |
| RETAIN_DAILY: ${{ vars.RETAIN_DAILY || '7' }} | |
| RETAIN_WEEKLY: ${{ vars.RETAIN_WEEKLY || '4' }} | |
| RETAIN_MONTHLY: ${{ vars.RETAIN_MONTHLY || '6' }} | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| ALERT_EMAIL_WEBHOOK: ${{ secrets.ALERT_EMAIL_WEBHOOK }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install PostgreSQL 16 client | |
| run: | | |
| sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' | |
| curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/pgdg.gpg | |
| sudo apt-get update | |
| sudo apt-get install -y postgresql-client-16 | |
| - name: Verify AWS CLI | |
| run: aws --version | |
| - name: Run backup | |
| run: | | |
| ARGS="" | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| if [ "${{ inputs.verify_only }}" = "true" ]; then | |
| ARGS="--verify-only" | |
| elif [ "${{ inputs.verify }}" = "false" ]; then | |
| ARGS="--no-verify" | |
| fi | |
| fi | |
| chmod +x scripts/backup-db.sh | |
| ./scripts/backup-db.sh $ARGS | |
| - name: Notify on failure | |
| if: failure() | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| run: | | |
| if [ -n "$SLACK_WEBHOOK_URL" ]; then | |
| curl -fsS -X POST -H 'Content-type: application/json' \ | |
| --data "{\"text\":\"🔴 AetherMint DB backup workflow failed — run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}" \ | |
| "$SLACK_WEBHOOK_URL" || echo "Slack notification failed" | |
| else | |
| echo "SLACK_WEBHOOK_URL not set; skipping Slack notification" | |
| fi |