Moving the data directory fails

Hi there,

I am just starting out with seafile, but ran into an issue I cannot find a fix for. Maybe you can point me in the right direction?

Basically, I want to take the docker installation of seafile and have my data sitting in a different directory. From what I gathered by reading the documentation and forum, I need to use symbolic links for the seafile-data directory. Unfortunately this does not work. I also tried volume mapping with docker but this did not work either.

Here is my approach:

docker-compose.yaml:

services:
  db:
    image: mariadb:10.11
    container_name: seafile-mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}  # Required, set the root's password of MySQL service.
      - MYSQL_LOG_CONSOLE=true
      - MARIADB_AUTO_UPGRADE=1
    volumes:
      - ${DOCKERDIR}/mariadb-data:/var/lib/mysql  # Required, specifies the path to MySQL data persistent store.
    networks:
      - seafile-net

  memcached:
    image: memcached:1.6.18
    container_name: seafile-memcached
    entrypoint: memcached -m 256
    networks:
      - seafile-net
          
  seafile:
    image: seafileltd/seafile-mc:11.0-latest
    container_name: seafile
    ports:
      - "3333:80"
#     - "443:443"  # If https is enabled, cancel the comment.
    volumes:
      - ${DOCKERDIR}/sf-data:/shared   # Required, specifies the path to Seafile data persistent store.
    environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=${MYSQL_ROOT_PASSWORD}  # Required, the value should be root's password of MySQL service.
      - TIME_ZONE=${TZ}  # Optional, default is UTC. Should be uncomment and set to your local time zone.
      - SEAFILE_ADMIN_EMAIL=${SEAFILE_ADMIN_EMAIL} # Specifies Seafile admin user, default is 'me@example.com'.
      - SEAFILE_ADMIN_PASSWORD=${SEAFILE_ADMIN_PASSWORD}     # Specifies Seafile admin password, default is 'asecret'.
      - SEAFILE_SERVER_LETSENCRYPT=false   # Whether to use https or not.
      # - SEAFILE_SERVER_HOSTNAME=${SEAFILE_SERVER_HOSTNAME} # Specifies your host name if https is enabled.
      # - NON_ROOT=true
    depends_on:
      - db
      - memcached
    networks:
      - seafile-net

networks:
  seafile-net:

I am using an .env file for the sensitive information:

DOCKERDIR=/home/myuser/sf-community

TZ=Europe/Berlin

MYSQL_ROOT_PASSWORD=somepw

SEAFILE_ADMIN_EMAIL=someuser@mail.com
SEAFILE_ADMIN_PASSWORD=anotherpw
SEAFILE_SERVER_HOSTNAME=machine-hostname

I then create the container with docker compose up. This works so far. Now I move the newly created seafile-data folder and replace its original location with a symlink. This is where it fails:

docker compose down
sudo mv sf-data/seafile/seafile-data .
sudo ln -s $PWD/seafile-data ./sf-data/seafile/seafile-data
docker compose up

What am I doing wrong? Is this not supported and I can only move the complete /opt/seafile-data folder (sf-data in my case)?

Symlinks with Docker can be a bit weird and afaik they aren’t really respected outside of the build context, have you tried moving (renaming) the directory and mounting it without the symlink?

Thanks @Jukelyn. I also tried to use Docker to mount the data directory at a different location and I got it somewhat working:

When I start a fresh installation with the following volume mapping, I get an error that seafile-data already exists and the process fails.

volumes:
      - ${DOCKERDIR}/sf-data:/shared
      - ${DOCKERDIR}/seafile-data:/shared/seafile/seafile-data

The error is

seafile-mysql      | 2024-11-27  7:33:06 0 [Note] mariadbd: ready for connections.
seafile-mysql      | Version: '10.11.10-MariaDB-ubu2204'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
seafile            | [2024-11-27 08:33:06] Skip running setup-seafile-mysql.py because there is existing seafile-data folder.
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | waiting for mysql server to be ready: %s (2003, "Can't connect to MySQL server on 'db' ([Errno 111] Connection refused)")
seafile            | [11/27/2024 08:33:06][upgrade]: The container was recreated, start fix the media symlinks
seafile            | mv: target '/shared/seafile/seahub-data/avatars' is not a directory
seafile            | Traceback (most recent call last):
seafile            |   File "/scripts/start.py", line 94, in <module>
seafile            |     main()
seafile            |   File "/scripts/start.py", line 61, in main
seafile            |     check_upgrade()
seafile            |   File "/scripts/upgrade.py", line 120, in check_upgrade
seafile            |     fix_media_symlinks()
seafile            |   File "/scripts/upgrade.py", line 104, in fix_media_symlinks
seafile            |     call('mv -n %s/* %s' % (avatars_dir, dst_avatars_dir))
seafile            |   File "/scripts/utils.py", line 70, in call
seafile            |     return subprocess.check_call(*a, **kw)
seafile            |   File "/usr/lib/python3.10/subprocess.py", line 369, in check_call
seafile            |     raise CalledProcessError(retcode, cmd)
seafile            | subprocess.CalledProcessError: Command 'mv -n /opt/seafile/seafile-server-11.0.13/seahub/media/avatars/* /shared/seafile/seahub-data/avatars' returned non-zero exit status 1.

