134 lines
4.5 KiB
YAML
134 lines
4.5 KiB
YAML
name: Backup Docker Volumes (Remote)
|
|
|
|
on:
|
|
schedule:
|
|
- cron: '0 2 * * *' # Täglich um 2 Uhr nachts
|
|
workflow_dispatch: # Manueller Trigger
|
|
|
|
jobs:
|
|
backup:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup SSH
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
|
chmod 600 ~/.ssh/id_rsa
|
|
ssh-keyscan -H ${{ secrets.BACKUP_HOST }} >> ~/.ssh/known_hosts
|
|
|
|
- name: Create backup on remote server
|
|
run: |
|
|
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
|
|
|
|
ssh ${{ secrets.BACKUP_USER }}@${{ secrets.BACKUP_HOST }} << 'ENDSSH'
|
|
set -e
|
|
|
|
BACKUP_DATE='"$BACKUP_DATE"'
|
|
BACKUP_DIR="/tmp/backups/$BACKUP_DATE"
|
|
|
|
echo "Creating backup directory: $BACKUP_DIR"
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
echo "Listing available volumes:"
|
|
docker volume ls
|
|
|
|
# Backup Gitea Data
|
|
echo "Backing up gitea-data..."
|
|
VOLUME_NAME=$(docker volume ls --format '{{.Name}}' | grep 'gitea-data$' | head -n1)
|
|
if [ -n "$VOLUME_NAME" ]; then
|
|
docker run --rm \
|
|
-v "$VOLUME_NAME":/source:ro \
|
|
-v "$BACKUP_DIR":/backup \
|
|
alpine tar czf /backup/gitea-data.tar.gz -C /source .
|
|
echo "✓ gitea-data backed up"
|
|
else
|
|
echo "⚠ gitea-data volume not found"
|
|
fi
|
|
|
|
# Backup Gitea Database
|
|
echo "Backing up gitea-database..."
|
|
VOLUME_NAME=$(docker volume ls --format '{{.Name}}' | grep 'gitea-database$' | head -n1)
|
|
if [ -n "$VOLUME_NAME" ]; then
|
|
docker run --rm \
|
|
-v "$VOLUME_NAME":/source:ro \
|
|
-v "$BACKUP_DIR":/backup \
|
|
alpine tar czf /backup/gitea-database.tar.gz -C /source .
|
|
echo "✓ gitea-database backed up"
|
|
else
|
|
echo "⚠ gitea-database volume not found"
|
|
fi
|
|
|
|
# Backup MinIO Data
|
|
echo "Backing up minio-data..."
|
|
VOLUME_NAME=$(docker volume ls --format '{{.Name}}' | grep 'minio-data$' | head -n1)
|
|
if [ -n "$VOLUME_NAME" ]; then
|
|
docker run --rm \
|
|
-v "$VOLUME_NAME":/source:ro \
|
|
-v "$BACKUP_DIR":/backup \
|
|
alpine tar czf /backup/minio-data.tar.gz -C /source .
|
|
echo "✓ minio-data backed up"
|
|
else
|
|
echo "⚠ minio-data volume not found"
|
|
fi
|
|
|
|
# Backup Gitea Runner Data
|
|
echo "Backing up gitea-runner-data..."
|
|
VOLUME_NAME=$(docker volume ls --format '{{.Name}}' | grep 'gitea-runner-data$' | head -n1)
|
|
if [ -n "$VOLUME_NAME" ]; then
|
|
docker run --rm \
|
|
-v "$VOLUME_NAME":/source:ro \
|
|
-v "$BACKUP_DIR":/backup \
|
|
alpine tar czf /backup/gitea-runner-data.tar.gz -C /source .
|
|
echo "✓ gitea-runner-data backed up"
|
|
else
|
|
echo "⚠ gitea-runner-data volume not found"
|
|
fi
|
|
|
|
# Create manifest
|
|
cd "$BACKUP_DIR"
|
|
cat > manifest.txt << EOF
|
|
Backup created: $(date)
|
|
Hostname: $(hostname)
|
|
|
|
Files:
|
|
$(ls -lh *.tar.gz 2>/dev/null || echo "No backup files created")
|
|
|
|
Checksums (SHA256):
|
|
$(sha256sum *.tar.gz 2>/dev/null || echo "No files to checksum")
|
|
EOF
|
|
|
|
echo "Backup manifest:"
|
|
cat manifest.txt
|
|
|
|
echo "Total backup size: $(du -sh $BACKUP_DIR)"
|
|
ENDSSH
|
|
|
|
- name: Download backups from remote server
|
|
run: |
|
|
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
|
|
mkdir -p backups
|
|
|
|
echo "Downloading backups from remote server..."
|
|
scp -r ${{ secrets.BACKUP_USER }}@${{ secrets.BACKUP_HOST }}:/tmp/backups/$BACKUP_DATE backups/
|
|
|
|
echo "Downloaded files:"
|
|
ls -lh backups/$BACKUP_DATE/
|
|
|
|
- name: Upload backup artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: docker-volumes-backup-${{ env.BACKUP_DATE }}
|
|
path: backups/
|
|
retention-days: 30
|
|
|
|
- name: Cleanup remote backups
|
|
if: always()
|
|
run: |
|
|
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
|
|
ssh ${{ secrets.BACKUP_USER }}@${{ secrets.BACKUP_HOST }} "rm -rf /tmp/backups/$BACKUP_DATE"
|
|
echo "Remote backup cleaned up"
|