How to move only files but not calendar and contacts to new location?

Hi all,

I am using OwnCloud 10.15.3 (stable) on a Raspi 5 in a docker environment. I use the apps “Files”, “Calendar” and “Contacts”. Attached to the Raspi there is a USB HDD which is supposed to store the files the users sync via OwnCloud. The Calendars and Contacts shall reside on the SD-card the Raspi boots from.

The background for this is that I want to have a simple backup concept: I copy an image of the SD-Card via cron-job to a backup location. For the files sync’d via OwnCloud there is a dedicated backup job. Since there are some other things on the SD-Card, the SD-Card image does not only backup owncloud but also those other things in one go.

After having set-up OwnCloud in Docker everything is stored in the SD-Card: Contacts, Calendar and also the files.

I found that the command

docker exec -it <hash-value> occ user:move-home <user name> <new location>

moves the user’s directory to a new location. I can also move it to the USB-HDD.

Unfortunately this move apparently encompasses calendar and contacts as well. I deduced that the following way: I created a few sample appointments in the calendar. Next I created an image of the SD-Card. After that I deleted one of the sample appointments and added new ones. Finally, I restored the SD-Card from the backup. I see that all changes I did after I took the backup are still there: The deleted appointments are still deleted and the newly created appointments are still there. If the Calendar data was stored on the SD-Card it would have been restored to the backup state, undoing the changes I did after the backup was created.

Now the question is: How can I move only the file storage from the SD-Card to the USB-HDD?

Thanks in advance and best regards
– Solderdot

Thanks for the detailed explanation this setup makes a lot of sense for simplifying your backup process. In OwnCloud, unfortunately, the user:move-home command moves the entire user data directory, which includes not only the synced files but also app data like calendars and contacts. This is why you observed the calendar entries persisting despite restoring your SD card image the data is being stored along with the user’s home folder that was moved to the USB HDD.

To achieve your goal of separating file storage from calendar and contacts, you would need a more granular control of data paths, which OwnCloud doesn’t natively support out of the box. However, one potential workaround would involve mounting external storage (like your USB HDD) specifically for the files directory inside each user’s data folder, using symbolic links or bind mounts, while keeping the rest of the app data on the SD card.

More technical guidance and best practices around storage configuration are covered in the official OwnCloud Admin Documentation which might help you refine this setup.

If you’re interested in similar cloud storage and remote data access setups, feel free to visit the main OwnCloud Community Forum where advanced use cases like yours are regularly discussed.

That’s a really thoughtful setup makes total sense wanting to separate files from calendar and contacts for cleaner backups. I’ve run into similar issues with OwnCloud in Docker, and it can be tricky. Curious if mounting just the data/ directory to the USB HDD while keeping app and config data on the SD card could help? Would love to hear how you end up solving it.

Hi @kearawill ,

thanks for the suggestion. Apparently this does not work. My attempt of creating such a files folder for a single user resulted in all the containers of the stack being displayed as running in Portainer, but the web service is not reachable.

The log displays this:

