Question - Best Practice for Persistence with Docker Volumes

I did search the forums on this, as well as read several posts in the “Your topic is similar to…” section. I didn’t come up with an answer to this.

The title is a bit of a mouthfull, so I’ll put the TLDR up front:

TLDR: If I want all Nextcloud customizations (data, apps, themes, etc.) to be persistent, but also want as little Nextcloud code to be persistent (for upgrades), then which folders should I mount and how? What is the best practice for mounting volumes with Nextcloud on containers?

This may seem like a “well duh…” kind of question. However, I ran across a post on these forums that made me re-think this, and now I thought I’d specifically ask this question.

Here’s the longer version. I started my Nextcloud on Docker journey at the Docker Hub website. It contains good information on Docker volumes for Nextcloud:

Overview of the folders that can be mounted as volumes:

* /var/www/html Main folder, needed for updating
* /var/www/html/custom_apps installed / modified apps
* /var/www/html/config local configuration
* /var/www/html/data the actual data of your Nextcloud
* /var/www/html/themes/<YOU_CUSTOM_THEME> theming/branding

If you want to use named volumes for all of these it would look like this

$ docker run -d \
    -v nextcloud:/var/www/html \
    -v apps:/var/www/html/custom_apps \
    -v config:/var/www/html/config \
    -v data:/var/www/html/data \
    -v theme:/var/www/html/themes/<YOUR_CUSTOM_THEME> \
    nextcloud

So that’s how I started my Nextcloud on containers journey. I created separate mounts for the DB and each Nextcloud folder that contained a customization.

$ docker run -d \
    -v db:/var/lib/mysql \
    -v data:/var/www/html/data \
    -v nextcloud:/var/www/html \
    -v custom_apps:/var/www/html/custom_apps \
    -v config:/var/www/html/config \
    -v themes:/var/www/html/themes \
    nextcloud

I got everything working, and all was well. However, that post I referenced (I wish I could find it) asked a simple question back to another user: “If everything in Nextcloud is mounted from a subdirectory off ‘/var/www/html’, then why would you add complexity by separately mounting the subdirectories? Why not just create a single mount for ‘/var/www/html’ and be done?”

$ docker run -d \
    -v db:/var/lib/mysql \
    -v data:/var/www/html/data \
    -v nextcloud:/var/www/html \
    nextcloud

I thought it was a valid point, and changed my own config. Now I’m mounting the DB, one Nextcloud “web” folder and one Nextcloud “data” folder. Cool, everything still works. But my understanding of the way Docker mounts work is, any Docker container that starts with a mount that is empty, the files inside the docker container will be copied to populate the mount.

My understanding is also that if a file (or files) of the same name already exists in this Docker mount, the file (or files) will not be copied, even if the files in the Docker container are newer. I don’t know this part for sure, and I’m finding it difficult to test. It’s just that’s my understanding.

Now that a new stable major version of Nextcloud is on the horizon (v17.0.2), I’m wondering if creating a single mount for ‘/var/www/html’ was the right approach? When I go to upgrade to the next stable version, I believe this will play out:

  1. I’ll pull the newest Nextcloud image that has all the v17.0.2 files.
  2. I’ll stop the existing Nextcloud container (based on the v16.0.6 image).
  3. I’ll start the new Nextcloud container (based on the v17.0.2 image).
  4. That new container will, during its startup sequence, determine that all the Nextcloud files already exist in the Docker mount (which are v16.0.6)
  5. That container will do nothing with regards to updating files in the Docker mount, and keep running the old version of Nextcloud.

Right?

At this point, I guess I could use the web updater for Nextcloud, to re-download the files that already exist in the container I’m running and perform the upgrade that way, but is this the most efficient way? If I want to keep all Nextcloud customizations persistent but keep as much Nextcloud code in the container, is this the best practice?

I have very little data in Nextcloud, so reinstalling Nextcloud and going back to the old way isn’t a big issue for me. But then that raises questions on the flip side of the coin. Let’s assume that I create separate mounts for everything custom in Nextcloud but no mount at all for the Nextcloud web files (’/var/www/html’).

$ docker run -d \
    -v db:/var/lib/mysql \
    -v data:/var/www/html/data \
    -v custom_apps:/var/www/html/custom_apps \
    -v config:/var/www/html/config \
    -v themes:/var/www/html/themes \
    nextcloud

In this config, I assume a slightly different series of steps will play out:

  1. I’ll pull the newest Nextcloud image that has all the v17.0.2 files.
  2. I’ll stop the existing Nextcloud container (based on the v16.0.6 image).
  3. I’ll start the new Nextcloud container (based on the v17.0.2 image).
  4. That new container will, during its startup sequence, not touch the DB (with Nextcloud v16.0.6 schema), not touch any of the subdirectories with Nextcloud customizations (which were functional on Nextcloud v16.0.6), but will start running Nextcloud web files for v17.0.2.
  5. That new container will start with a hybrid of two versions of Nextcloud information, DB & customizations (v16.0.6) / web files (v17.0.2).

Will this accelerate the update process for Nextcloud or will this create any new issues when upgrading? I’m assuming there will still be steps to complete the upgrade, but is this approach better or worse than the previous approach?

Nextcloud offers great information about what ‘can’ be mounted separately, and I do definitely appreciate that. However my question to the support forum is more how ‘should’ I be mounting Nextcloud directories to achieve my goal of: keep all Nextcloud customzations persistent but keep as much Nextcloud code in the container?

Thank you for any input in advance.

1 Like

no.

the entrypoint skript will check the installed version (aka the version in your volume) versus a version in /usr/src/nextcloud/ in the image. and perform an update on first startup. or deny to start because it would lead to a downgrade.

that’s the way nextcloud handles updates.

no. that would interfere with the update skript and is not possible.

don’t worry. it doesn’t matter. the nextcloud example file use the “simple” approach today. so you may assume that this is best practice.

https://github.com/nextcloud/docker/blob/f2489f014216122820d159c1c31081a069461c32/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml#L19

btw: you may have a look at watchtower (older) or ouroboros (newer) to have your container updated automatic or manual but without the docker stop & docker rm & docker run hustle and bustle.

2 Likes