# Seafile Docker Cluster Deployment - Seafile Admin Manual
Author: seafile

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.