环境配置
.env 配置容器运行中的环境变量,在涉及容器镜像版本调整或更改时仅需调整 .env 文件
使用 .env 可以配置多个容器运行的配置文件而无需在启动时指定对应的文件名
#COMPOSE_FILE='seatable-server.yml' COMPOSE_FILE='seatable-server.yml' COMPOSE_PATH_SEPARATOR=',' # system settings TIME_ZONE='Asia/Shanghai' # seatable server url SEATABLE_SERVER_HOSTNAME='table.waringid.me' SEATABLE_SERVER_PROTOCOL='https' # initial web admin SEATABLE_ADMIN_EMAIL='13609796771@139.com' SEATABLE_ADMIN_PASSWORD='www.myj123.com' # database SEATABLE_MYSQL_ROOT_PASSWORD='www.myj123.com' SEATABLE_DIR='/data/seatable'
官网默认启用 caddy 用来实现网关应用和域名的 https 证书管理,这里直接使用内置的 nginx
seatable.yml
--- 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
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']” 会出现下图所示的安全提醒。
模板配置
模板配置参考官网说明 Templates and Manual - SeaTable Admin Manual
- 新建 templates 的群组 【需要管理员权限】
- 在 templates 群组下新建 “Templates and Plugins” 的 Base 表格
- 在 Base 表格中新建 templates 表格,表格内容和格式如图示
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】
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 /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> # for all bases $ seatable.sh python-env /opt/seatable/seatable-server-latest/dtable-web/manage.py domain_transfer -all -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
增加用户
docker exec -it seatable-server /shared/seatable/scripts/seatable.sh superuser
增加脚本运行功能
- https://forum.seatable.io/t/tutorial-create-a-barcode-and-save-it-as-image-to-seatable/1658/5
- https://github.com/seatable/seatable-scripts/blob/master/examples/python/generate_barcode.py
- https://admin.seatable.io/installation/components/python-pipeline/
添加评论