Analytics cookies only (Google Analytics, PostHog). No ad networks, no cross-site tracking. See our privacy policy.
Self-host Duplicati
updated Oct 2026deployed by usprices checked · Jul 2026Install verified on Ubuntu 26.04 · Oct 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →
A backup client with a web UI that stores encrypted, incremental, compressed backups on cloud storage and remote servers: S3, Backblaze B2, OneDrive, Google Drive, WebDAV, SFTP, FTP and more. The open-source core is MIT-licensed C# on .NET (a few connectors under a proprietary/ directory need a paid subscription); it runs as a single container with its own SQLite databases in /data and backs up whatever host paths you mount into it.
Runs on a VPS from $6/mo (Kamatera 2GB, 2 GB RAM) · prices checked Sep 2026
Our recommendation
Pick Duplicati when you want a backup tool you drive from a browser rather than a shell: pick folders, pick a destination (S3, Backblaze B2, OneDrive, Google Drive, WebDAV, SFTP, FTP and more), set a schedule and retention, and let it ship encrypted, incremental, compressed blocks. The core is MIT-licensed C# on .NET with SQLite for its local databases; a `proprietary/` directory (disk-image, Office 365 and Google Workspace connectors, and the licence checker) is under a separate subscription licence, so the image is open-core rather than fully open source. Our snippet is the Docker Hub README's single container with the two secrets its security notes recommend, generated into `.env`: `SETTINGS_ENCRYPTION_KEY` with database encryption turned back on, and a fixed `DUPLICATI__WEBSERVICE_PASSWORD`. Upstream publishes no RAM minimum, so our 512 MB floor is an estimate. The catalog's Kopia and restic are command-line engines you script and schedule yourself; Duplicati is the one with a scheduler, a retention policy editor and a restore browser built in.
What you need
Any VPS with at least 512 MB of RAM
A domain you control — most self-hosted setups need HTTPS in front of them
The Docker Hub README and the "Using Duplicati from Docker" page flag these before you expose it:
non-negotiableFirst boot generates a random UI password you cannot know; the README's fix is either DUPLICATI__WEBSERVICE_PASSWORD (which our snippet sets from .env) or the one-time sign-in link printed in the container logs. The image ships with DUPLICATI__DISABLE_DB_ENCRYPTION=true so a moved container does not lose a key derived from the machine serial; we set it back to false with a generated SETTINGS_ENCRYPTION_KEY, which encrypts stored credentials and is not the UI password. Lose that key and the server database is unreadable.
non-negotiableEverything Duplicati knows (job definitions, local block databases, the settings database) lives in /data, so back up the duplicati_data volume as well as your destinations. Since a recent release the server refuses a data folder whose permissions are not exactly what it expects; a Docker named volume passes, and a bind mount that cannot be locked down needs DUPLICATI__ALLOW_INSECURE_DATAFOLDER=true per the docs. Upgrading is a tag bump plus docker compose up -d; the docs keep per-major downgrade guides because databases are migrated forward.
non-negotiableUpstream's examples run duplicati/duplicati:latest and also publish beta, canary and experimental channel tags; we pin a stable version tag, which exists in both x.y.z.w and x.y.z.w-stable spellings. The container can only back up what is mounted into it: the README's convention is -v /host/path:/container/path, and our compose exposes the host's /home as /backup/home, so add a volume line per extra tree you want to protect. Any --option from the CLI can be set as an environment variable by prefixing DUPLICATI__ and swapping - for _.
non-negotiablePort 8200 is plain HTTP; the docs' reverse-proxy example terminates in nginx, and if you then reach the UI by hostname rather than IP you must list it in DUPLICATI__WEBSERVICE_ALLOWED_HOSTNAMES (* disables the check and is discouraged). The image listens on all interfaces (DUPLICATI__WEBSERVICE_INTERFACE=any) and authentication cannot be switched off; a pre-authenticated proxy header via DUPLICATI__WEBSERVICE_PRE_AUTH_TOKENS is the documented alternative to a second password.