Skip to content

Repository files navigation

Backup Manager

A self-hosted service that automates PostgreSQL backups with scheduling, retention policies, cloud storage, restore workflows, and monitoring.

Status: 🚧 Active development


πŸš€ Getting Started

You can run Backup Manager either as a pre-built Docker image or directly from the source code.

Option A: Docker Image (Recommended)

This is the easiest way to get started. No need to install Go or build dependencies.

  1. Create a docker-compose.yml:
    services:
      backup-manager:
        image: md2sa/backup-manager:latest
        ports:
          - "8080:8080"
        environment:
          - APP_BACKUP_PATH=./backups
          - APP_METADATA_DB_URL=postgres://...
          - APP_TARGET_DB_HOST=...
          - APP_ADMIN_KEY=your-secure-api-key # Optional but recommended
          # - APP_ENCRYPTION_PASSPHRASE=... (Optional for simple encryption)
        volumes:
          - ./backups:/backups
  2. Start the service:
    docker-compose up -d

Option B: From Source

Ideal for development or custom deployments.

  1. Clone and install tools:
    git clone https://github.com/MD2SA/backup-manager.git
    cd backup-manager
    make tools
  2. Configure and Run:
    cp .env.example .env
    # Edit .env with your database details
    make migrate
    make dev

πŸ” Security

API Authentication

To protect your API, set the APP_ADMIN_KEY environment variable. Once set, all requests to the /api/v1 endpoints must include the X-API-Key header:

curl -H "X-API-Key: your-secure-api-key" http://localhost:8080/api/v1/profiles

If no key is set, the application will run in Insecure Mode and display a warning on startup.

Backup Encryption

Backup Manager features professional, end-to-end encryption using the Age standard. You can choose between two modes:

1. Simple Mode (Passphrase)

Just set the APP_ENCRYPTION_PASSPHRASE environment variable. This is the easiest way to secure your backups.

2. Pro Mode (X25519 Keypair)

For maximum security, you can use a public/private key pair. Generate them using the built-in utility:

For Docker users:

docker run --rm md2sa/backup-manager:latest keygen

For Source users:

go run ./cmd/api keygen

Project Structure

.
β”œβ”€β”€ cmd/                   # Application entry points
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ api/               # REST API layer (Handlers, DTOs)
β”‚   β”œβ”€β”€ app/               # App initialization and wiring (DI)
β”‚   β”œβ”€β”€ backup/            # Core Backup Engine (Runner, Pipeline, Stages)
β”‚   β”œβ”€β”€ repository/        # Data access layer (Postgres + SQLC)
β”‚   β”œβ”€β”€ service/           # Domain business logic
β”‚   β”œβ”€β”€ storage/           # Storage provider implementations
β”‚   β”œβ”€β”€ notification/      # Notification provider implementations
β”‚   β”œβ”€β”€ retention/         # Retention policy engine
β”‚   └── verification/      # Integrity verification logic
β”œβ”€β”€ sql/                   # SQL migrations and queries
└── docs/                  # Documentation and OpenAPI specs

Architecture

Backup Manager follows a Modular Monolith architecture.

Each package represents a business domain with a single responsibility. Business logic is kept independent from infrastructure, making it straightforward to introduce new storage providers, notification providers, or verification strategies without impacting the rest of the application.

Core domains include:

  • Backup – Coordinates the backup pipeline
  • Storage – Uploads and manages backup artifacts
  • Retention – Applies GFS retention policies
  • Verification – Validates backup integrity
  • Notifications – Sends backup events
  • Repository – Database persistence
  • Service – Coordinates business operations
  • API – Exposes REST endpoints

Technology Stack

Component Technology
Language Go
HTTP Router Chi
API Documentation OpenAPI / Swagger
Database PostgreSQL
Database Access pgx + sqlc
Migrations Goose
Logging slog
Configuration Environment Variables
Validation go-playground/validator
Hot Reload Air
Linting golangci-lint
Containers Docker & Docker Compose

Getting Started

