Skip to content

Commit 1988ac2

Browse files
committed
Initial creation.
1 parent d744237 commit 1988ac2

8 files changed

Lines changed: 181 additions & 1 deletion

File tree

.github/dependabot.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: 2
2+
updates:
3+
# Keep Dockerfile base images up to date
4+
- package-ecosystem: "docker"
5+
directory: "/" # Path where your Dockerfile lives
6+
schedule:
7+
interval: "weekly"
8+
labels:
9+
- "dependencies"
10+
- "docker"
11+
open-pull-requests-limit: 5
12+
commit-message:
13+
prefix: "deps(docker)"
14+
15+
# Keep GitHub Actions up to date
16+
- package-ecosystem: "github-actions"
17+
directory: "/"
18+
schedule:
19+
interval: "weekly"
20+
labels:
21+
- "dependencies"
22+
- "github-actions"
23+
commit-message:
24+
prefix: "deps(actions)"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Docker Build Check
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Docker Buildx
17+
uses: docker/setup-buildx-action@v3
18+
19+
- name: Build Docker image
20+
run: |
21+
docker build . -t test-image:pr-${{ github.event.pull_request.number }}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- 'v*.*.*' # Match tags like v1.0.0
9+
workflow_dispatch: # Allow manual trigger
10+
11+
jobs:
12+
build-and-push:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v3
18+
19+
- name: Set up Docker Buildx
20+
uses: docker/setup-buildx-action@v3
21+
22+
- name: Log in to Docker Hub
23+
uses: docker/login-action@v2
24+
with:
25+
username: ${{ secrets.DOCKERHUB_USERNAME }}
26+
password: ${{ secrets.DOCKERHUB_TOKEN }}
27+
28+
- name: Extract version tag
29+
id: version
30+
run: |
31+
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
32+
VERSION="${GITHUB_REF#refs/tags/}"
33+
else
34+
VERSION="latest"
35+
fi
36+
echo "VERSION=$VERSION" >> $GITHUB_ENV
37+
38+
- name: Build and push Docker image
39+
uses: docker/build-push-action@v5
40+
with:
41+
context: .
42+
file: ./Dockerfile
43+
push: true
44+
tags: |
45+
${{ secrets.DOCKERHUB_USERNAME }}/postgres-backup:${{ env.VERSION }}
46+
${{ secrets.DOCKERHUB_USERNAME }}/postgres-backup:latest
47+
platforms: linux/amd64,linux/arm64

Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM alpine:3.20
2+
3+
RUN apk add --no-cache \
4+
postgresql15 \
5+
rclone \
6+
redis \
7+
bash \
8+
tzdata \
9+
coreutils \
10+
busybox-suid \
11+
curl \
12+
su-exec \
13+
dcron \
14+
gzip \
15+
&& mkdir -p /scripts /backups
16+
17+
COPY backup_full.sh /scripts/backup_full.sh
18+
COPY backup_incremental.sh /scripts/backup_incremental.sh
19+
COPY entrypoint.sh /entrypoint.sh
20+
RUN chmod +x /scripts/*.sh /entrypoint.sh
21+
22+
ENTRYPOINT ["/entrypoint.sh"]

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 Scott
3+
Copyright (c) 2025 Scott Fridlund
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

backup_full.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
DATE=$(date +%F_%H-%M-%S)
5+
DEST_DIR="/backups/full/$DATE"
6+
mkdir -p "$DEST_DIR"
7+
8+
export PGPASSWORD=$(cat $PGPASSWORD_FILE)
9+
10+
echo "[$(date)] Performing full backup..."
11+
pg_dump -h "${POSTGRES_HOST}" \
12+
-p "${POSTGRES_PORT}" \
13+
-U "${POSTGRES_USER}" \
14+
"${POSTGRES_DB}" | gzip > "$DEST_DIR/$BACKUP_NAME.gz"
15+
16+
# Apply retention
17+
find /backups/full -type d -mtime +${RETENTION_FULL_DAYS} -exec rm -rf {} +
18+
19+
echo "[$(date)] Full backup completed."

backup_incremental.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
DATE=$(date +%F_%H-%M-%S)
5+
DEST_DIR="/backups/incremental/$DATE"
6+
mkdir -p "$DEST_DIR"
7+
8+
echo "[$(date)] Performing incremental backup..."
9+
10+
# Backup all WALs since last backup
11+
cp /wal_archive/* "$DEST_DIR/" || true
12+
13+
# Apply retention on the incremental backups themselves
14+
find /backups/incremental -type d -mtime +${RETENTION_INC_DAYS} -exec rm -rf {} +
15+
16+
# Clean up WAL files using pg_archivecleanup
17+
# Determine the last WAL file to keep
18+
LAST_WAL=$(ls -1 /wal_archive/* | sort | tail -n 1 || true)
19+
if [ -n "$LAST_WAL" ]; then
20+
echo "[$(date)] Cleaning up WAL archive up to $LAST_WAL"
21+
pg_archivecleanup /wal_archive "$LAST_WAL"
22+
fi
23+
24+
echo "[$(date)] Incremental backup completed."

entrypoint.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
CRON_DIR=/tmp/cron
5+
mkdir -p "$CRON_DIR"
6+
7+
ENABLE_INCREMENTAL="${ENABLE_INCREMENTAL:-true}"
8+
FULL_INTERVAL="${BACKUP_FULL_INTERVAL:-0 2 * * 0}"
9+
10+
cat > "$CRON_DIR/backup" <<EOF
11+
$FULL_INTERVAL /scripts/backup_full.sh
12+
EOF
13+
14+
if [[ "$ENABLE_INCREMENTAL" == "true" ]]; then
15+
INC_INTERVAL="${BACKUP_INCREMENTAL_INTERVAL:-0 */6 * * *}"
16+
echo "$INC_INTERVAL /scripts/backup_incremental.sh" >> "$CRON_DIR/backup"
17+
fi
18+
19+
echo "Starting dcron with schedule:"
20+
cat "$CRON_DIR/backup"
21+
22+
# Use busybox crond (non-root safe)
23+
exec busybox crond -f -l 8 -c "$CRON_DIR"

0 commit comments

Comments
 (0)