generated from ztimson/template
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea97a26d5c |
48
.github/workflows/build.yaml
vendored
48
.github/workflows/build.yaml
vendored
@@ -1,32 +1,36 @@
|
|||||||
name: Build and publish
|
name: Build Website
|
||||||
run-name: Build and publish
|
run-name: Build Website
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
container:
|
docker:
|
||||||
name: Build Container
|
name: Build Dockerfile
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: docker
|
container: docker:dind
|
||||||
steps:
|
steps:
|
||||||
- name: Build Container
|
- name: Clone Repository
|
||||||
run: |
|
uses: ztimson/actions/clone@develop
|
||||||
git clone -b "${{github.ref_name}}" "$(echo ${{github.server_url}}/${{github.repository}}.git | sed s%://%://${{github.token}}@% )" .
|
|
||||||
DOCKER_HUB=$([ -n "${{secrets.DOCKER_HUB_USER}}" ] && [ -n "${{secrets.DOCKER_HUB_TOKEN}}" ] && [ -n "${{secrets.DOCKER_HUB_IMAGE}}" ] && echo "true" || echo "false")
|
|
||||||
REGISTRY="$(echo "${{github.server_url}}" | sed -E 's|https?://||')"
|
|
||||||
|
|
||||||
docker login -u "${{github.repository_owner}}" -p "${{secrets.DEPLOY_TOKEN}}" "$REGISTRY"
|
- name: Install Node
|
||||||
if [ "$DOCKER_HUB" = "true" ]; then docker login -u "${{secrets.DOCKER_HUB_USER}}" -p "${{secrets.DOCKER_HUB_TOKEN}}" docker.io; fi
|
run: apk add nodejs npm
|
||||||
|
|
||||||
docker build -t "$REGISTRY/${{github.repository}}:${{github.ref_name}}" .
|
- name: Set up Docker Buildx
|
||||||
docker push "$REGISTRY/${{github.repository}}:${{github.ref_name}}"
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
if [ "${{github.ref_name}}" = "master" ]; then
|
- name: Set up QEMU
|
||||||
docker tag "$REGISTRY/${{github.repository}}:${{github.ref_name}}" "$REGISTRY/${{github.repository}}:latest"
|
uses: docker/setup-qemu-action@v3
|
||||||
docker push "$REGISTRY/${{github.repository}}:latest"
|
|
||||||
if [ "$DOCKER_HUB" = "true" ]; then
|
- name: Publish Latest Tag
|
||||||
docker tag "$REGISTRY/${{github.repository}}:${{github.ref_name}}" "docker.io/${{secrets.DOCKER_HUB_IMAGE}}:latest"
|
run: |
|
||||||
docker push "docker.io/${{secrets.DOCKER_HUB_IMAGE}}:latest"
|
if [ "${{github.ref_name}}" = "master" ]; then
|
||||||
fi
|
REGISTRY=$(echo ${{github.server_url}} | sed s%http://%% | sed s%https://%%)
|
||||||
fi
|
docker login -u "${{github.repository_owner}}" -p "${{secrets.DEPLOY_TOKEN}}" "$REGISTRY"
|
||||||
|
docker login -u "${{secrets.DOCKER_HUB_USER}}" -p "${{secrets.DOCKER_HUB_TOKEN}}" docker.io
|
||||||
|
|
||||||
|
docker buildx build --platform linux/amd64,linux/arm64 \
|
||||||
|
-t "$REGISTRY/${{github.repository}}:latest" \
|
||||||
|
-t "docker.io/ztimson/kiwixm:latest" \
|
||||||
|
--push .
|
||||||
|
fi
|
||||||
|
|||||||
26
README.md
26
README.md
@@ -41,28 +41,22 @@ MongoDB + Backups & Retention
|
|||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
Custom MongoDB Docker image extending `mongo:latest` with automated backups, retention management, and replica set configuration.
|
Custom MongoDB Docker image extending `mongo:latest` with automated backup functionality.
|
||||||
|
|
||||||
Includes cron-based scheduled `mongodump` operations with compression, automatic stale lock recovery on unclean shutdowns, and zero-config replica set initialization — while preserving all native MongoDB functionality.
|
Installs cron to run scheduled mongodump operations with compression and retention management, while preserving all native MongoDB server functionality.
|
||||||
|
|
||||||
**Manually trigger a backup:**
|
Backups can be manually triggered with: `docker --exec -t mongodb backup`
|
||||||
docker exec -t mongodb backup
|
|
||||||
|
|
||||||
**Restore a backup:**
|
To restore a backup, uncompress it and use the official `mongorestore`
|
||||||
Decompress the archive and use the official `mongorestore` tool.
|
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
| Variable | Description | Default | Example |
|
| Variable | Description | Default | Example |
|
||||||
|------------------------------|----------------------------------------------------------------------|--------------------------|-----------------------|
|
|-------------------------|----------------------------|---------------|---------------|
|
||||||
| `BACKUP_CRON` | Cron schedule expression | | `0 */6 * * *` |
|
| `MONGO_INITDB_DATABASE` | Database name to backup | - | `myapp` |
|
||||||
| `BACKUP_DIR` | Directory to store backups | `/data/backups` | `/backups` |
|
| `BACKUP_CRON` | Cron schedule expression | - | `0 */6 * * *` |
|
||||||
| `BACKUP_DB` | Database to backup | `$MONGO_INITDB_DATABASE` | `admin` |
|
| `BACKUP_DIR` | Directory to store backups | /data/backups | `/backups` |
|
||||||
| `BACKUP_RETENTION` | Number of backups to keep, defaults to unlimited | | `7` |
|
| `BACKUP_RETENTION` | Number of backups to keep | - | `7` |
|
||||||
| `MONGO_INITDB_DATABASE` | Default database name | | `momentum` |
|
|
||||||
| `MONGO_INITDB_ROOT_USERNAME` | Root username for mongodump auth | | `root` |
|
|
||||||
| `MONGO_INITDB_ROOT_PASSWORD` | Root password for mongodump auth | | `secret` |
|
|
||||||
| `REPLICA` | Comma-separated list of replica hostnames to init/join a replica set | | `db1:27017,db2:27017` |
|
|
||||||
|
|
||||||
### Built With
|
### Built With
|
||||||
|
|
||||||
|
|||||||
11
backup.sh
11
backup.sh
@@ -1,16 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
|
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
|
||||||
if [[ -z "$BACKUP_DB" ]]; then BACKUP_DB="$MONGO_INITDB_DATABASE"; fi
|
BACKUP_FILE="${MONGO_INITDB_DATABASE}_${TIMESTAMP}.dump.tar.gz"
|
||||||
BACKUP_FILE="${BACKUP_DB}_${TIMESTAMP}.dump.tar.gz"
|
|
||||||
TEMP_DUMP="/tmp/mongo_dump_${TIMESTAMP}"
|
TEMP_DUMP="/tmp/mongo_dump_${TIMESTAMP}"
|
||||||
|
|
||||||
|
# Create & zip backup
|
||||||
mkdir -p "$BACKUP_DIR"
|
mkdir -p "$BACKUP_DIR"
|
||||||
mongodump --host localhost --db "$BACKUP_DB" -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --out "$TEMP_DUMP"
|
mongodump --host localhost --db "$MONGO_INITDB_DATABASE" -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --out "$TEMP_DUMP"
|
||||||
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" -C "$TEMP_DUMP" .
|
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" -C "$TEMP_DUMP" .
|
||||||
rm -rf "$TEMP_DUMP"
|
rm -rf "$TEMP_DUMP"
|
||||||
|
|
||||||
|
# Remove old backups
|
||||||
if [[ -n "$BACKUP_RETENTION" ]]; then
|
if [[ -n "$BACKUP_RETENTION" ]]; then
|
||||||
cd "$BACKUP_DIR"
|
cd "$BACKUP_DIR"
|
||||||
ls -1t ${BACKUP_DB}_*.dump.tar.gz | tail -n +$((BACKUP_RETENTION + 1)) | xargs -r rm -f
|
ls -1t ${MONGO_INITDB_DATABASE}_*.dump.tar.gz 2>/dev/null | tail -n +$((BACKUP_RETENTION + 1)) | xargs -r rm -f
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
services:
|
|
||||||
db1:
|
|
||||||
build: .
|
|
||||||
environment:
|
|
||||||
MONGO_INITDB_DATABASE: momentum
|
|
||||||
MONGO_INITDB_ROOT_USERNAME: root
|
|
||||||
MONGO_INITDB_ROOT_PASSWORD: secret
|
|
||||||
BACKUP_CRON: "0 2 * * *"
|
|
||||||
BACKUP_RETENTION: "7"
|
|
||||||
BACKUP_DIR: /data/backups
|
|
||||||
REPLICA: db1:27017,db2:27017 # CSV, Must match hostname
|
|
||||||
volumes:
|
|
||||||
- data1:/data/db
|
|
||||||
- backups:/data/backups
|
|
||||||
db2:
|
|
||||||
build: .
|
|
||||||
environment:
|
|
||||||
REPLICA: db1:27017,db2:27017 # CSV, Must match hostname
|
|
||||||
volumes:
|
|
||||||
- data2:/data/db
|
|
||||||
@@ -1,62 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Setup cron job if BACKUP_CRON is set
|
||||||
if [ -n "$BACKUP_CRON" ]; then
|
if [ -n "$BACKUP_CRON" ]; then
|
||||||
env >> /etc/environment
|
echo "$BACKUP_CRON /usr/local/bin/backup >> /var/log/mongo-backup.log 2>&1" > /etc/cron.d/mongo-backup
|
||||||
echo "$BACKUP_CRON root . /etc/environment; /usr/local/bin/backup >> /var/log/mongo-backup.log 2>&1" > /etc/cron.d/mongo-backup
|
echo "" >> /etc/cron.d/mongo-backup
|
||||||
chmod 0644 /etc/cron.d/mongo-backup
|
chmod 0644 /etc/cron.d/mongo-backup
|
||||||
cron
|
crontab /etc/cron.d/mongo-backup
|
||||||
|
cron &
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean locks & repair only if lock files exist (unclean shutdown)
|
# Execute original mongo entrypoint
|
||||||
if [ -f /data/db/mongod.lock ] || [ -f /data/db/WiredTiger.lock ] || [ -f /data/db/.lock ]; then
|
|
||||||
echo "Stale locks detected, running repair..."
|
|
||||||
rm -f /data/db/mongod.lock /data/db/.lock /data/db/WiredTiger.lock
|
|
||||||
mongod --repair
|
|
||||||
echo "Repair complete, starting normally..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$REPLICA" ]; then
|
|
||||||
# Start mongo temporarily in background with replSet enabled
|
|
||||||
mongod --replSet rs0 --bind_ip_all &
|
|
||||||
MONGO_PID=$!
|
|
||||||
|
|
||||||
# Wait for mongo to be ready
|
|
||||||
echo "Waiting for MongoDB to be ready..."
|
|
||||||
until mongosh --quiet --eval "db.runCommand({ ping: 1 })" &>/dev/null; do
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
# Build members array from REPLICA CSV
|
|
||||||
MEMBERS=""
|
|
||||||
INDEX=0
|
|
||||||
IFS=',' read -ra HOSTS <<< "$REPLICA"
|
|
||||||
for HOST in "${HOSTS[@]}"; do
|
|
||||||
[ $INDEX -gt 0 ] && MEMBERS+=","
|
|
||||||
MEMBERS+="{ _id: $INDEX, host: '$HOST' }"
|
|
||||||
INDEX=$((INDEX + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Init or reconfig replica set
|
|
||||||
mongosh --quiet --eval "
|
|
||||||
try {
|
|
||||||
const config = rs.conf();
|
|
||||||
config.members = [$MEMBERS];
|
|
||||||
rs.reconfig(config, { force: true });
|
|
||||||
print('Replica set reconfigured');
|
|
||||||
} catch(e) {
|
|
||||||
rs.initiate({ _id: 'rs0', members: [$MEMBERS] });
|
|
||||||
print('Replica set initiated');
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
# Stop the temporary mongod
|
|
||||||
kill $MONGO_PID
|
|
||||||
wait $MONGO_PID 2>/dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$REPLICA" ]; then
|
|
||||||
set -- mongod --replSet rs0 --bind_ip_all
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Hand off to normal mongo entrypoint
|
|
||||||
exec /usr/local/bin/docker-entrypoint.sh "$@"
|
exec /usr/local/bin/docker-entrypoint.sh "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user