From 6e04db4a9825e3dba79f559cc81d9ce647ef6fff Mon Sep 17 00:00:00 2001 From: Renz Date: Tue, 25 Nov 2025 18:33:34 +0000 Subject: [PATCH] feat: Add Docker support for easy distribution - Multi-stage Dockerfile for minimal image size (~119MB) - Includes PostgreSQL, MySQL, MariaDB client tools - Non-root user (UID 1000) for security - Docker Compose examples for all use cases - Complete Docker documentation (DOCKER.md) - Kubernetes CronJob examples - Support for Docker secrets - Multi-platform build support Docker makes deployment trivial: - No dependency installation needed - Consistent environment - Easy CI/CD integration - Kubernetes-ready --- .dockerignore | 21 ++++ DOCKER.md | 250 +++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 58 +++++++++++ README.md | 25 +++++ docker-compose.yml | 88 ++++++++++++++++ 5 files changed, 442 insertions(+) create mode 100644 .dockerignore create mode 100644 DOCKER.md create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..07c2240 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,21 @@ +.git +.gitignore +*.dump +*.dump.gz +*.sql +*.sql.gz +*.tar.gz +*.sha256 +*.info +.dbbackup.conf +backups/ +test_workspace/ +bin/ +dbbackup +dbbackup_* +*.log +.vscode/ +.idea/ +*.swp +*.swo +*~ diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..92b8784 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,250 @@ +# Docker Usage Guide + +## Quick Start + +### Build Image + +```bash +docker build -t dbbackup:latest . +``` + +### Run Container + +**PostgreSQL Backup:** +```bash +docker run --rm \ + -v $(pwd)/backups:/backups \ + -e PGHOST=your-postgres-host \ + -e PGUSER=postgres \ + -e PGPASSWORD=secret \ + dbbackup:latest backup single mydb +``` + +**MySQL Backup:** +```bash +docker run --rm \ + -v $(pwd)/backups:/backups \ + -e MYSQL_HOST=your-mysql-host \ + -e MYSQL_USER=root \ + -e MYSQL_PWD=secret \ + dbbackup:latest backup single mydb --db-type mysql +``` + +**Interactive Mode:** +```bash +docker run --rm -it \ + -v $(pwd)/backups:/backups \ + -e PGHOST=your-postgres-host \ + -e PGUSER=postgres \ + -e PGPASSWORD=secret \ + dbbackup:latest interactive +``` + +## Docker Compose + +### Start Test Environment + +```bash +# Start test databases +docker-compose up -d postgres mysql + +# Wait for databases to be ready +sleep 10 + +# Run backup +docker-compose run --rm postgres-backup +``` + +### Interactive Mode + +```bash +docker-compose run --rm dbbackup-interactive +``` + +### Scheduled Backups with Cron + +Create `docker-cron`: +```bash +#!/bin/bash +# Daily PostgreSQL backup at 2 AM +0 2 * * * docker run --rm -v /backups:/backups -e PGHOST=postgres -e PGUSER=postgres -e PGPASSWORD=secret dbbackup:latest backup single production_db +``` + +## Environment Variables + +**PostgreSQL:** +- `PGHOST` - Database host +- `PGPORT` - Database port (default: 5432) +- `PGUSER` - Database user +- `PGPASSWORD` - Database password +- `PGDATABASE` - Database name + +**MySQL/MariaDB:** +- `MYSQL_HOST` - Database host +- `MYSQL_PORT` - Database port (default: 3306) +- `MYSQL_USER` - Database user +- `MYSQL_PWD` - Database password +- `MYSQL_DATABASE` - Database name + +**General:** +- `BACKUP_DIR` - Backup directory (default: /backups) +- `COMPRESS_LEVEL` - Compression level 0-9 (default: 6) + +## Volume Mounts + +```bash +docker run --rm \ + -v /host/backups:/backups \ # Backup storage + -v /host/config/.dbbackup.conf:/home/dbbackup/.dbbackup.conf:ro \ # Config file + dbbackup:latest backup single mydb +``` + +## Docker Hub + +Pull pre-built image (when published): +```bash +docker pull uuxo/dbbackup:latest +docker pull uuxo/dbbackup:1.0 +``` + +## Kubernetes Deployment + +**CronJob Example:** +```yaml +apiVersion: batch/v1 +kind: CronJob +metadata: + name: postgres-backup +spec: + schedule: "0 2 * * *" # Daily at 2 AM + jobTemplate: + spec: + template: + spec: + containers: + - name: dbbackup + image: dbbackup:latest + args: ["backup", "single", "production_db"] + env: + - name: PGHOST + value: "postgres.default.svc.cluster.local" + - name: PGUSER + value: "postgres" + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: postgres-secret + key: password + volumeMounts: + - name: backups + mountPath: /backups + volumes: + - name: backups + persistentVolumeClaim: + claimName: backup-storage + restartPolicy: OnFailure +``` + +## Docker Secrets + +**Using Docker Secrets:** +```bash +# Create secrets +echo "mypassword" | docker secret create db_password - + +# Use in stack +docker stack deploy -c docker-stack.yml dbbackup +``` + +**docker-stack.yml:** +```yaml +version: '3.8' +services: + backup: + image: dbbackup:latest + secrets: + - db_password + environment: + - PGHOST=postgres + - PGUSER=postgres + - PGPASSWORD_FILE=/run/secrets/db_password + command: backup single mydb + volumes: + - backups:/backups + +secrets: + db_password: + external: true + +volumes: + backups: +``` + +## Image Size + +**Multi-stage build results:** +- Builder stage: ~500MB (Go + dependencies) +- Final image: ~100MB (Alpine + clients) +- Binary only: ~15MB + +## Security + +**Non-root user:** +- Runs as UID 1000 (dbbackup user) +- No privileged operations needed +- Read-only config mount recommended + +**Network:** +```bash +# Use custom network +docker network create dbnet + +docker run --rm \ + --network dbnet \ + -v $(pwd)/backups:/backups \ + dbbackup:latest backup single mydb +``` + +## Troubleshooting + +**Check logs:** +```bash +docker logs dbbackup-postgres +``` + +**Debug mode:** +```bash +docker run --rm -it \ + -v $(pwd)/backups:/backups \ + dbbackup:latest backup single mydb --debug +``` + +**Shell access:** +```bash +docker run --rm -it --entrypoint /bin/sh dbbackup:latest +``` + +## Building for Multiple Platforms + +```bash +# Enable buildx +docker buildx create --use + +# Build multi-arch +docker buildx build \ + --platform linux/amd64,linux/arm64,linux/arm/v7 \ + -t uuxo/dbbackup:latest \ + --push . +``` + +## Registry Push + +```bash +# Tag for registry +docker tag dbbackup:latest git.uuxo.net/uuxo/dbbackup:latest +docker tag dbbackup:latest git.uuxo.net/uuxo/dbbackup:1.0 + +# Push to private registry +docker push git.uuxo.net/uuxo/dbbackup:latest +docker push git.uuxo.net/uuxo/dbbackup:1.0 +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9fcaf3b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# Multi-stage build for minimal image size +FROM golang:1.24-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache git make + +WORKDIR /build + +# Copy go mod files +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build binary +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags="-w -s" -o dbbackup . + +# Final stage - minimal runtime image +FROM alpine:3.19 + +# Install database client tools +RUN apk add --no-cache \ + postgresql-client \ + mysql-client \ + mariadb-client \ + pigz \ + pv \ + ca-certificates \ + tzdata + +# Create non-root user +RUN addgroup -g 1000 dbbackup && \ + adduser -D -u 1000 -G dbbackup dbbackup + +# Copy binary from builder +COPY --from=builder /build/dbbackup /usr/local/bin/dbbackup +RUN chmod +x /usr/local/bin/dbbackup + +# Create backup directory +RUN mkdir -p /backups && chown dbbackup:dbbackup /backups + +# Set working directory +WORKDIR /backups + +# Switch to non-root user +USER dbbackup + +# Set entrypoint +ENTRYPOINT ["/usr/local/bin/dbbackup"] + +# Default command shows help +CMD ["--help"] + +# Labels +LABEL maintainer="UUXO" +LABEL version="1.0" +LABEL description="Professional database backup tool for PostgreSQL, MySQL, and MariaDB" diff --git a/README.md b/README.md index 233c3c3..b22b8c0 100755 --- a/README.md +++ b/README.md @@ -16,6 +16,31 @@ Professional database backup and restore utility for PostgreSQL, MySQL, and Mari ## Installation +### Docker (Recommended) + +**Pull from registry:** +```bash +docker pull git.uuxo.net/uuxo/dbbackup:latest +``` + +**Quick start:** +```bash +# PostgreSQL backup +docker run --rm \ + -v $(pwd)/backups:/backups \ + -e PGHOST=your-host \ + -e PGUSER=postgres \ + -e PGPASSWORD=secret \ + git.uuxo.net/uuxo/dbbackup:latest backup single mydb + +# Interactive mode +docker run --rm -it \ + -v $(pwd)/backups:/backups \ + git.uuxo.net/uuxo/dbbackup:latest interactive +``` + +See [DOCKER.md](DOCKER.md) for complete Docker documentation. + ### Download Pre-compiled Binary Linux x86_64: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0ba58fd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,88 @@ +version: '3.8' + +services: + # PostgreSQL backup example + postgres-backup: + build: . + image: dbbackup:latest + container_name: dbbackup-postgres + volumes: + - ./backups:/backups + - ./config/.dbbackup.conf:/home/dbbackup/.dbbackup.conf:ro + environment: + - PGHOST=postgres + - PGPORT=5432 + - PGUSER=postgres + - PGPASSWORD=secret + command: backup single mydb + depends_on: + - postgres + networks: + - dbnet + + # MySQL backup example + mysql-backup: + build: . + image: dbbackup:latest + container_name: dbbackup-mysql + volumes: + - ./backups:/backups + environment: + - MYSQL_HOST=mysql + - MYSQL_PORT=3306 + - MYSQL_USER=root + - MYSQL_PWD=secret + command: backup single mydb --db-type mysql + depends_on: + - mysql + networks: + - dbnet + + # Interactive mode example + dbbackup-interactive: + build: . + image: dbbackup:latest + container_name: dbbackup-tui + volumes: + - ./backups:/backups + environment: + - PGHOST=postgres + - PGUSER=postgres + - PGPASSWORD=secret + command: interactive + stdin_open: true + tty: true + networks: + - dbnet + + # Test PostgreSQL database + postgres: + image: postgres:15-alpine + container_name: test-postgres + environment: + - POSTGRES_PASSWORD=secret + - POSTGRES_DB=mydb + volumes: + - postgres-data:/var/lib/postgresql/data + networks: + - dbnet + + # Test MySQL database + mysql: + image: mysql:8.0 + container_name: test-mysql + environment: + - MYSQL_ROOT_PASSWORD=secret + - MYSQL_DATABASE=mydb + volumes: + - mysql-data:/var/lib/mysql + networks: + - dbnet + +volumes: + postgres-data: + mysql-data: + +networks: + dbnet: + driver: bridge