Some basics about running duplicacy in a docker container

I’m starting to appreciate docker on my home server. Running various apps and services in a container allows me to keep my operating system (Debian/OpenMediaVault) as clean as possible without having to run lots of virtual machines.

@saspus is providing a docker image for duplicacy (here: Bitbucket) so I take it that it makes sense to dockerize even duplicacy, but I’m not sure I fully understand

a) why/under what circumstances this makes sense
b) how it works.

Ad a), here is what I found so far:

I do run docker as root and my machine is (for the time being) not exposed to the internet.

Hm, not sure how this is an advantage as it also means: I have to make sure everything I want to backup is indeed mounted. I think I prefer to rely on duplicacy’s filter file (as well as . nobackup files and, if need be, symlinks) for managing what is or is not backed up. Why introduce a second selection layer?

I totally see the advantage here but it applies exactly once (upon first setup) and I have learned that this is also easily solved with a tunnel.

So is there anything else to say about dockerizing duplicacy?

Ad b), what I’m mainly wondering is: how does duplicacy get access to the files it should back up? I realize that the answer might already be up there in this very post: you have to mount everything. But if this is correct, then I’d anticipate all kinds of access problems which I probably wouldn’t have when running duplicacy as root on the server directly?

I’d also anticipate confusions around repository paths as these will we relative to the container, not the host. Not unsolvable, of course, but adding friction.

Please let me know if I’m missing any important points (I’m pretty sure I am).

it’s great for running on limited functionality linux systems/appliances, like unRAID in my case, where you can’t just install a deb or rpm.

i get the app and the webui in one package and I can inject mounts into the container as i see fit:

  • my server’s root filesystem as read only
  • a very specific path (dedicated to duplicacy) where i want the local backup to land as RW
  • config/logs to a raid protected ssd pool
  • cache to a ‘scratch’ ssd that isn’t protected/backed up

and because i separately backup the configuration of this container, it’s easily reproduced if i lose my docker.img


Think of docker as chroot + networking. It provides entirely separate user mode environment but relies on host systems kernel.

In contrast virtual machine runs both kernel and userspace (via hypervisor that can either run on the host OS or sit under it).

Docker is useful to isolate dependencies and convert a complex app consisting from multiple interacting services and libraries into one single disposable monolithic entity that operates on some data mapped out to the host system. Instead of updating apps in the container one is expected to replace the whole container; since containers are isolated and immutable their behavior is reliable and predictable.

For Duplicacy therefore containerization does not make much sense as it is written in go and hence is already single monolithic executable with no dependencies. Wrapping it into container does not add value in that regard — as there are no dependencies to isolate to begin with.

Some systems (Synology, unraid, etc) provide docker UI and docker hub can be viewed as a sort of software distribution channel so this side of docker infrastructure may be useful to simplify Duplicacy installation. I suspect that’s the reason for the majority of people to use it.

Even though I wrote that container to run Duplicacy on synology I don’t use it myself anymore:

But since it’s has now got 500k pulls I fee obligated to keep supporting it…


thank you for continuing!

that said, now i feel a bit weary about dropping 4x5yr licenses when my trial period expires as i don’t have much option if the container disappears

Haha. Don’t worry about that, I’ll be supporting it while I’m around, it does not really take much work. I stopped using it about year and half ago, and yet I did update it couple of times during that period FWIW.

Actually, you are likely using :latest tag there, which has specific version of duplicacy_web baked into the container, so when @gchen releases new version I need to update the version string, have the container rebuilt and users need to download a new image and update their instance.

There is now another tag: :mini: it does not have anything backed in. It’s an extremely lightweight shell. To update to the new duplicacy you don’t need to download new image – you just update the version string in the environment variable and restart the container. It will download new duplicacy_web (just as duplicacy_web downloads new Duplicacy CLI on start; same behavior).

This contradicts a bit docker ideology – that containers are immutable – but duplicacy_web already does it with cli so the immutability has already been thrown out of the window; all I did was extend the same behavior to duplicacy_web itself.

This however aligns better with my understanding of the intended use form previous comment – as installation facilitator – and in that regards thin shell is preferable.

With :mini you don’t really need to ever update the container itself as nothing would change there (aside of drastic changes in docker itself – but then I’d assume docker hub would rebuild existing containers anyway; or some crazy bug in the container script – but they are rather simple so I don’t anticipate much)

Eventually the :mini branch will become :latest in a few months anyway (when I’m absolutely sure it is working reliably)


Doh, missed this question due to infinitesimal attention span…

You are correct, that duplicacy can only see what’s visible from the container so you would map stuff into the container from outside. In fact, you can map multiple things into a single share effectively replicating duplicacy’s existing functional of collecting a bunch of folders all over the system under singe virtual “repo”.


docker run ... \
 --volume /host/path1/:/backuproot/path1:ro  \
 --volume /host/totally/differnet/path2/:/backuproot/path2:ro \

and then pointing duplicacy to create repo in the folder /backuproot which would have path1 and path2 subfolders.

Access problems are solved on the host: you would create a user “Duplicacy” on the host system and give it access to read stuff it needs to backup. Then you would run the container on behalf of that user. Or in case of my container, you can specify UID and GUID under which to run the duplicacy – so you can run your docker container under root but duplicacy_web will be run under specified user.

The path names – nothing prevents you to map them in the same place in the container as they are on the host if you wanted to:

docker run ... \
 --volume /some/crazy/path/of/sentimental/value/1:/some/crazy/path/of/sentimental/value/1:ro  \
 --volume /anthother/fine/path:/anthother/fine/path:ro \

Then duplicacy instance in the container will see the same paths. I however to map everything to under single mappable share but that’s matter of taste.

1 Like

switched to the :mini version to upgrade to 1.4.0, thanks for the heads up.

(I’m in the woods camping with family, will update the :latest to 1.4.0 by the end of the week)

If :mini does not work for your or misbehaves in any way I’d like to know (if you have a minute) :slight_smile:

works totally fine, just switched the tag and added the version variable and it booted with my existing config.