架构概览
前置要求
- 已安装并配置 AWS CLI
- AWS 账号具备 ECS、RDS、ElastiCache、S3、IAM 权限
- Docker 镜像仓库访问权(或 ECR)
步骤 1:创建 AWS 资源
1.1 创建 RDS PostgreSQL
aws rds create-db-instance \
--db-instance-identifier teable-db \
--db-instance-class db.t3.medium \
--engine postgres \
--engine-version 16 \
--master-username teableadmin \
--master-user-password '<你的强密码>' \
--allocated-storage 100 \
--vpc-security-group-ids sg-xxxxxx \
--db-subnet-group-name your-subnet-group \
--publicly-accessible false
等待实例状态变为 available。获取 endpoint:aws rds describe-db-instances \
--db-instance-identifier teable-db \
--query 'DBInstances[0].Endpoint.Address' --output text
1.2 创建 ElastiCache Redis(用于队列)
aws elasticache create-cache-cluster \
--cache-cluster-id teable-cache \
--engine redis \
--cache-node-type cache.t3.small \
--num-cache-nodes 1 \
--engine-version 7.0 \
--security-group-ids sg-xxxxxx \
--cache-subnet-group-name your-subnet-group
获取 endpoint:aws elasticache describe-cache-clusters \
--cache-cluster-id teable-cache \
--show-cache-node-info \
--query 'CacheClusters[0].CacheNodes[0].Endpoint.Address' --output text
1.3 创建 S3 bucket(public + private)
# 创建 public bucket
aws s3api create-bucket \
--bucket teable-public-<你的唯一后缀> \
--region us-west-2 \
--create-bucket-configuration LocationConstraint=us-west-2
# 创建 private bucket
aws s3api create-bucket \
--bucket teable-private-<你的唯一后缀> \
--region us-west-2 \
--create-bucket-configuration LocationConstraint=us-west-2
必做:配置 public bucket
- Public read 策略:
cat > public-bucket-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::teable-public-<你的唯一后缀>/*"
}
]
}
EOF
aws s3api put-bucket-policy \
--bucket teable-public-<你的唯一后缀> \
--policy file://public-bucket-policy.json
- 关闭 public bucket 的”阻止公共访问”:
aws s3api put-public-access-block \
--bucket teable-public-<你的唯一后缀> \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
- CORS 配置(允许任意跨域):
cat > cors.json <<EOF
{
"CORSRules": [
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD", "PUT"],
"AllowedOrigins": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
}
EOF
aws s3api put-bucket-cors \
--bucket teable-public-<你的唯一后缀> \
--cors-configuration file://cors.json
安全提醒:public bucket 必须允许公开读。请确保符合你们公司的安全规范。private bucket 保持私有即可。
1.4 创建 IAM 用户/角色用于 S3 访问
# 创建 IAM 用户
aws iam create-user --user-name teable-s3-user
# 附加 S3 完全访问策略(或创建自定义策略)
aws iam attach-user-policy \
--user-name teable-s3-user \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
# 创建访问密钥
aws iam create-access-key --user-name teable-s3-user
保存输出中的 AccessKeyId 和 SecretAccessKey。
步骤 2:准备环境变量
创建 .env 文件(或 ECS 任务定义的环境变量):
# Core
PUBLIC_ORIGIN=https://teable.yourcompany.com
SECRET_KEY=<生成32位随机字符串>
# Database
PRISMA_DATABASE_URL=postgresql://teableadmin:<password>@<rds-endpoint>:5432/teable
# Redis(队列依赖)
BACKEND_CACHE_PROVIDER=redis
BACKEND_CACHE_REDIS_URI=redis://<elasticache-endpoint>:6379/0
# 性能缓存(可选;可指向同一个 Redis 或单独集群)
BACKEND_PERFORMANCE_CACHE=redis://<elasticache-endpoint>:6379/0
# Storage(S3 双桶)
BACKEND_STORAGE_PROVIDER=s3
BACKEND_STORAGE_S3_REGION=us-west-2
BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
BACKEND_STORAGE_S3_ACCESS_KEY=<步骤1.4的access-key>
BACKEND_STORAGE_S3_SECRET_KEY=<步骤1.4的secret-key>
BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-<你的唯一后缀>
BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-<你的唯一后缀>
STORAGE_PREFIX=https://teable-public-<你的唯一后缀>.s3.us-west-2.amazonaws.com
# 可选:Sandbox 服务(如果单独部署)
# SANDBOX_URL=http://teable-sandbox:7070
步骤 3:部署到 ECS
方案 A:使用 ECS Fargate(推荐,简单)
- 创建 ECS 集群:
aws ecs create-cluster --cluster-name teable-cluster
- 创建任务定义 (
teable-task.json):
{
"family": "teable",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "2048",
"memory": "4096",
"containerDefinitions": [
{
"name": "teable",
"image": "ghcr.io/teableio/teable:latest",
"portMappings": [
{
"containerPort": 3000,
"protocol": "tcp"
}
],
"environment": [
{"name": "PUBLIC_ORIGIN", "value": "https://teable.yourcompany.com"},
{"name": "SECRET_KEY", "value": "***REDACTED***"},
{"name": "PRISMA_DATABASE_URL", "value": "postgresql://..."},
{"name": "BACKEND_CACHE_PROVIDER", "value": "redis"},
{"name": "BACKEND_CACHE_REDIS_URI", "value": "redis://..."},
{"name": "BACKEND_STORAGE_PROVIDER", "value": "s3"},
{"name": "BACKEND_STORAGE_S3_REGION", "value": "us-west-2"},
{"name": "BACKEND_STORAGE_S3_ENDPOINT", "value": "https://s3.us-west-2.amazonaws.com"},
{"name": "BACKEND_STORAGE_S3_ACCESS_KEY", "value": "***"},
{"name": "BACKEND_STORAGE_S3_SECRET_KEY", "value": "***"},
{"name": "BACKEND_STORAGE_PUBLIC_BUCKET", "value": "teable-public-xxx"},
{"name": "BACKEND_STORAGE_PRIVATE_BUCKET", "value": "teable-private-xxx"},
{"name": "STORAGE_PREFIX", "value": "https://teable-public-xxx.s3.us-west-2.amazonaws.com"}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/teable",
"awslogs-region": "us-west-2",
"awslogs-stream-prefix": "teable"
}
}
}
]
}
- 注册任务定义:
aws ecs register-task-definition --cli-input-json file://teable-task.json
- 创建 ECS 服务:
aws ecs create-service \
--cluster teable-cluster \
--service-name teable-service \
--task-definition teable \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xxx,subnet-yyy],securityGroups=[sg-xxx],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=teable,containerPort=3000"
你需要单独创建 Application Load Balancer (ALB) 和目标组,然后在 --load-balancers 中引用。
步骤 4:验证部署
- 检查 ECS 服务状态:
aws ecs describe-services \
--cluster teable-cluster \
--services teable-service
- 查看日志:
aws logs tail /ecs/teable --follow
- 访问健康检查:
curl https://teable.yourcompany.com/health
预期返回:
- 浏览器访问 Teable:
https://teable.yourcompany.com
故障排查
数据库连接错误
- 验证 RDS 安全组允许来自 ECS 任务的流量
- 检查
PRISMA_DATABASE_URL 格式:postgresql://user:pass@endpoint:5432/dbname
Redis 连接错误
- 验证 ElastiCache 安全组允许来自 ECS 的流量
- 使用 主节点 endpoint(不是只读副本)
S3 访问错误
- 验证 IAM 用户具有
s3:GetObject、s3:PutObject、s3:DeleteObject 权限
- 检查 bucket 名称在
BACKEND_STORAGE_PUBLIC_BUCKET / BACKEND_STORAGE_PRIVATE_BUCKET 中完全匹配
- 确保 public bucket 已配置 public read 策略与 CORS
容器启动失败
- 检查 CloudWatch Logs:
/ecs/teable
- 验证所有必需环境变量已设置
- 确保
SECRET_KEY 已设置(不为空)
生产环境建议
-
高可用:
- 至少运行 2 个 ECS 任务,跨多个可用区
- 使用 RDS Multi-AZ 部署
- ElastiCache 使用副本
-
弹性伸缩:
- 启用 ECS 基于 CPU/内存的自动伸缩
- 使用 Application Load Balancer 分发流量
-
安全:
- 使用 AWS Secrets Manager 存储敏感值(而非明文环境变量)
- 启用 RDS 静态加密
- 使用 VPC endpoint 访问 S3/ECR 避免公网流量
-
监控:
- 启用 CloudWatch Container Insights for ECS
- 设置任务失败、高 CPU/内存的告警
-
备份:
- 启用 RDS 自动备份(保留 7-30 天)
- 为 private bucket 启用 S3 版本控制
相关文档