Image that handles database backup. It detects container with a database and handles its backup into a remote location.
Find a file
Adam Štrauch 737e6846e5
All checks were successful
Build a dev image / build (push) Successful in 13s
Release of a new version / build (release) Successful in 17s
Initial commit
2025-10-18 01:48:43 +02:00
.gitea/workflows Initial commit 2025-10-18 01:48:43 +02:00
backup.sh Initial commit 2025-10-18 01:48:43 +02:00
Dockerfile Initial commit 2025-10-18 01:48:43 +02:00
README.md Initial commit 2025-10-18 01:48:43 +02:00
Taskfile.yml Initial commit 2025-10-18 01:48:43 +02:00

Database Backup Container

A lightweight Alpine-based Docker container for backing up MariaDB and PostgreSQL databases using Restic.

Overview

This container automatically detects the database type (MariaDB or PostgreSQL) in a target container and creates backups using Restic. It supports backing up databases from other Docker containers by executing dump commands inside them.

Features

  • Multi-database support: Automatically detects and backs up MariaDB or PostgreSQL databases
  • Restic integration: Uses Restic for efficient, encrypted, and deduplicated backups
  • Docker-in-Docker: Can access and backup databases from other containers
  • Lightweight: Based on Alpine Linux for minimal footprint

Prerequisites

  • Docker with socket access (/var/run/docker.sock)
  • Target container with either MariaDB or PostgreSQL client tools
  • Restic repository (local, S3, B2, etc.)

Environment Variables

Required

Variable Description
CONTAINER Name of the Docker container where the database is running
RESTIC_PASSWORD Password for the Restic repository
RESTIC_REPOSITORY Restic repository URL (e.g., s3:s3.amazonaws.com/bucket, /data/backups)

Database-specific

For MariaDB containers:

Variable Description
MARIADB_ROOT_PASSWORD Root password for MariaDB

For PostgreSQL containers:

Variable Description
DB_USER PostgreSQL username
PGPASSWORD PostgreSQL password
DB_NAME PostgreSQL database name

Usage

Basic Usage

docker run --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-mariadb-container \
  -e RESTIC_PASSWORD=my-secret-password \
  -e RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-backup-bucket \
  -e MARIADB_ROOT_PASSWORD=db-password \
  gitea.ceperka.net/rosti/db-backup:latest

With Docker Compose

version: '3.8'

services:
  database:
    image: mariadb:latest
    environment:
      MARIADB_ROOT_PASSWORD: secretpassword
      MARIADB_DATABASE: myapp
    volumes:
      - db_data:/var/lib/mysql

  backup:
    image: gitea.ceperka.net/rosti/db-backup:latest
    depends_on:
      - database
    environment:
      CONTAINER: database
      RESTIC_PASSWORD: my-backup-password
      RESTIC_REPOSITORY: /backups
      MARIADB_ROOT_PASSWORD: secretpassword
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./backups:/backups

volumes:
  db_data:

Scheduled Backups with Cron

To run backups on a schedule, you can use cron or a container orchestrator:

# Add to crontab for daily backups at 2 AM
0 2 * * * docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -e CONTAINER=my-db -e RESTIC_PASSWORD=pass -e RESTIC_REPOSITORY=/backups -e MARIADB_ROOT_PASSWORD=dbpass gitea.ceperka.net/rosti/db-backup:latest

Kubernetes CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: database-backup
spec:
  schedule: "0 2 * * *"  # Daily at 2 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: gitea.ceperka.net/rosti/db-backup:latest
            env:
            - name: CONTAINER
              value: "my-database-pod"
            - name: RESTIC_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: backup-secrets
                  key: restic-password
            - name: RESTIC_REPOSITORY
              value: "s3:s3.amazonaws.com/my-backup-bucket"
            - name: MARIADB_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secrets
                  key: root-password
            volumeMounts:
            - name: docker-sock
              mountPath: /var/run/docker.sock
          volumes:
          - name: docker-sock
            hostPath:
              path: /var/run/docker.sock
          restartPolicy: OnFailure

Backup File Naming

Backups are stored with the following naming convention:

  • MariaDB: mariadb_[CONTAINER]_[DB_NAME].sql
  • PostgreSQL: pgsql_[CONTAINER]_[DB_NAME].sql

Supported Restic Repositories

This container supports all Restic repository types:

  • Local: /path/to/backup/dir
  • SFTP: sftp:user@host:/path/to/repo
  • S3: s3:s3.amazonaws.com/bucket
  • Azure: azure:container:/path
  • Google Cloud: gs:bucket:/path
  • Backblaze B2: b2:bucket:/path
  • REST: rest:http://host:8000/repo

Building

# Build the image
task build

# Tag as latest
task tag-latest

# Push to registry
task push

Or manually:

docker build -t gitea.ceperka.net/rosti/db-backup:dev .

Troubleshooting

Common Issues

  1. "Docker is not available"

    • Ensure Docker socket is mounted: -v /var/run/docker.sock:/var/run/docker.sock
    • Check Docker daemon is running
  2. "Unsupported database type"

    • Verify the target container has mariadb-dump or pg_dump installed
    • Check container name is correct
  3. Authentication errors

    • Verify database credentials are correct
    • Ensure environment variables are properly set

Debug Mode

To debug issues, you can run the container interactively:

docker run -it --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --entrypoint /bin/sh \
  gitea.ceperka.net/rosti/db-backup:latest

Security Considerations

  • Store sensitive environment variables in secrets (Kubernetes secrets, Docker secrets, etc.)
  • Use least-privilege access for Docker socket when possible
  • Regularly rotate Restic repository passwords
  • Consider using encrypted storage for backup repositories

License

This project is licensed under the MIT License.