Requirements

  • Go 1.26+
  • PostgreSQL
  • Docker (optional)

Clone

git clone https://github.com/MD2SA/backup-manager.git

cd backup-manager

Install development tools

Backup Manager uses local development tools for code generation, migrations, documentation, hot reload, and linting.

Install them with:

make tools

This installs:

  • Air (hot reload)
  • SQLC (database code generation)
  • Goose (database migrations)
  • Swag (OpenAPI documentation)
  • golangci-lint (code quality checks)

Configure environment

Create your local environment file:

cp .env.example .env

Update the required database and application settings.

Run database migrations

make migrate

Run the API

For normal execution:

make run

For development with hot reload:

make dev

Generate code

Generate SQLC code:

make sqlc

Generate Swagger/OpenAPI documentation:

make swagger

Other commands

make test      # Run tests
make fmt       # Format Go code
make lint      # Run golangci-lint
make build     # Build API binary
make clean     # Remove build artifacts

Health Check

GET /api/v1/health

Response:

OK

Production Deployment

Running with Docker

Backup Manager is designed to be deployed as a containerized microservice. The provided Dockerfile uses a multi-stage build to keep the image small and secure (running as a non-root user).

  1. Build the image:

    docker build -t backup-manager:latest .
  2. Configure environment: Ensure your .env file has the correct APP_METADATA_DB_* (for internal state) and APP_TARGET_DB_* (the database to backup) settings.

  3. Deploy with Docker Compose: For production, the base configuration starts only the manager and its metadata database:

    docker-compose up -d

Local Development & Testing

To test the full pipeline locally with a sample target database, use the provided development stack:

make docker-dev-up

This will start:

  1. Backup Manager: The microservice.
  2. Metadata DB: To store internal state.
  3. Target DB: A sample database to be backed up.

To stop the development stack:

make docker-dev-down

This service exposes only an HTTP API (/api/v1). It is designed to be consumed by dashboards and tools built by whoever operates it; there is no bundled UI.

Important Deployment Notes

  • Authentication: Set APP_ADMIN_KEY. With APP_ENV=production the service refuses to start without it, so Insecure Mode can never reach a production instance. All requests must include the X-API-Key header.
  • Reverse proxy: Put the service behind a TLS-terminating proxy (Caddy, nginx, Traefik); configure APP_CORS_ORIGINS with your dashboard origin and APP_TRUSTED_PROXIES with the proxy IPs/CIDRs so rate limiting sees real client IPs.
  • Secrets at rest: Set APP_CONFIG_ENCRYPT_KEY to encrypt provider credentials (S3, Discord) in the metadata database. Changing it later invalidates existing provider configs.
  • Metadata database is internal in the production compose stack β€” it exposes no host ports and is reachable only by the manager container.
  • Disaster recovery built-in: each backup execution also uploads an encrypted snapshot of the management state (profiles, providers, history) to the same storage providers, so a fresh instance can be rebuilt. See docs/guides/CONFIGURATION.md β†’ "Metadata Disaster Recovery".
  • Protect the database you manage: enable the metadata self-backup with APP_METADATA_BACKUP_SCHEDULE (plus APP_METADATA_BACKUP_PASSPHRASE), so profiles, providers, and history survive incidents.
  • Auto-Adaptive Identity: The Docker image automatically detects the owner of the mounted /backups volume and runs with those permissions. This ensures created backups are owned by your host user without manual configuration. You can still override this using PUID and PGID environment variables.
  • Database Compatibility: The image includes postgresql16-client. This is compatible with PostgreSQL 13 through 17.
  • Automatic Migrations: The container automatically runs database migrations on the metadata database during startup. If migrations fail, the container will exit with an error.

Contributing

This project is currently under active development and is not accepting external contributions yet.

Contribution guidelines will be added once the project reaches a more stable stage.


License

This project is currently under development. License information will be added before the first stable release.

About

A PostgreSQL backup manager with profiles, retention policies, and pluggable storage and notification providers.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages