版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

环境配置

.env 配置容器运行中的环境变量,在涉及容器镜像版本调整或更改时仅需调整 .env 文件

...

信息

官网默认启用 caddy 用来实现网关应用和域名的 https 证书管理,这里直接使用内置的 nginx 

seatable.yml

代码块
languageyml
---
services:
  seatable-server:
    image: ${SEATABLE_IMAGE:-seatable/seatable-enterprise:4.3.8}
    restart: unless-stopped
    container_name: seatable-server
    ports:
      - "8006:80"
    volumes:
      - "${SEATABLE_DIR}/seatable-server:/shared"
      - "${SEATABLE_DIR}/deps/seatable.sh:/templates/seatable.sh:rx"
      - "${SEATABLE_DIR}/deps/seatable-license.txt:/shared/seatable/seatable-license.txt"
      - "${SEATABLE_DIR}/deps/licenseparse.py:/opt/seatable/seatable-server-latest/dtable-web/seahub/utils/licenseparse.py:rw"
      - "${SEATABLE_DIR}/deps/seafile-controller:/opt/seatable/seatable-server-latest/seafile/bin/seafile-controller:rw"
      - "${SEATABLE_DIR}/deps/seaf-server:/opt/seatable/seatable-server-latest/seafile/bin/seaf-server:rw"
#      - type: bind
#        source: "./seatable-license.txt"
#        target: "/shared/seatable/seatable-license.txt"
#        read_only: ${SEATABLE_LICENSE_FORCE_READ_ONLY:-false}
    environment:
      - DB_HOST=mariadb
      - DB_ROOT_PASSWD=${SEATABLE_MYSQL_ROOT_PASSWORD:?Variable is not set or empty}
      - SEATABLE_SERVER_HOSTNAME=${SEATABLE_SERVER_HOSTNAME:?Variable is not set or empty} 
      - SEATABLE_SERVER_PROTOCOL=${SEATABLE_SERVER_PROTOCOL:-https}
      - SEATABLE_ADMIN_EMAIL=${SEATABLE_ADMIN_EMAIL:?Variable is not set or empty}
      - SEATABLE_ADMIN_PASSWORD=${SEATABLE_ADMIN_PASSWORD:?Variable is not set or empty}
      - TIME_ZONE=${TIME_ZONE}
    depends_on:
      mariadb:
        condition: service_healthy
      memcached:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend-net
      - backend-seatable-net
    # healthcheck specifically for dtable-web
    healthcheck:
      test: ["CMD-SHELL", "curl --fail http://localhost:8000 || exit 1"]
      interval: 20s
      retries: 3
      start_period: 30s
      timeout: 10s

  mariadb:
    image: ${SEATABLE_DB_IMAGE:-mariadb:10.11.6}
    restart: unless-stopped
    container_name: mariadb
    environment:
      - MYSQL_ROOT_PASSWORD=${SEATABLE_MYSQL_ROOT_PASSWORD:?Variable is not set or empty}
      - MYSQL_LOG_CONSOLE=true
      - MARIADB_AUTO_UPGRADE=1
    volumes:
      - "${SEATABLE_DIR}/mariadb:/var/lib/mysql"
    networks:
      - backend-seatable-net
    healthcheck:
      test:
        [
          "CMD",
          "/usr/local/bin/healthcheck.sh",
          "--connect",
          "--mariadbupgrade",
          "--innodb_initialized",
        ]
      interval: 20s
      retries: 3
      start_period: 30s
      timeout: 10s
      # On older database containers without healthcheck users present you might need to create them manually,
      # otherwise the container stays unhealthy.
  memcached:
    image: ${SEATABLE_MEMCACHED_IMAGE:-memcached:1.6.22}
    restart: unless-stopped
    container_name: memcached
    entrypoint: memcached -m 256
    networks:
      - backend-seatable-net
    healthcheck:
      test: ["CMD-SHELL", "timeout 2 bash -c '</dev/tcp/localhost/11211'"]
      interval: 20s
      retries: 3
      timeout: 5s

  redis:
    image: ${SEATABLE_REDIS_IMAGE:-redis:7.2.3}
    restart: unless-stopped
    container_name: redis
    networks:
      - backend-seatable-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 20s
      retries: 3
      timeout: 5s

networks:
  frontend-net:
    name: frontend-net
  backend-seatable-net:
    name: backend-seatable-net
信息

注意:需要申请 seatable-license.txt 文件。在初始化的过程中需要校验 license 文件创建对应的 repo 文件夹,在初始化时会有错误的日志提示。

seatable-server/seatable/conf/dtable_web_settings.py

代码块
languagepy
IS_PRO_VERSION = True

CSRF_TRUSTED_ORIGINS = ['https://table.waringid.me']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'mariadb',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'password',
        'NAME': 'dtable_db',
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'memcached',
     },
    'locmem': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    },
}
COMPRESS_CACHE_BACKEND = 'locmem'

SECRET_KEY = '1_n338k*han@4$b'

# for dtable-server
DTABLE_PRIVATE_KEY = 'h@6d%re+(=0nfs!k3_k'
DTABLE_SERVER_URL = 'https://table.waringid.me/dtable-server/'
DTABLE_SOCKET_URL = 'https://table.waringid.me/'

# for dtable-web
DTABLE_WEB_SERVICE_URL = 'https://table.waringid.me/'

# for dtable-db
DTABLE_DB_URL = 'https://table.waringid.me/dtable-db/'

# for dtable-storage-server
DTABLE_STORAGE_SERVER_URL = 'http://127.0.0.1:6666/'

NEW_DTABLE_IN_STORAGE_SERVER = True

# for seaf-server
FILE_SERVER_ROOT = 'https://table.waringid.me/seafhttp/'

ENABLE_USER_TO_SET_NUMBER_SEPARATOR = True

TIME_ZONE = 'Asia/Shanghai'

DISABLE_ADDRESSBOOK_V1 = True
ENABLE_ADDRESSBOOK_V2 = True

TEMPLATE_BASE_API_TOKEN = '36fa233b4a0363d0331c223dfeaa480cc461f265'
TEMPLATE_TABLE_NAME = 'templates'
ENABLE_CREATE_BASE_FROM_TEMPLATE = True
SHOW_TEMPLATES_LINK = True

DTABLE_BAIDU_MAP_KEY = 'PlhFWpA02aoURjAOpnWcRGqw7AI8EEyO'

PLUGINS_REPO_ID='a5bbeac5-7dea-4092-9d6e-b9198367cb82'
信息

还需要记得调整 nginx 中关于 hostname 的设置

日常维护

信息

注意:如果没有设置 “CSRF_TRUSTED_ORIGINS = ['https://table.waringid.me']” 会出现下图所示的安全提醒。

Image Added

模板配置

模板配置参考官网说明 Templates and Manual - SeaTable Admin Manual 

  1. 新建 templates 的群组 【需要管理员权限】
  2. 在 templates 群组下新建 “Templates and Plugins” 的 Base 表格
  3. 在 Base 表格中新建 templates 表格,表格内容和格式如图示

Image AddedImage AddedImage Added

信息
  • TEMPLATE_BASE_API_TOKEN 是 “Templates-and-Plugins” Base 表的 API token
    TEMPLATE_TABLE_NAME 是表格名称

Seatable 自带的 Nginx 配置

seatable 自带 Nginx ,这里没有采用官网推荐的 Docker 再增加 caddy 的方式而是直接引用自带的 Nginx ,在部署后的测试过程中发生过很多问题。主要集中在“导入外部文件时提示网络错误”、“打开模板功能链接时提示网络错误”、dtable_web.log 提示“无法访问 API ,后端服务器拒绝”等错误提示。

本文网络访问环境的流程如下

1、DNS 二级域名解析到 Cpolar (提供 ddns 服务)的 Cname【已提前在 cpolar 的控制界面增加预留的二级域名】

2、在容器上启用 cpolar 客户端,配置该客户端将二级域名解析到 WAF 代理【另一个 WAF 容器】同时启用自定义的 SSL 证书

3、WAF 容器监听80 端口,通过 hostname 的方式解析到后端具体的服务器

4、Seatable 容器对外映射8006 端口(内部端口80),seatable 容器本身没有启用 SSL

外网访问 https://table.waringid.me 时自动解析到 seatable 的 8006 端口。出现上述问题的主要原因是:seatable 内置的 nginx 配置并没有启用 SSL ,当外部的 https 传入内部时会出现无法访问后端服务器(443端口)的网络错误和超时提醒。所以需要在 Nginx 的配置文件中增加对应的 SSL 配置。另外需要在容器的宿主机中增加外部域名的本地解析,例如将 table.waringid.me 解析到 127.0.0.1 【/etc/hosts】

