Seafile Docker: Use external hard drive

Basically I tried exactly this so I can use my NAS hdd instead of the VMs SSD for the actual data:

How to move seafile-data folder to my hard drive when using docker

Here is my docker-compose file:

image: mariadb:10.11
container_name: seafile-mysql
  - MYSQL_ROOT_PASSWORD=REDACTED  # Requested, set the root's password of MySQL service.
  - /root/docker-compose-files/seafile/mysql:/var/lib/mysql  # Requested, specifies the path to MySQL data persistent store.
  - seafile-net

image: memcached:1.6.18
container_name: seafile-memcached
entrypoint: memcached -m 256
  - seafile-net
image: seafileltd/seafile-mc:latest
container_name: seafile
  - "8012:80"
#      - "443:443"  # If https is enabled, cancel the comment.
  - /root/docker-compose-files/seafile/config:/shared
  - /mnt/nas/docker/seafile:/shared/seafile/seafile-data

  - DB_HOST=db
  - DB_ROOT_PASSWD=REDACTED  # Requested, the value should be root's password of MySQL service.
  - TIME_ZONE=Europe/Berlin  # Optional, default is UTC. Should be uncomment and set to your local time zone.
  - SEAFILE_ADMIN_EMAIL=admin@REDACTED # Specifies Seafile admin user, default is ''.
  - SEAFILE_ADMIN_PASSWORD=REDACTED     # Specifies Seafile admin password, default is 'asecret'.
  - SEAFILE_SERVER_LETSENCRYPT=false   # Whether to use https or not.
  - SEAFILE_SERVER_HOSTNAME=seafile.nas.REDACTED # Specifies your host name if https is enabled.
  - db
  - memcached
  - seafile-net


but I only get:

root@hdocker:~/docker-compose-files/seafile# docker logs seafile
*** Running /etc/my_init.d/
*** Booting runit daemon...
*** Runit started as PID 17
*** Running /scripts/
2023-12-22 17:06:32 Waiting Nginx 
2023-12-22 17:06:32 Nginx ready 
2023-12-22 17:06:32 This is an idle script (infinite loop) to keep container running. 
[2023-12-22 17:06:39] Skip running because there is existing seafile-data folder.
waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
[12/22/2023 17:06:39][upgrade]: The container was recreated, start fix the media symlinks
mv: target '/shared/seafile/seahub-data/avatars' is not a directory
Traceback (most recent call last):
  File "/scripts/", line 95, in <module>
  File "/scripts/", line 61, in main
  File "/scripts/", line 95, in check_upgrade
  File "/scripts/", line 79, in fix_media_symlinks
    call('mv -n %s/* %s' % (avatars_dir, dst_avatars_dir))
  File "/scripts/", line 70, in call
    return subprocess.check_call(*a, **kw)
  File "/usr/lib/python3.10/", line 369, in check_call
    raise CalledProcessError(retcode, cmd)
**subprocess.CalledProcessError: Command 'mv -n /opt/seafile/seafile-server-11.0.3/seahub/media/avatars/* /shared/seafile/seahub-data/avatars' returned non-zero exit status 1.**

I tried creating an “avatars” directory: mkdir -p /root/docker-compose-files/seafile/config/seafile/seahub-data/avatars

but it still doesn’t work…

What did I do wrong?
Would also gladly accept any other solution on how to use my mounted HDD for the seafile-data and keep the rest on the hosts SSD (I can’t be the only one who wants something like this?)

Here to say that I am also experiencing this problem. I am doing a brand new install. Hopefully someone can chime in :crossed_fingers:

Official compose file states this for volumes:

      - /opt/seafile-data:/shared   # Requested, specifies the path to Seafile data persistent store.

Basically, it means everything (seafile-data, seahub-data, conf, logs and nginx stuff) will be mounted from /opt/seafile-data or, in your case, from your NAS (by adjusting the path).

This is the easy way and the one I would recommend. However, if I understand correctly, you’re trying to split the volume in something like this:

  • seafile-data mounted from your NAS
  • Everything else mounted from some directory on the SSD

This is a little trickier and requires a two-step initialization, I’ve written some tips about it here

After your advice in the referenced thread, and some fiddling, I was able to successfully separate the folders by doing this:

  - /mnt/docker-data/seafile/conf/:/shared/seafile/conf # ssd
  - /mnt/docker-data/seafile/ccnet/:/shared/seafile/ccnet # ssd
  - /mnt/docker-data/seafile/logs/:/shared/logs # ssd
  - /mnt/seafile/seafile-data:/shared/seafile/seafile-data # hdd
  - /mnt/seafile/seahub-data:/shared/seafile/seahub-data # hdd

The problem I am having described in this thread, happens when I try a new install using the auto-configuration of nginx and let’s encrypt. Maybe I will try it now with everything on one drive.

That’s why you need to do it in two steps.

Seafile’s scripts use the seafile-data folder to know if the server should be initialized or just launched.

But adding a volume directly mapped to /shared/seafile/seafile-data in the container will create this directory in the container.

Then seafile will think it has already been initialized (which is wrong), skips initialization and you end up with everything broken.


[2023-12-22 17:06:39] Skip running because there is existing seafile-data folder.