-
由
虚拟的现实创建于6月 24, 2025 需要 5 分钟阅读时间
简介
seatable 5.3.10 以前的版本部署操作可以参考历史文档 Docker-部署Seatable-4.3.8 和 Docker-Seatable-5.0.9。
从 5.3.10 版本开始增加了功能并调整了配置方式:https://seatable.com/seatable-release-5-3/ 和 https://seatable.com/api-gateway-version-5-3/
- 加强并整合了 API 的功能,将以往版本中针对 dtable-db 和 dtable-server 的 API 整合到同一个 API 的访问接口
- 官网的安装配置步骤中整合 caddy 作为前端代理
- 取消了 private_key 的配置 ,通过统一的 JWT 进行安全通讯
- 增加了表格的属性以及更细致的权限配置功能
- APP 和 数据分析功能可以整合到页面中
- 去掉了 memcache 缓存,简化了配置文件
- ……
全新安装
这里的全新安装不配置 caddy 组件,直接通过以往的方式将配置内容整合到 .env 和 seatable-server.yml 配置文件中。
如果在配置中启用 https ,需要在 nginx.conf 文件中增加 ssl 配置项
.env
展开源码
# components to be used; IMPORTANT: there should be no space between the files names ! COMPOSE_FILE='seatable-server.yml' COMPOSE_PATH_SEPARATOR=',' # system settings TIME_ZONE='Asia/Shanghai' # seatable server url SEATABLE_SERVER_HOSTNAME='table.lfang123.com' SEATABLE_SERVER_PROTOCOL='https' # initial web admin SEATABLE_ADMIN_EMAIL='1366771@139.com' SEATABLE_ADMIN_PASSWORD='password-db' # database SEATABLE_MYSQL_ROOT_PASSWORD='password-db' MARIADB_PASSWORD='password-db' # redis REDIS_PASSWORD='260963684c515968cd4e1068a39cea741157fa195c1201a85d4c63a054c089dc' # shared secret for secure communication JWT_PRIVATE_KEY='l#z5)izj#qbip0q$6t3b3^+@ad5@4!ozk+m!$w^cu$q!6v%^_^' SEATABLE_DIR='/data/seatable'
seatable-server.yml
展开源码
--- services: seatable-server: image: ${SEATABLE_IMAGE:-seatable/seatable-enterprise:5.3.10} 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/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" environment: - SEATABLE_MYSQL_DB_HOST=${MARIADB_HOST:-mariadb} - SEATABLE_MYSQL_DB_PORT=${MARIADB_PORT:-3306} - SEATABLE_MYSQL_DB_USER=root - SEATABLE_MYSQL_DB_PASSWORD=${MARIADB_PASSWORD:?Variable is not set or empty} - INIT_SEATABLE_MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD:-${MARIADB_PASSWORD}} - SEATABLE_MYSQL_DB_DTABLE_DB_NAME=dtable_db - SEATABLE_MYSQL_DB_CCNET_DB_NAME=ccnet_db - SEATABLE_MYSQL_DB_SEAFILE_DB_NAME=seafile_db - REDIS_HOST=${REDIS_HOST:-redis} - REDIS_PORT=${REDIS_PORT:-6379} - REDIS_PASSWORD=${REDIS_PASSWORD:?Variable is not set or empty} - JWT_PRIVATE_KEY=${JWT_PRIVATE_KEY:?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} - PYTHON_SCHEDULER_URL=${PYTHON_SCHEDULER_URL:-http://python-scheduler} - PYTHON_SCHEDULER_AUTH_TOKEN=${PYTHON_SCHEDULER_AUTH_TOKEN:-} - REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt - SEATABLE_EMAIL_USE_TLS=${SEATABLE_EMAIL_USE_TLS:-} - SEATABLE_EMAIL_HOST=${SEATABLE_EMAIL_HOST:-} - SEATABLE_EMAIL_HOST_USER=${SEATABLE_EMAIL_HOST_USER:-} - SEATABLE_EMAIL_HOST_PASSWORD=${SEATABLE_EMAIL_HOST_PASSWORD:-} - SEATABLE_EMAIL_PORT=${SEATABLE_EMAIL_PORT:-} - SEATABLE_DEFAULT_FROM_EMAIL=${SEATABLE_DEFAULT_FROM_EMAIL:-} - SEATABLE_SERVER_EMAIL=${SEATABLE_SERVER_EMAIL:-} - SEATABLE_SHOW_TEMPLATES_LINK=${SEATABLE_SHOW_TEMPLATES_LINK:-} - SEATABLE_TEMPLATE_BASE_API_TOKEN=${SEATABLE_TEMPLATE_BASE_API_TOKEN:-} - SEATABLE_TEMPLATE_TABLE_NAME=${SEATABLE_TEMPLATE_TABLE_NAME:-} - SEATABLE_ENABLE_CREATE_BASE_FROM_TEMPLATE=${SEATABLE_ENABLE_CREATE_BASE_FROM_TEMPLATE:-} - SEATABLE_HELP_LINK=${SEATABLE_HELP_LINK:-https://help.seatable.com} - SEATABLE_LOG_LEVEL=${SEATABLE_LOG_LEVEL:-INFO} depends_on: mariadb: condition: service_healthy redis: condition: service_healthy networks: - frontend-net - backend-seatable-net 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:11.4.3-noble} 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 - TZ=${TIME_ZONE} 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. redis: image: ${SEATABLE_REDIS_IMAGE:-redis:7.2.7-bookworm} restart: unless-stopped container_name: redis environment: - REDIS_PASSWORD=${REDIS_PASSWORD:?Variable is not set or empty} command: - /bin/sh - -c - redis-server --requirepass "$${REDIS_PASSWORD:?REDIS_PASSWORD variable is not set}" 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
/data/seatable/seatable-server/seatable/conf/nginx.conf
nginx.conf 文件在容器启动后会自动创建。默认情况下无需其它设置也能正常登录并使用在线表格应用,但是应用的在线导出表格为 excel 功能不正常,无法正常导出附件(导入附件没有问题)。该问题的原因是容器无法正常响应 https 的访问请求,需要在容器内部构建能访问的 https 环境。
展开源码
log_format seatableformat '[$time_iso8601] $http_x_forwarded_for $remote_addr "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time'; upstream dtable_servers { server 127.0.0.1:5000; keepalive 15; } server { server_name table.lfang123.com; listen 80; # for letsencrypt location /.well-known/acme-challenge/ { alias /var/www/challenges/; try_files $uri =404; } proxy_set_header X-Forwarded-For $remote_addr; location / { 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; } 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"; 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 /api-gateway/socket.io/ { proxy_pass http://127.0.0.1:7780/socket.io/; 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 { 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 $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_set_header X-Forwarded-Proto $scheme; # used for import excel 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/ { 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; } 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"; proxy_pass http://127.0.0.1:7777/; proxy_redirect off; 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_set_header X-Forwarded-Proto $scheme; client_max_body_size 10m; access_log /opt/nginx-logs/dtable-db.access.log seatableformat; error_log /opt/nginx-logs/dtable-db.error.log; } location /api-gateway/ { 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; } 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"; proxy_pass http://127.0.0.1:7780/; proxy_redirect off; 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_set_header X-Forwarded-Proto $scheme; proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; access_log /opt/nginx-logs/api-gateway.access.log seatableformat; error_log /opt/nginx-logs/api-gateway.error.log; } } server { server_name table.lfang123.com 127.0.0.1; listen 443 ssl; ssl_certificate /shared/ssl/lfang.cer; ssl_certificate_key /shared/ssl/lfang.key; proxy_set_header X-Forwarded-For $remote_addr; location / { 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; } 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"; 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 /api-gateway/socket.io/ { proxy_pass http://127.0.0.1:7780/socket.io/; 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 { 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 $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_set_header X-Forwarded-Proto $scheme; # used for import excel 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/ { 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; } 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"; proxy_pass http://127.0.0.1:7777/; proxy_redirect off; 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_set_header X-Forwarded-Proto $scheme; client_max_body_size 10m; access_log /opt/nginx-logs/dtable-db.access.log seatableformat; error_log /opt/nginx-logs/dtable-db.error.log; } location /api-gateway/ { 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; } 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"; proxy_pass http://127.0.0.1:7780/; proxy_redirect off; 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_set_header X-Forwarded-Proto $scheme; proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; access_log /opt/nginx-logs/api-gateway.access.log seatableformat; error_log /opt/nginx-logs/api-gateway.error.log; } }
- 无标签