代码块
languagetext
server {
    server_name table.waringid.me 127.0.0.1 192.168.77.12;
    listen 443 ssl;
    ssl_certificate /shared/ssl/waringid.cer;
    ssl_certificate_key /shared/ssl/waringid.key;

    proxy_set_header X-Forwarded-For $remote_addr;

    location / {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
            return 204;
        }
        proxy_pass         http://127.0.0.1:8000;
        proxy_set_header   Host $http_host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        proxy_read_timeout  1200s;

        # used for view/edit office file via Office Online Server
        client_max_body_size 0;

        access_log      /opt/nginx-logs/dtable-web.access.log seatableformat;
        error_log       /opt/nginx-logs/dtable-web.error.log;
    }

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;

        client_max_body_size 0;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_request_buffering off;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
        proxy_send_timeout  36000s;
        send_timeout  36000s;

        access_log      /opt/nginx-logs/seafhttp.access.log seatableformat;
        error_log       /opt/nginx-logs/seafhttp.error.log;

    }

    location /media {
        root /opt/seatable/seatable-server-latest/dtable-web;
    }

    location /socket.io {
        proxy_pass http://dtable_servers;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_redirect off;

        proxy_buffers 8 32k;
        proxy_buffer_size 64k;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        access_log      /opt/nginx-logs/socket-io.access.log seatableformat;
        error_log       /opt/nginx-logs/socket-io.error.log;

    }

    location /dtable-server {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
            return 204;
        }
        rewrite ^/dtable-server/(.*)$ /$1 break;
        proxy_pass         http://dtable_servers;
        proxy_redirect     off;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host  $server_name;
        proxy_set_header   X-Forwarded-Proto $scheme;
       client_max_body_size 100m;

        access_log      /opt/nginx-logs/dtable-server.access.log seatableformat;
        error_log       /opt/nginx-logs/dtable-server.error.log;

    }

    location /dtable-db/ {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
            return 204;
        }
        proxy_pass         http://127.0.0.1:7777/;
        proxy_redirect     off;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host  $server_name;
        proxy_set_header   X-Forwarded-Proto $scheme;

        access_log      /opt/nginx-logs/dtable-db.access.log seatableformat;
        error_log       /opt/nginx-logs/dtable-db.error.log;
    } 


日常维护

数据库备份

代码块
cd /opt/seatable-backup/databases
docker exec -it seatable-mysql mysqldump -uroot -pMYSQL_ROOT_PASSWORD --opt ccnet_db > ccnet_db.sql
docker exec -it seatable-mysql mysqldump -uroot -pMYSQL_ROOT_PASSWORD --opt seafile_db > seafile_db.sql
docker exec -it seatable-mysql mysqldump -uroot -pMYSQL_ROOT_PASSWORD --opt dtable_db > dtable_db.sql

数据文件备份

代码块
rsync -az --exclude 'ccnet' --exclude 'logs' --exclude 'db-data' /opt/seatable/seatable-data/seatable /opt/seatable-backup/seatable

dtable-db 备份

代码块
docker exec -it seatable /opt/seatable/scripts/seatable.sh backup-all

数据库恢复

代码块
docker exec -i seatable-mysql /usr/bin/mysql -uroot -pMYSQL_ROOT_PASSWORD ccnet_db < /opt/seatable-backup/databases/ccnet_db.sql
docker exec -i seatable-mysql /usr/bin/mysql -uroot -pMYSQL_ROOT_PASSWORD seafile_db < /opt/seatable-backup/databases/seafile_db.sql
docker exec -i seatable-mysql /usr/bin/mysql -uroot -pMYSQL_ROOT_PASSWORD dtable_db < /opt/seatable-backup/databases/dtable_db.sql

恢复数据文件

代码块
rsync -az /opt/seatable-backup/seatable /opt/seatable/seatable-data/seatable

恢复 dtable-db 文件

代码块
docker exec -it seatable /opt/seatable/scripts/seatable.sh restore-all

更改域名配置

docker exec -it seatable /opt/seatable/scripts/seatable.sh restore-all

更改域名配置

代码块
$ docker exec -it seatable /bin/bash

# for one base
$ seatable.sh python-env /opt/seatable/seatable-server-latest/dtable-web/manage.py domain_transfer -uuid <:base uuid> -od <:old domain> -nd <:new domain>
代码块
$ docker exec -it seatable /bin/bash

# for oneall basebases
$ seatable.sh python-env /opt/seatable/seatable-server-latest/dtable-web/manage.py domain_transfer -uuid <:base uuid> all -od <:old domain> -nd <:new domain>

# for all bases
$ seatable.sh python-env /opt/seatable/seatable-server-latest/dtable-web/manage.py domain_transfer -alluuid 695fa115-4927-4be1-b5b6-fbbbabd43b72  -od <:old domain> -nd <:new domain>

seatable.sh python-env /opt/seatable/seatable-server-latest/dtable-web/manage.py domain_transfer -uuid 695fa115-4927-4be1-b5b6-fbbbabd43b72  -od https://dev.seatable.cn -nd https://cloud.seatable.io

增加用户

...

https://dev.seatable.cn -nd https://cloud.seatable.io

增加用户

代码块
docker exec -it seatable-server /shared/seatable/scripts/seatable.sh superuser

增加脚本运行功能