ChaCha20-Authenticated Backup Protection for Docker/Podman Directories and Volumes
with authenticated encryption, compression, smart retention, incremental backups, deduplication, and real-time notifications.
Chantik β A robust backup solution, originally built for the digital-independence project, now available for general use. Chantik provides protection with ChaCha20-Poly1305 authenticated encryption, smart retention policies, and comprehensive automation features.
| Feature | Description |
|---|---|
| π Authenticated Encryption | ChaCha20-Poly1305 (primary) with AES-256-CBC fallback |
| π Strong Key Derivation | PBKDF2 with configurable iterations (default: 600,000) |
| π Deduplication | Fixed nonce support for deterministic encryption |
| ποΈ Compression | Gzip with configurable level (1-9) |
| π³ Container Support | Backup and restore Docker and Podman volumes |
| π Incremental Backup | Saves storage and speeds up backups |
| π Smart Retention | Daily, weekly, and monthly retention policies |
| π Real-time Notifications | Instant alerts via ntfy.sh |
| β Integrity Verification | SHA256 checksum verification for every backup |
| π Security | Configurable permissions and process locking |
| π Comprehensive Logging | Detailed logs for auditing and troubleshooting |
| π― Multi-Container Runtime | Supports Docker and Podman automatically |
Ensure your system has:
- Bash 4.0+
- Docker or Podman (if backing up volumes)
- OpenSSL with ChaCha20 support
- gzip, tar, curl
- find, grep, sed, awk
- df, du, hostname, sha256sum-
Clone the repository:
git clone https://git.ricalnet.my.id/chantik.git cd chantik -
Set up an alias for ease of use:
# For Zsh (common on macOS and most modern Linux distros) nano ~/.zshrc # Or for Bash (default on many systems) nano ~/.bashrc # Add the following line to the appropriate file: alias chantik='/path/to/chantik/chantik.sh' # Example: if you cloned to /home/user/chantik alias chantik='/home/user/chantik/chantik.sh' # Save the file and reload the configuration: source ~/.zshrc # or source ~/.bashrc # Now you can run Chantik from anywhere: chantik backup chantik list chantik restore postgres_data
-
Generate an encryption key:
openssl rand -base64 32 > encryption.key chmod 600 encryption.key -
(Optional) Generate a fixed salt for deduplication:
openssl rand -hex 8 > fixed_salt.txt chmod 600 fixed_salt.txt -
Create a configuration from the example:
cp chantik.conf.example chantik.conf
-
Edit the configuration with your settings:
nano chantik.conf
-
Make the script executable:
chmod +x chantik.sh
-
Test the encryption system:
chantik test
chantik backup
# Example output:
ββββββββββββββββββββββββββββββββββββββββββββββ
[2026-09-09 23:06:03] ββββββββββββββββββββββββββββββββββββββββββββββ
[2026-09-09 23:06:03] ποΈ Starting Chantik (v0.1.4)
[2026-09-09 23:06:03] ββββββββββββββββββββββββββββββββββββββββββββββ
[2026-09-09 23:06:03] π¬ ChaCha20-Authenticated Backup Protection
[2026-09-09 23:06:03] π In ChaCha We Trust β Authentically Secured
[2026-09-09 23:06:03]
β
Config loaded: /home/user/chantik/chantik.conf
β
Runtime: podman
[2026-09-09 23:06:06] π³ Container runtime: podman
[2026-09-09 23:06:06] π Source: /home/user/my-projects
[2026-09-09 23:06:06] π Size: 78.4 KB (33 files, 23 dirs)
[2026-09-09 23:06:06] π³ Volumes: 37 volumes
[2026-09-09 23:06:06] πΎ Target: /path/kto/BACKUP/my-bacups
[2026-09-09 23:06:06] πΏ Free: 761.6 GB
[2026-09-09 23:06:06] π Encryption: CHACHA20
[2026-09-09 23:06:06] π PBKDF2: 600000
[2026-09-09 23:06:06] π Dedup: DISABLED
[2026-09-09 23:06:06] ποΈ Compression: gzip level 6
[2026-09-09 23:06:06] π Retention: D7/W4/M6
[2026-09-09 23:06:06] π Incremental: ENABLED (7 days)
[2026-09-09 23:06:07] π Backup directory created: /path/to/BACKUP/my-backups/chantik-backup_20260909_230607
[2026-09-09 23:06:08] π¦ INCREMENTAL backup of /home/user/my-projects (since 2026-09-09 22:56:24)
[2026-09-09 23:06:08] Backing up directory: /home/user/my-projects
[2026-09-09 23:06:08] Creating INCREMENTAL backup archive...
[2026-09-09 23:06:08] π Found 33 changed files
[2026-09-09 23:06:08] ποΈ Compressing...
[2026-09-09 23:06:08] β
Compression complete
[2026-09-09 23:06:08] β
INCREMENTAL backup: digital-independence_20260909_230607_inc.tar.gz.enc (31.2 KB)
[2026-09-09 23:06:08] π¦ Podman volume 1: element_nginx_conf
[2026-09-09 23:06:08] π¦ INCREMENTAL backup of volume: element_nginx_conf (since 2026-09-09 22:56:37)
[2026-09-09 23:06:08] π¦ Backing up volume: element_nginx_conf
element_nginx_conf_snapshot_19911
ddbb9a592b309c9c79d3190869757428ece7e9f38315d25e7e5a1cef40764aa0
chantik_copy_19911
[2026-09-09 23:06:22] Creating INCREMENTAL backup archive for volume...
element_nginx_conf_snapshot_19911
[2026-09-09 23:06:23] ποΈ Compressing...
[2026-09-09 23:06:23] β
FULL volume backup: volume_element_nginx_conf_20260909_230608_inc.tar.gz.enc (606 B)
[2026-09-09 23:06:23] β
Podman volume element_nginx_conf backed up successfully| Variable | Description | Example |
|---|---|---|
BACKUP_BASE_DIR |
Where encrypted backups are stored | /media/backup |
SOURCE_DIR |
Main directory to back up | /home/user/digital-independence |
DOCKER_VOLUMES |
Docker volume names | ("postgres_data" "redis_cache") |
PODMAN_VOLUMES |
Podman volume names | ("podman_data" "podman_config") |
CONTAINER_RUNTIME |
Container runtime (auto/docker/podman) | auto |
ENCRYPTION_KEY_FILE |
Path to encryption key | /home/user/chantik/encryption.key |
NTFY_TOPIC |
ntfy.sh topic for notifications | my-backup-topic |
NTFY_TOKEN |
ntfy.sh authentication token | tk_xxxxxxxxxxxxxxxx |
| Variable | Description | Default |
|---|---|---|
ENCRYPTION_CIPHER |
Cipher used (auto-detected) | chacha20 |
PBKDF2_ITERATIONS |
Key derivation iterations (100,000+) | 600000 |
FIXED_SALT_FILE |
Fixed salt for deterministic encryption | (optional) |
INCREMENTAL_ENABLED |
Enable incremental backups | true |
FULL_BACKUP_INTERVAL |
Days between full backups | 7 |
RETENTION_DAILY |
Number of daily backups to keep | 7 |
RETENTION_WEEKLY |
Number of weekly backups to keep | 4 |
RETENTION_MONTHLY |
Number of monthly backups to keep | 6 |
GZIP_LEVEL |
Compression level (1-9) | 6 |
DEDUP_TOOL |
Deduplication tool (hardlink/jdupes) | hardlink |
VERBOSE |
Enable detailed debug output | false |
BACKUP_PREFIX |
Backup directory prefix | chantik-backup |
EXCLUDE_PATTERNS |
File/directory exclusion patterns | *.tmp,*.log |
MAX_BACKUP_SIZE_MB |
Maximum backup size limit | 0 (unlimited) |
NTFY_CUSTOM_SERVER |
Custom ntfy server URL | (empty) |
DOCKER_IMAGE |
Image for helper container | alpine:latest |
Enabling Deduplication
Generate a fixed salt:
openssl rand -hex 8 > fixed_salt.txt
chmod 600 fixed_salt.txtIn chantik.conf:
FIXED_SALT_FILE="/path/to/fixed_salt.txt"
DEDUP_TOOL="hardlink"Using Podman
In chantik.conf:
CONTAINER_RUNTIME="podman"
PODMAN_VOLUMES=(
"postgres_data"
"redis_cache"
)Custom ntfy Server
In chantik.conf:
NTFY_CUSTOM_SERVER="https://ntfy.your-domain.com"# Run a backup (full or incremental based on config)
chantik backup
# Test the encryption/decryption system
chantik test
# List all available backups
chantik list
# Verify the integrity of a specific backup
chantik verify /path/to/backup.enc
# Verify all backups
chantik verify-all
# Restore from backup
chantik restore <pattern>
# Restore with dry-run (no changes)
chantik restore --dry-run <pattern>
# Restore multiple backups at once
chantik restore volume_postgres volume_redis
# Run deduplication on the backup directory
chantik dedup
# Show help
chantik help# Restore all backups matching 'postgres'
chantik restore postgres
# Restore backups from a specific date
chantik restore 20260906
# Restore multiple volumes at once
chantik restore vol1 vol2 vol3
# Restore with comma separator
chantik restore "postgres,redis"
# Dry-run restore (see what would be restored)
chantik restore --dry-run postgreschantik-backup_YYYYMMDD_HHMMSS/
βββ digital-independence_YYYYMMDD_HHMMSS_full.tar.gz.enc # Full backup
βββ digital-independence_YYYYMMDD_HHMMSS_inc.tar.gz.enc # Incremental backup
βββ volume_postgres_data_YYYYMMDD_HHMMSS_full.tar.gz.enc # Full volume backup
βββ volume_redis_cache_YYYYMMDD_HHMMSS_inc.tar.gz.enc # Incremental volume backup
βββ *.checksums # SHA256 checksums
βββ *.enc.checksums # Encrypted file checksums
- Primary cipher is ChaCha20βPoly1305 (authenticated encryption)
- Fallback cipher is AESβ256βCBC with PBKDF2 key derivation
- Key derivation uses PBKDF2 with configurable iterations (default 600,000)
- Key strength is 256βbit encryption
- Integrity is guaranteed by SHA256 checksums for verification
- Every backup is verified against potential tampering
- Fixed nonce support for deterministic deduplication
- Never commit configuration to version control
- Protect the encryption key:
chmod 600 encryption.key - Store the encryption key separately from backups
- Use a strong ntfy.sh token
- Rotate encryption keys regularly
- Test restores periodically
- Use high PBKDF2 iterations (600,000+)
Generate a new encryption key:
openssl rand -base64 32 > encryption.key
chmod 600 encryption.keyGenerate a fixed salt for deduplication:
openssl rand -hex 8 > fixed_salt.txt
chmod 600 fixed_salt.txtBack up the encryption key separately (GPG):
gpg -c encryption.keyChantik integrates with ntfy.sh for real-time notifications.
- Get an ntfy token: Visit https://ntfy.sh/account
- Choose a unique topic name
- Configure in
chantik.conf:NTFY_TOPIC="my-backup-topic" NTFY_TOKEN="tk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
| Type | Priority | Tag | When Triggered |
|---|---|---|---|
| Success | 3 (default) | β | Backup completed successfully |
| Error | 5 (urgent) | π΄ | Backup failed or interrupted |
| Info | 3 | βΉοΈ | Backup started, config loaded |
| Restore | 3 | π | Restore operation completed |
Chantik uses a smart retention policy:
- Daily backups: Keep the last
RETENTION_DAILYdays (default: 7) - Weekly backups: Keep the last
RETENTION_WEEKLYweeks (default: 4) - Monthly backups: Keep the last
RETENTION_MONTHLYmonths (default: 6)
# Example retention timeline
Retention: Daily=7, Weekly=4, Monthly=6
# Backups retained:
Day 1-7: All daily backups
Week 1-4: One backup per week
Month 1-6: One backup per month
Older: DeletedChantik can back up and restore Docker and Podman volumes:
# In chantik.conf - Use Docker
DOCKER_VOLUMES=(
"postgres_data"
"redis_cache"
"nginx_conf"
)
CONTAINER_RUNTIME="docker"
# Or use Podman
PODMAN_VOLUMES=(
"postgres_data"
"redis_cache"
)
CONTAINER_RUNTIME="podman"
# Or let it auto-detect
CONTAINER_RUNTIME="auto"
# Each volume gets its own encrypted backup
volume_postgres_data_20260808_100000_full.tar.gz.enc
volume_redis_cache_20260808_100000_inc.tar.gz.encChantik will detect the available container runtime:
- If
CONTAINER_RUNTIMEis set todockerorpodman, use that - If
auto, check Podman first, then Docker - If no runtime is found, an error will appear
# Restore a volume (auto-detects runtime)
chantik restore postgres_data
# Restore multiple volumes at once
chantik restore postgres_data redis_cache
# Restore with dry-run
chantik restore --dry-run postgres_data
# Output:
[2026-08-08 10:30:00] π¦ Restoring type: volume_postgres_data
[2026-08-08 10:30:00] π Decrypting...
[2026-08-08 10:30:05] β
Checksum verification passed.
[2026-08-08 10:30:10] π¦ Restoring volume: postgres_data
[2026-08-08 10:30:15] β
Volume restore complete for postgres_data# Edit crontab
sudo crontab -e
# Daily backup at 2:00 AM
0 2 * * * /usr/local/bin/chantik backup >> /var/log/chantik-cron.log 2>&1
# Weekly full backup on Sunday at 3:00 AM
0 3 * * 0 /usr/local/bin/chantik backup >> /var/log/chantik-cron.log 2>&1
# Backup with verbose logging
0 2 * * * VERBOSE=true /usr/local/bin/chantik backup >> /var/log/chantik-cron.log 2>&1
# Backup with custom configuration
0 2 * * * CHANTIK_CONFIG=/etc/chantik/prod.conf /usr/local/bin/chantik backup| Schedule | Cron Expression | Description |
|---|---|---|
| Daily | 0 2 * * * |
Every day at 2:00 AM |
| Hourly | 0 * * * * |
Every hour |
| Weekly | 0 3 * * 0 |
Every Sunday at 3:00 AM |
| Monthly | 0 4 1 * * |
1st of every month at 4:00 AM |
# Specify a custom configuration
CHANTIK_CONFIG=/path/to/chantik.conf
# Specify the working directory
CHANTIK_WORK_DIR=/path/to/workdir
# Enable verbose
VERBOSE=true
# Use in cron
0 2 * * * CHANTIK_CONFIG=/etc/chantik/prod.conf VERBOSE=false /usr/local/bin/chantik backupChaCha20 not supported:
β οΈ WARNING: ChaCha20-Poly1305 not supported; falling back to AES-256-CBC.The script will automatically use AES-256-CBC as a fallback.
Insufficient disk space:
# Check available space
df -h /media/backup
# Reduce retention or increase storage
RETENTION_DAILY=3
RETENTION_WEEKLY=2Key file errors:
# If a previous backup was interrupted
rm -f /path/to/chantik/.chantik.lock
# Or remove the lock directory
rm -rf /path/to/chantik/.chantik.lock.dirContainer runtime not detected:
# Check Docker
docker info
# Check Podman
podman info
# Set the runtime explicitly in the config
CONTAINER_RUNTIME="docker" # or "podman"Enable verbose mode:
VERBOSE=true chantik backupCheck the log:
tail -f chantik.log
# or if the log is in a custom location
tail -f /path/to/chantik.logTest the encryption system:
chantik test| Scenario | GZIP_LEVEL | PBKDF2_ITERATIONS | INCREMENTAL_ENABLED |
|---|---|---|---|
| Daily backup | 6 | 600000 | true |
| Large files | 3 | 600000 | false |
| Maximum compression | 9 | 600000 | true |
| Speed priority | 1 | 100000 | false |
| Security priority | 6 | 1000000 | true |
Use deduplication with a fixed salt:
FIXED_SALT_FILE="/path/to/fixed_salt.txt"
DEDUP_TOOL="hardlink"Use incremental backups:
INCREMENTAL_ENABLED=true
FULL_BACKUP_INTERVAL=14More aggressive compression:
GZIP_LEVEL=9Chantik detects and uses the available runtime:
- Podman: Detected first (if available)
- Docker: Used as a fallback
- Manual: Set
CONTAINER_RUNTIMEexplicitly
Run the full test suite:
chantik testThe test suite verifies:
- ChaCha20 encryption/decryption (text and binary)
- AES-256-CBC fallback
- PBKDF2 compatibility
- Fixed nonce deduplication (if configured)
- Container runtime detection
chantik/
βββ chantik.sh # Main script
βββ chantik.conf # Configuration (create from example)
βββ chantik.conf.example # Example configuration
βββ encryption.key # Encryption key (generate your own)
βββ fixed_salt.txt # Fixed salt (optional)
βββ chantik.log # Log file
βββ .chantik.lock # Lock file (automatic)
βββ .chantik.lock.dir/ # Lock directory (automatic)
βββ .tmp/ # Temporary directory
βββ .incremental/ # Incremental snapshot data
βββ dir_digital-independence.snar
βββ vol_postgres_data.snar
βββ vol_redis_cache.snar
- ChaCha20-Poly1305 - Authenticated encryption
- OpenSSL - Cryptographic operations
- ntfy.sh - Notification service
- Docker & Podman - Container volume backups
- Alpine Linux - Lightweight container image
MIT License - See the LICENSE file for details.