A self-hosted backup management system with a web UI, supporting multiple destinations including local drives, cloud storage, SFTP, and WebDAV.
Multiple Backup Destinations
Job Management
Directory Compression
Customizable Job List
Security
Lightweight
| Provider | Description | Authentication |
|---|---|---|
| Local/USB | Rsync to local or mounted drives | None |
| AWS S3 | S3 and S3-compatible storage | Access Key + Secret |
| Google Drive | Google Drive folders and shared drives | OAuth2 |
| OneDrive | Microsoft OneDrive personal/business | OAuth2 |
| SFTP | SSH/SFTP servers | Password or SSH Key |
| WebDAV | Nextcloud, ownCloud, generic WebDAV | Username + Password |
# Create a directory for Dynamight
mkdir dynamight && cd dynamight
# Download the example config and docker-compose file
curl -O https://raw.githubusercontent.com/moonwhaler/dynamight/main/dynamight.toml.example
curl -O https://raw.githubusercontent.com/moonwhaler/dynamight/main/docker-compose.yml
# Create your configuration
cp dynamight.toml.example dynamight.toml
# Set a secure JWT secret (required)
NEW_SECRET=$(openssl rand -base64 32)
sed -i "s|CHANGE-ME-generate-with-openssl-rand-base64-32|${NEW_SECRET}|" dynamight.toml
# Start the container
docker compose up -d
Access the UI at http://localhost:8080 and complete the setup wizard to create your admin account.
services:
dynamight:
image: ghcr.io/moonwhaler/dynamight:latest
container_name: dynamight
restart: unless-stopped
cap_add:
- SYS_ADMIN
devices:
- /dev:/dev
ports:
- "8080:8080"
volumes:
- ./dynamight.toml:/app/config/dynamight.toml:ro
- dynamight-data:/app/data
- dynamight-logs:/app/logs
- /mnt:/mnt:rshared
# Add your backup sources (read-only recommended):
# - /home:/source/home:ro
# - /var/www:/source/www:ro
environment:
- TZ=${TZ:-UTC}
- RUST_LOG=${RUST_LOG:-info,dynamight=debug}
security_opt:
- no-new-privileges:true
volumes:
dynamight-data:
dynamight-logs:
Configuration is done via a TOML file (dynamight.toml). Environment variables can override any setting.
Copy dynamight.toml.example to dynamight.toml and edit:
[security]
jwt_secret = "your-secret-here" # Generate with: openssl rand -base64 32
secure_cookies = true
allowed_browse_paths = ["/mnt", "/home", "/media"]
[server]
host = "0.0.0.0"
port = 8080
[database]
url = "sqlite:data/dynamight.db"
See dynamight.toml.example for all available options with detailed documentation.
dynamight.toml)DYNAMIGHT_CONFIG environment variable (if set)./dynamight.toml (current directory)/etc/dynamight/dynamight.toml (system-wide)Any setting can be overridden via environment variables using SCREAMING_SNAKE_CASE:
| Setting | Environment Variable |
|---|---|
security.jwt_secret |
JWT_SECRET |
server.host |
HOST |
server.port |
PORT |
database.url |
DATABASE_URL |
security.allowed_browse_paths |
ALLOWED_BROWSE_PATHS (comma-separated) |
| Setting | Default | Description |
|---|---|---|
security.jwt_secret |
required | Secret for JWT signing and credential encryption |
server.host |
0.0.0.0 |
Network interface to bind |
server.port |
8080 |
Port to listen on |
database.url |
sqlite:data/dynamight.db |
SQLite database location |
security.secure_cookies |
true |
Require HTTPS for cookies |
security.allowed_browse_paths |
["/mnt", "/home", "/media"] |
Paths users can browse |
rate_limit.max_attempts |
5 |
Max failed auth attempts before lockout |
# Start both backend and frontend with one command
./scripts/dev.sh
This will:
dynamight.toml from dynamight.toml.example with a random JWT secret# Create config file in project root
cp dynamight.toml.example dynamight.toml
# Edit dynamight.toml and set jwt_secret
# Or generate one: openssl rand -base64 32
# Create data directory
mkdir -p data
# Run the backend
cd backend
cargo run
cd frontend
npm install
npm run dev
./scripts/build.sh
Creates dist/dynamight-<timestamp>.tar.gz containing:
# Build locally
docker build -t dynamight .
# Or use the build script (builds native package + Docker image)
./scripts/build.sh
# Build and push to registry
./scripts/build.sh --docker-only --push
# Extract package
tar -xzf dynamight-*.tar.gz
cd dynamight-*
# Install as system service
sudo ./scripts/install.sh
This will:
dynamight system user/opt/dynamight/etc/dynamight/dynamight.toml (with auto-generated JWT secret)/var/lib/dynamightThen configure and start:
# Review/edit configuration (optional - defaults are sensible)
sudo nano /etc/dynamight/dynamight.toml
# Enable and start service
sudo systemctl enable dynamight
sudo systemctl start dynamight
# Check status
sudo systemctl status dynamight
# View logs
journalctl -u dynamight -f
sudo ./scripts/install.sh uninstall
Credentials for cloud providers are stored encrypted. Manage them in Settings:
Add schedules in the job detail page:
Enable 2FA for additional security:
Customise which columns appear in the job list:
Schedules run according to the server's configured timezone (server.timezone in dynamight.toml or the TZ environment variable). Set this to your local timezone (e.g. Europe/Berlin, America/New_York) so that "Daily at 03:00" means 3 AM local time, not UTC.
┌─────────────────┐ ┌─────────────────────────────┐ ┌────────────┐
│ Browser │────▶│ Axum Server │────▶│ SQLite │
│ (Svelte SPA) │◀────│ (Rust) │◀────│ │
└─────────────────┘ └──────────┬──────────────────┘ └────────────┘
│
▼
┌─────────────────────────────┐
│ Provider Layer │
│ ┌─────┐ ┌────┐ ┌──────┐ │
│ │Rsync│ │ S3 │ │GDrive│ │
│ └─────┘ └────┘ └──────┘ │
│ ┌──────┐ ┌────┐ ┌──────┐ │
│ │OneDrv│ │SFTP│ │WebDAV│ │
│ └──────┘ └────┘ └──────┘ │
└─────────────────────────────┘
See project-description.md for detailed architecture documentation.
For complete API documentation, see docs/API.md.
| Endpoint | Method | Description |
|---|---|---|
/api/auth/setup-required |
GET | Check if setup needed |
/api/auth/setup |
POST | Initial admin setup |
/api/auth/login |
POST | Authenticate user |
/api/auth/logout |
POST | End session |
/api/auth/me |
GET | Get current user |
/api/auth/change-password |
POST | Change password |
| Endpoint | Method | Description |
|---|---|---|
/api/auth/totp/setup |
POST | Generate TOTP secret |
/api/auth/totp/enable |
POST | Enable 2FA |
/api/auth/totp/disable |
POST | Disable 2FA |
/api/auth/totp/validate |
POST | Validate TOTP code |
/api/auth/totp/recovery |
POST | Use recovery code |
/api/auth/totp/status |
GET | Get 2FA status |
| Endpoint | Method | Description |
|---|---|---|
/api/jobs |
GET | List all jobs |
/api/jobs |
POST | Create job |
/api/jobs/:id |
GET | Get job details |
/api/jobs/:id |
PUT | Update job |
/api/jobs/:id |
DELETE | Delete job |
/api/jobs/:id/run |
POST | Run job |
/api/jobs/:id/cancel |
POST | Cancel running job |
/api/jobs/:id/clone |
POST | Clone job |
| Endpoint | Method | Description |
|---|---|---|
/api/jobs/:id/schedules |
GET | List job schedules |
/api/jobs/:id/schedules |
POST | Create schedule |
/api/schedules/:id |
PUT | Update schedule |
/api/schedules/:id |
DELETE | Delete schedule |
| Endpoint | Method | Description |
|---|---|---|
/api/jobs/:id/runs |
GET | List job runs |
/api/runs/:id |
GET | Get run details |
/api/runs/:id |
DELETE | Delete run |
/api/runs/:id/logs |
GET | Get run logs |
/api/ws/logs/:runId |
WS | Stream live logs |
/api/ws/status |
WS | Global status updates |
| Endpoint | Method | Description |
|---|---|---|
/api/credentials |
GET | List credentials |
/api/credentials |
POST | Create credential |
/api/credentials/:id |
GET | Get credential |
/api/credentials/:id |
PUT | Update credential |
/api/credentials/:id |
DELETE | Delete credential |
/api/credentials/:id/usage |
GET | Get credential usage |
| Endpoint | Method | Description |
|---|---|---|
/api/providers |
GET | List providers |
/api/providers/:type/capabilities |
GET | Get capabilities |
/api/providers/test |
POST | Test connection |
| Endpoint | Method | Description |
|---|---|---|
/api/system/health |
GET | Health check |
/api/system/drives |
GET | List USB drives |
/api/system/mounts |
GET | List mount points |
/api/system/mount |
POST | Mount drive |
/api/system/unmount |
POST | Unmount drive |
/api/system/browse |
GET | Browse filesystem |
/api/system/mkdir |
POST | Create directory |
/api/system/allowed-paths |
GET | Get allowed paths |
/api/settings |
GET/PUT | App settings |
SYS_ADMIN capability for mount operations. Use no-new-privileges security option.:ro) when possible.Ensure the container has proper capabilities:
cap_add:
- SYS_ADMIN
devices:
- /dev:/dev
/dev is mounted in the containersudo blkiddocker compose logs dynamightMount source directories as volumes:
volumes:
- /path/to/source:/source/mydata:ro
Wait for lockout to expire (check logs for duration) or restart the application.
Contributions are welcome! Please:
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)This project is licensed under the MIT License - see the LICENSE file for details.