Why this backup strategy?
Traditional backup methods often fall short in cloud-native environments: they may lack encryption, require manual intervention, or fail to integrate cleanly with immutable infrastructure. An S3-based backup solution using Duplicity and GPG encryption addresses these gaps through the following design choices:End-to-end encryption:
All backups are encrypted at rest using GPG before leaving the application container. Even if S3 credentials are compromised, data remains protected by a strong passphrase and private key. Private keys and passphrases should never be stored in plaintext on the platform.Efficient incremental backups
Duplicity uses incremental syncing, meaning only changed files are uploaded after the initial full backup. This reduces bandwidth, storage costs, and backup windows. Critical for large Drupal sites with frequent file uploads.Cloud-native and portable
By using AWS S3 (a durable, versionable, and globally available object store) and boto3 (the official AWS SDK), avoid vendor lock-in while leveraging battle-tested infrastructure. The same backup can be restored anywhere, like Upsun, local dev, or another cloud.Declarative and reproducible
Thanks to Upsun’s composable Nix stack, every dependency (Duplicity, GnuPG, Python packages) is versioned and immutable. There’s no “works on my machine” problem. Your backup environment is identical across all deployments.Fully automated
With cron-driven execution and deploy-time key setup, backups run without human intervention. Combined with environment-based toggles (S3_BACKUP=On), it’s easy to enable/disable per environment (on for prod, off for dev).How to set up:
1. Configure the composable stack
Upsun’s composable images (based on Nix) let you declaratively define your runtime environment. To support encrypted S3 backups, add the required packages to yourWhy these packages?
- Duplicity: Handles incremental, encrypted backups.
- gnupg: Manages GPG key operations.
- boto3: Enables Duplicity to communicate with AWS S3.
- python3 & numpy: Runtime dependencies for Duplicity and boto3.
2. Generate GPG keys locally
Backups are encrypted using GPG. Generate a dedicated key pair on your local machine:- Choose RSA and RSA (default)
- Set key size to 4096 bits.
- Set a strong passphrase (you’ll store this securely)
- Use a descriptive name/email (devops+upsun-backup@example.com)
Export the keys in ASCII-armored format:
3. Set environment variables
Upsun has a 4096-byte limit on environment variable values. Since GPG private keys often exceed this, split the private key into two parts:The Settings > Variables section in UI allows you to paste or edit long multi-line values directly without worrying about formatting issues or line breaks.
4. Create an S3 bucket
Create a dedicated S3 bucket in your preferred region (us-east-2):5. Automate backups with a cron job
Add a cron task to .upsun/config.yaml to run incremental backups every 30 minutes:You can adjust the schedule to match your preference.
| Cron Expression | Meaning |
|---|---|
| ***/30 * * * *** | Every 30 minutes |
| **0 2 * * *** | Daily at 2 AM (for full) |
| 0 1 * * 0 | Weekly at 1 AM on Sunday |
What’s backed up?
By default, the entire /app directory (containing the application codebase and files) is backed up incrementally. Additional directories can be included as needed.6. Import GPG keys on deploy
During deployment, import your GPG keys into a temporary keyring:7. Test Your first backup
After deployment, trigger a manual full backup to verify the setup:8. Restoring from backup
Need to restore? Since Upsun is a read-only environment, use a local or a Cloud Server to restore backups.- Spin up a recovery environment on a cloud server or on a local server.
- Re-import GPG keys
- Use duplicity restore with your S3 URL and passphrase
- Sync files back to Upsun