I got around this issue by first only mounting the /shared directory:

volumes:
      - ${DOCKERDIR}/sf-data:/shared 

Once the initial setup completed, I stopped the container and moved /sf-data/seafile/seafile-data to a new location and then mounted both volumes:

mv sf-data/seafile/seafile-data .
volumes:
      - ${DOCKERDIR}/sf-data:/shared
      - ${DOCKERDIR}/seafile-data:/shared/seafile/seafile-data

So far, so good. When I now switch to non-root containers, the seafile service does not come up and does not produce any kind of error in the logs:

Stopping the containers, switching the non-root setting on:

- NON_ROOT=true

Changing folder permissions:

sudo chmod -R a+rwx sf-data/seafile/
sudo chmod -R a+rwx seafile-data/

Last log entries (no error visible):

seafile            | *** Running /etc/my_init.d/01_create_data_links.sh...
seafile            | *** Booting runit daemon...
seafile            | *** Runit started as PID 21
seafile            | *** Running /scripts/enterpoint.sh...
seafile            | 2024-11-27 08:58:31 Nginx ready 
seafile            | 2024-11-27 08:58:31 Create linux user seafile in container, please wait. 
seafile-mysql      | 2024-11-27 07:58:30+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.11.10+maria~ubu2204 started.
seafile-mysql      | 2024-11-27 07:58:30+00:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
seafile-mysql      | 2024-11-27 07:58:30+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
seafile-mysql      | 2024-11-27 07:58:30+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.11.10+maria~ubu2204 started.
seafile-mysql      | 2024-11-27 07:58:30+00:00 [Note] [Entrypoint]: MariaDB upgrade not required
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] Starting MariaDB 10.11.10-MariaDB-ubu2204 source revision 3d0fb150289716ca75cd64d62823cf715ee47646 server_uid zIjyEoysD5NU6PKNQ1CIFxZLh24= as process 1
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: Number of transaction pools: 1
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: Using SSE4.2 crc32 instructions
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] mariadbd: O_TMPFILE is not supported on /tmp (disabling future attempts)
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: Initializing buffer pool, total size = 128.000MiB, chunk size = 2.000MiB
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: Completed initialization of buffer pool
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
seafile-mysql      | 2024-11-27  7:58:30 0 [Note] InnoDB: End of log at LSN=1078698
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: 128 rollback segments are active.
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: log sequence number 1078698; transaction id 772
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] Plugin 'FEEDBACK' is disabled.
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
seafile-mysql      | 2024-11-27  7:58:31 0 [Warning] You need to use --log-bin to make --expire-logs-days or --binlog-expire-logs-seconds work.
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] Server socket created on IP: '0.0.0.0'.
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] Server socket created on IP: '::'.
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] mariadbd: ready for connections.
seafile-mysql      | Version: '10.11.10-MariaDB-ubu2204'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: Buffer pool(s) load completed at 241127  7:58:31

Any idea to get non-root working?

My final goal is to move this seafile-data location onto a nfs share with root squashed and therefore (I think) I need seafile to work in non-root mode.

Update: it looks like the seafile container eventually came up 10 minutes later:

seafile-mysql      | 2024-11-27  7:58:31 0 [Note] InnoDB: Buffer pool(s) load completed at 241127  7:58:31
seafile-mysql      | 2024-11-27  8:08:12 6 [Warning] Aborted connection 6 to db: 'seahub_db' user: 'seafile' host: '172.20.0.4' (Got an error reading communication packets)
seafile            | *** Running /etc/my_init.d/01_create_data_links.sh...
seafile            | *** Booting runit daemon...
seafile            | *** Runit started as PID 21
seafile            | *** Running /scripts/enterpoint.sh...
seafile            | 2024-11-27 08:58:31 Nginx ready 
seafile            | 2024-11-27 08:58:31 Create linux user seafile in container, please wait. 
seafile            | 2024-11-27 09:08:08 This is an idle script (infinite loop) to keep container running. 
seafile            | [2024-11-27 09:08:08] Skip running setup-seafile-mysql.py because there is existing seafile-data folder.
seafile            | [11/27/2024 09:08:08][upgrade]: The container was recreated, start fix the media symlinks
seafile            | [11/27/2024 09:08:08][upgrade]: Done
seafile            | 
seafile            | Starting seafile server, please wait ...
seafile            | Seafile server started
seafile            | 
seafile            | Done.
seafile            | 
seafile            | Starting seahub at port 8000 ...
seafile            | 
seafile            | Seahub is started
seafile            | 
seafile            | Done.

I will start using this setup and see whether it is behaving :slight_smile:
Not sure why it took that long to boot up though…