Skip to content

Seafile Docker Cluster Deployment

Seafile Docker cluster deployment requires "sticky session" settings in the load balancer. Otherwise sometimes folder download on the web UI can't work properly. Read the Load Balancer Setting for details.

Environment

System: Ubuntu 20.04

docker-compose: 1.25.0

Seafile Server: 2 frontend nodes, 1 backend node

We assume you have already deployed memcache, MariaDB, ElasticSearch in separate machines and use S3 like object storage.

Deployment preparation

Create the three databases ccnet_db, seafile_db, and seahub_db required by Seafile on MariaDB/MySQL, and authorize the `seafile` user to be able to access these three databases:

$ mysql -h{your mysql host} -u[username] -p[password]

mysql>
create user 'seafile'@'%' identified by 'PASSWORD';

create database `ccnet_db` character set = 'utf8';
create database `seafile_db` character set = 'utf8';
create database `seahub_db` character set = 'utf8';

GRANT ALL PRIVILEGES ON `ccnet_db`.* to 'seafile'@'%';
GRANT ALL PRIVILEGES ON `seafile_db`.* to 'seafile'@'%';
GRANT ALL PRIVILEGES ON `seahub_db`.* to 'seafile'@'%';

You also need to create a table in `seahub_db`

mysql>
use seahub_db;
CREATE TABLE `avatar_uploaded` (
  `filename` text NOT NULL,
  `filename_md5` char(32) NOT NULL,
  `data` mediumtext NOT NULL,
  `size` int(11) NOT NULL,
  `mtime` datetime NOT NULL,
  PRIMARY KEY (`filename_md5`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Deploy Seafile service

Deploy seafile frontend nodes

Create the mount directory

$ mkdir -p /opt/seafile/shared

Create the docker-compose.yml file

$ cd /opt/seafile
$ vim docker-compose.yml
services:
  seafile:
    image: docker.seadrive.org/seafileltd/seafile-pro-mc:latest
    container_name: seafile
    ports:
      - 80:80
    volumes:
      - /opt/seafile/shared:/shared
    environment:
      - CLUSTER_SERVER=true
      - CLUSTER_MODE=frontend
      - TIME_ZONE=UTC  # Optional, default is UTC. Should be uncomment and set to your local time zone.

Note: CLUSTER_SERVER=true means seafile cluster mode, CLUSTER_MODE=frontend means this node is seafile frontend server.

Start the seafile docker container

$ cd /opt/seafile
$ docker compose up -d

Initial configuration files

1. Manually generate configuration files

$ docker exec -it seafile bash

# cd /scripts  && ./cluster_conf_init.py
# cd /opt/seafile/conf 

2. Modify the mysql configuration options (user, host, password) in configuration files such as ccnet.conf, seafevents.conf, seafile.conf and seahub_settings.py.

3. Modify the memcached configuration option in seahub_settings.py

CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'memcached:11211',
    },
...
}
                         |
                         v

CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': '{you memcached server host}:11211',
    },
...
}

4. Modify the [INDEX FILES] configuration options in seafevents.conf

[INDEX FILES]
es_port = {your elasticsearch server port}
es_host = {your elasticsearch server host}
external_es_server = true
enabled = true
highlight = fvh
interval = 10m
...

5. Add some configurations in seahub_settings.py

SERVICE_URL = 'http{s}://{your server IP or sitename}/'
FILE_SERVER_ROOT = 'http{s}://{your server IP or sitename}/seafhttp'
AVATAR_FILE_STORAGE = 'seahub.base.database_storage.DatabaseStorage'

6. Add cluster special configuration in seafile.conf

[cluster]
enabled = true

7. Add memory cache configuration in seafile.conf

[memcached]
memcached_options = --SERVER={you memcached server host} --POOL-MIN=10 --POOL-MAX=100

Import the tables of seahub_db, seafile_db and ccnet_db

Enter the container, and then execute the following commands to import tables

$ docker exec -it seafile bash

# apt-get update && apt-get install -y mysql-client

# mysql -h{your mysql host} -u[username] -p[password]  ccnet_db < /opt/seafile/seafile-server-latest/sql/mysql/ccnet.sql
# mysql -h{your mysql host} -u[username] -p[password]  seafile_db < /opt/seafile/seafile-server-latest/sql/mysql/seafile.sql
# mysql -h{your mysql host} -u[username] -p[password]  seahub_db <  /opt/seafile/seafile-server-latest/seahub/sql/mysql.sql

Start Seafile service

$ docker exec -it seafile bash

