Encrypted Server Backups to S3 with Duplicati
1 - How I Built My Own Server Using Local and Cloud Resources
2 - Deploying containers via Cloudflare Tunnel (Zero Trust)
3 - Reverse proxy on Oracle VPS with Traefik
4 - Encrypted Server Backups to S3 with Duplicati
This is the last part of the build-server series. After setting up a reverse proxy, it's important to keep your data safe. In this guide, we'll use Duplicati to back up your VPS (e.g Oracle VPS) to an S3-compatible service with encryption.
Duplicati is a lightweight and powerful backup tool with a user-friendly web interface. It supports encryption, scheduling, and remote destinations like S3, FTP, WebDAV, and others.
Requirements
Make sure you have the following before starting:
- A VPS with Docker and Docker Compose installed
- An S3-compatible storage provider (e.g., AWS S3, Backblaze B2, Wasabi, MinIO, etc.)
- S3 access credentials (Access Key and Secret Key)
- A domain if you're accessing Duplicati behind a reverse proxy (optional)
Step 1: Deploy Duplicati with Docker Compose
Here's the Docker Compose file I used.
services:
duplicati:
image: lscr.io/linuxserver/duplicati:latest
container_name: duplicati
environment:
- PUID=0 # use 0 instead 1000 because some of my files using root owner
- PGID=0
- TZ=Asia/Jakarta
- SETTINGS_ENCRYPTION_KEY=<YOUR_KEY_FOR_ENCRYPTION>
# an env from linuxserver so i can use docker command
- DOCKER_MODS=linuxserver/mods:universal-docker
volumes:
- <local-path-to-duplicati-dir>/config:/config
- <local-path-to-duplicati-dir>/backups:/backups
- <local-path-to-duplicati-dir>/scripts:/scripts
- <dir-to-backup>:/source
# because i need to run docker for my scripts, i need to bind the socket
- /var/run/docker.sock:/var/run/docker.sock:ro
# ports:
# - 8200:8200
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.duplicati.rule=Host(`duplicati.domain.com`)"
- "traefik.http.routers.duplicati.entrypoints=websecure"
- "traefik.http.routers.duplicati.tls=true"
- "traefik.http.services.duplicati.loadbalancer.server.port=8200"
networks:
- public-net
networks:
public-net:
external: true
Once your configuration is ready, deploy it with:
docker compose up -d
Open Duplicati in your browser at http://your-server-ip:8200
or via your reverse proxy domain if set up (https://duplicati.domain.com
).
Step 2: Create Pre and Post Backup Scripts
To ensure certain files can be backed up properly, I stop specific containers before the backup and start them again afterward.
<local-path-to-duplicati-dir>/scripts/stop-docker.sh
#!/bin/bash
docker stop your-container-name
<local-path-to-duplicati-dir>/scripts/start-docker.sh
#!/bin/bash
docker start your-container-name
Make both scripts executable:
chmod +x <local-path-to-duplicati-dir>/scripts/stop-docker.sh <local-path-to-duplicati-dir>/scripts/start-docker.sh
You can then configure Duplicati to run these scripts using the Advanced Options in the backup job:
--run-script-before=/scripts/stop-docker.sh
--run-script-after=/scripts/start-docker.sh
Step 2: Initial Setup
Step 1. Open Duplicati in your browser (default password: changeme
, then update it in Settings)

Step 2. Create a new backup (Add backup -> Configure a new backup)
Step 3. Fill in all the required fields.

Step 4. Set the Storage Type to S3 Compatible, then fill in the required fields and check the Use SSL checkbox

If you're using a custom URL, select Custom server URL and enter your S3 endpoint (e.g.,s3.domain.com
, withouthttp
/https
).
Even if you're using MinIO, keep Amazon AWS SDK as the client library.
Step 5. Click Test connection to verify your S3 configuration. Make sure the connection is successful.
Step 6. Add the Source path. Since we mounted <dir-to-backup>:/source
in the Docker Compose file earlier, your target directory will be under /computer/source
.

Step 7. Set your backup schedule.

Step 8. Configure other options as needed. Under Advanced options, refer to the example image below. You can add more advanced options by following the documentation.

Step 9. Click Save, and your backup is now ready.
Step 3: Start the Backup
Click "Run now" to perform your first backup.
Once it’s done, verify that your data is saved in your S3 storage.
Optional: Test Restore
To restore your data, simply configure your S3 credentials and bucket in Duplicati again (if you're using a different Duplicati instance for restore). Once connected, you can browse and select which version or files you want to restore
Final Thoughts
From spinning up an local server using SBC, securing it with Cloudflare Tunnel, reverse proxying with Traefik, to backing everything up to S3 with encryption — you’ve now got yourself a solid, self-hosted setup. No public IP? No problem.
The best part? Most of this was done using free tools and services — just some time, curiosity, and coffee ☕.
Hopefully this series made things easier and gave you the confidence to manage your own server stack like a pro. Whether you're hosting a personal project or just tinkering around, you’re in control now.
Until the next project — happy self-hosting!
Member discussion