Next Doctrine\DBAL\Driver\PDO\Exception: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'owncloud.oc_appconfig' doesn't exist in /var/www/owncloud/lib/composer/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php:18      
Stack trace:
#0 /var/www/owncloud/lib/composer/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php(143): Doctrine\DBAL\Driver\PDO\Exception::new()
#1 /var/www/owncloud/lib/composer/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php(38): Doctrine\DBAL\Driver\PDOConnection->doQuery()
#2 /var/www/owncloud/lib/composer/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(1309): Doctrine\DBAL\Driver\PDOConnection->query()
#3 /var/www/owncloud/lib/private/DB/Connection.php(191): Doctrine\DBAL\Connection->executeQuery()
#4 /var/www/owncloud/lib/composer/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php(212): OC\DB\Connection->executeQuery()
#5 /var/www/owncloud/lib/private/DB/QueryBuilder/QueryBuilder.php(141): Doctrine\DBAL\Query\QueryBuilder->execute()
#6 /var/www/owncloud/lib/private/AppConfig.php(312): OC\DB\QueryBuilder\QueryBuilder->execute()
#7 /var/www/owncloud/lib/private/AppConfig.php(80): OC\AppConfig->loadConfigValues()
#8 /var/www/owncloud/lib/private/AppConfig.php(289): OC\AppConfig->getApps()
#9 /var/www/owncloud/lib/private/App/AppManager.php(138): OC\AppConfig->getValues()
#10 /var/www/owncloud/lib/private/App/AppManager.php(159): OC\App\AppManager->getInstalledAppsValues()
#11 /var/www/owncloud/lib/private/legacy/app.php(352): OC\App\AppManager->getInstalledApps()
#12 /var/www/owncloud/lib/private/legacy/app.php(108): OC_App::getEnabledApps()
#13 /var/www/owncloud/lib/kernel.php(596): OC_App::loadApps()
#14 /var/www/owncloud/lib/kernel.php(1076): OC::init()
#15 /var/www/owncloud/lib/base.php(27): require_once('/var/www/ownclo...')
#16 /var/www/owncloud/console.php(52): require_once('/var/www/ownclo...')
#17 /var/www/owncloud/occ(11): require_once('/var/www/ownclo...')
#18 {main}

Unfortunately I cannot read too much from those logs…

In case it is of interest, here is the docker configuration:

services:
  owncloud:
    image: owncloud/server:${OWNCLOUD_VERSION}
    container_name: owncloud_server
    restart: always
    ports:
      - ${HTTP_PORT}:8080
    depends_on:
      - mariadb
      - redis
    environment:
      - OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
      - OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloud
      - OWNCLOUD_DB_USERNAME=owncloud
      - OWNCLOUD_DB_PASSWORD=owncloud
      - OWNCLOUD_DB_HOST=mariadb
      - OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
      - OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - OWNCLOUD_MYSQL_UTF8MB4=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - ${OWNCLOUD_FILES_LOCATION}:/mnt/data
      - ${OWNCLOUD_USER_MIRI_FILES_LOCATION}:/mnt/data/files/Miri


  mariadb:
    image: mariadb:10.11 # minimum required ownCloud version is 10.9
    container_name: owncloud_mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=owncloud
      - MYSQL_USER=owncloud
      - MYSQL_PASSWORD=owncloud
      - MYSQL_DATABASE=owncloud
      - MARIADB_AUTO_UPGRADE=1
    command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - ./mysql:/var/lib/mysql

  redis:
    image: redis:6
    container_name: owncloud_redis
    restart: always
    command: ["--databases", "1"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - ./redis:/data

And the environment looks like this:

OWNCLOUD_VERSION=10.15
OWNCLOUD_DOMAIN=192.168.2.123:8080
OWNCLOUD_TRUSTED_DOMAINS=192.168.2.123
ADMIN_USERNAME=admin
ADMIN_PASSWORD=<password>
HTTP_PORT=8080
OWNCLOUD_FILES_LOCATION=/data/DockerVolumes/OwnCloud
OWNCLOUD_USER_MIRI_FILES_LOCATION=/mnt/nas_drv/OwnCloud/Files/Miri

As you can see, I’d like to handle the files directory of the to-be-created user “Miri” in this way.

Any suggestions? Or is it just the case that this is simply not feasible…?

Hi @kearawill,
my above statement is wrong. I missed deleting all data from the previous installation, in particular the stuff in OWNCLOUD_FILES_LOCATION. After emptying this folder, removing the stack and deploying it anew, the Owncloud server came up correctly. I was able to create the user “Miri” and a folder created in the web interface showed up in OWNCLOUD_USER_MIRI_FILES_LOCATION. So on 1sst glance it appears to be the case that this actually works.
Splendid!
Thanks for your suggestion.
Further testing is required, but for the time being it appears to be the case that this is the way to go for me. And maybe as well for you, @Ethanjohn ?