# cd /opt/seafile/seafile-server-latest
# ./seafile.sh start && ./seahub.sh start

When you start it for the first time, seafile will guide you to set up an admin user.

When deploying the second frontend node, you can directly copy all the directories generated by the first frontend node, including the docker-compose.yml file and modified configuration files, and then start the seafile docker container.

Deploy seafile backend node

Create the mount directory

$ mkdir -p /opt/seafile/shared

Create the docker-compose.yml file

$ cd /opt/seafile
$ vim docker-compose.yml
services:
  seafile:
    image: docker.seadrive.org/seafileltd/seafile-pro-mc:latest
    container_name: seafile
    ports:
      - 80:80
    volumes:
      - /opt/seafile/shared:/shared      
    environment:
      - CLUSTER_SERVER=true
      - CLUSTER_MODE=backend
      - TIME_ZONE=UTC  # Optional, default is UTC. Should be uncomment and set to your local time zone.

Note: CLUSTER_SERVER=true means seafile cluster mode, CLUSTER_MODE=backend means this node is seafile backend server.

Start the seafile docker container

$ cd /opt/seafile
$ docker compose up -d

Copy configuration files of the frontend node, and then start Seafile server of the backend node

$ docker exec -it seafile bash

# cd /opt/seafile/seafile-server-latest
# ./seafile.sh start && ./seafile-background-tasks.sh start

Use S3 as backend storage

Modify the seafile.conf file on each node to configure S3 storage.

vim seafile.conf

[commit_object_backend]
name = s3
bucket = {your-commit-objects}  # The bucket name can only use lowercase letters, numbers, and dashes
key_id = {your-key-id}
key = {your-secret-key}
use_v4_signature = true
aws_region = eu-central-1  # eu-central-1 for Frankfurt region

[fs_object_backend]
name = s3
bucket = {your-fs-objects}
key_id = {your-key-id}
key = {your-secret-key}
use_v4_signature = true
aws_region = eu-central-1

[block_backend]
name = s3
bucket = {your-block-objects}
key_id = {your-key-id}
key = {your-secret-key}
use_v4_signature = true
aws_region = eu-central-1

Deployment load balance (Optional)

Install HAproxy and Keepalived services

Execute the following commands on the two Seafile frontend servers:

$ apt install haproxy keepalived -y

$ mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

$ cat > /etc/haproxy/haproxy.cfg << 'EOF'
global
    log 127.0.0.1 local1 notice
    maxconn 4096
    user haproxy
    group haproxy

defaults
    log global
    mode http
    retries 3
    timeout connect 10000
    timeout client 300000
    timeout server 300000

listen seafile 0.0.0.0:80
    mode http
    option httplog
    option dontlognull
    option forwardfor
    cookie SERVERID insert indirect nocache
    server seafile01 Front-End01-IP:8001 check port 11001 cookie seafile01
    server seafile02 Front-End02-IP:8001 check port 11001 cookie seafile02
EOF

Note: Correctly modify the IP address (Front-End01-IP and Front-End02-IP) of the frontend server in the above configuration file.

Choose one of the above two servers as the master node, and the other as the slave node.

Perform the following operations on the master node:

$ cat > /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived

global_defs {
    notification_email {
        root@localhost
    }
    notification_email_from keepalived@localhost
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id node1
    vrrp_mcast_group4 224.0.100.18
}

vrrp_instance VI_1 {
    state MASTER
    interface eno1   # Set to the device name of a valid network interface on the current server, and the virtual IP will be bound to the network interface
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass seafile123
    }
    virtual_ipaddress {
        172.26.154.45/24 dev eno1  # Configure to the correct virtual IP and network interface device name
    }
}
EOF

Note: Correctly configure the virtual IP address and network interface device name in the above file.

Perform the following operations on the standby node:

$ cat > /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived

global_defs {
    notification_email {
        root@localhost
    }
    notification_email_from keepalived@localhost
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id node2
    vrrp_mcast_group4 224.0.100.18
}

vrrp_instance VI_1 {
    state BACKUP
    interface eno1   # Set to the device name of a valid network interface on the current server, and the virtual IP will be bound to the network interface
    virtual_router_id 50
    priority 98
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass seafile123
    }
    virtual_ipaddress {
        172.26.154.45/24 dev eno1   # Configure to the correct virtual IP and network interface device name
    }
}
EOF

Finally, run the following commands on the two Seafile frontend servers to start the corresponding services:

$ systemctl enable --now haproxy
$ systemctl enable --now keepalived

So far, Seafile cluster has been deployed.