A self-hosted service that automates PostgreSQL backups with scheduling, retention policies, cloud storage, restore workflows, and monitoring.
Status: π§ Active development
You can run Backup Manager either as a pre-built Docker image or directly from the source code.
This is the easiest way to get started. No need to install Go or build dependencies.
- 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
- Start the service:
docker-compose up -d
Ideal for development or custom deployments.
- Clone and install tools:
git clone https://github.com/MD2SA/backup-manager.git cd backup-manager make tools - Configure and Run:
cp .env.example .env # Edit .env with your database details make migrate make dev
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/profilesIf no key is set, the application will run in Insecure Mode and display a warning on startup.
Backup Manager features professional, end-to-end encryption using the Age standard. You can choose between two modes:
Just set the APP_ENCRYPTION_PASSPHRASE environment variable. This is the easiest way to secure your backups.
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 keygenFor Source users:
go run ./cmd/api keygen.
βββ 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
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
| 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 |
- Go 1.26+
- PostgreSQL
- Docker (optional)
git clone https://github.com/MD2SA/backup-manager.git
cd backup-managerBackup Manager uses local development tools for code generation, migrations, documentation, hot reload, and linting.
Install them with:
make toolsThis installs:
- Air (hot reload)
- SQLC (database code generation)
- Goose (database migrations)
- Swag (OpenAPI documentation)
- golangci-lint (code quality checks)
Create your local environment file:
cp .env.example .envUpdate the required database and application settings.
make migrateFor normal execution:
make runFor development with hot reload:
make devGenerate SQLC code:
make sqlcGenerate Swagger/OpenAPI documentation:
make swaggermake test # Run tests
make fmt # Format Go code
make lint # Run golangci-lint
make build # Build API binary
make clean # Remove build artifactsGET /api/v1/healthResponse:
OK
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).
-
Build the image:
docker build -t backup-manager:latest . -
Configure environment: Ensure your
.envfile has the correctAPP_METADATA_DB_*(for internal state) andAPP_TARGET_DB_*(the database to backup) settings. -
Deploy with Docker Compose: For production, the base configuration starts only the manager and its metadata database:
docker-compose up -d
To test the full pipeline locally with a sample target database, use the provided development stack:
make docker-dev-upThis will start:
- Backup Manager: The microservice.
- Metadata DB: To store internal state.
- Target DB: A sample database to be backed up.
To stop the development stack:
make docker-dev-downThis 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.
- Authentication: Set
APP_ADMIN_KEY. WithAPP_ENV=productionthe service refuses to start without it, so Insecure Mode can never reach a production instance. All requests must include theX-API-Keyheader. - Reverse proxy: Put the service behind a TLS-terminating proxy (Caddy,
nginx, Traefik); configure
APP_CORS_ORIGINSwith your dashboard origin andAPP_TRUSTED_PROXIESwith the proxy IPs/CIDRs so rate limiting sees real client IPs. - Secrets at rest: Set
APP_CONFIG_ENCRYPT_KEYto 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(plusAPP_METADATA_BACKUP_PASSPHRASE), so profiles, providers, and history survive incidents. - Auto-Adaptive Identity: The Docker image automatically detects the owner
of the mounted
/backupsvolume and runs with those permissions. This ensures created backups are owned by your host user without manual configuration. You can still override this usingPUIDandPGIDenvironment 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.
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.
This project is currently under development. License information will be added before the first stable release.