自托管部署
使用 Docker Compose 在自有 Linux 服务器上部署 dTax,15 分钟内完成。
前提条件
- Linux 服务器(推荐 Ubuntu 22.04+),2 GB+ 内存
- Docker Engine 24+ 和 Docker Compose v2
- 已将域名指向服务器 IP
- 防火墙开放 80 和 443 端口
快速开始
-
克隆仓库
Terminal window git clone https://github.com/dTaxLab/dtax.gitcd dtax -
配置环境变量
Terminal window cp .env.production.example .env编辑
.env,填写所有必填项:变量 说明 POSTGRES_PASSWORD强数据库密码 JWT_SECRET随机字符串,至少 32 字符 ENCRYPTION_KEY64 字符十六进制字符串 — 见下方说明 CORS_ORIGIN你的域名,例如 https://tax.example.comAPP_URL同上域名(用于密码重置邮件链接) NEXT_PUBLIC_API_URLhttps://tax.example.com/api(构建时变量,必须在docker compose build之前设置) -
启动服务
此命令会启动 PostgreSQL、Redis、API、Web 和 nginx。
migrate服务会自动执行数据库迁移。验证运行状态:
Terminal window docker compose pscurl http://localhost/api/health
架构说明
┌──────────┐ :80/:443 ────│ nginx │ └────┬─────┘ ┌────┴─────┐ ┌─────│ 路由 │─────┐ │ └──────────┘ │ ┌────┴───┐ ┌─────┴────┐ │ API │ │ Web │ │ :3001 │ │ :3000 │ └────┬───┘ └──────────┘ ┌────┴───┐ ┌───────┐ │Postgres│ │ Redis │ └────────┘ └───────┘Sync Worker 在 API 进程内运行,每 5 秒轮询 PostgreSQL 处理待执行的任务。它处理两种任务类型:
WALLET_SYNC— 获取链上或交易所交易记录PRICE_ENRICH— 回填缺失的 USD 价格,然后自动计算 FIFO 税务报告并发送汇总邮件
无需独立的 Worker 容器。配置 RESEND_API_KEY + FROM_EMAIL + APP_URL 以启用报税就绪邮件通知。
TLS 证书(Let’s Encrypt)
-
更新 nginx 配置
编辑
docker/nginx/nginx.conf,将server_name _;替换为你的域名:server_name tax.example.com; -
申请证书
Terminal window docker compose up -d nginxdocker run --rm \-v dtax_letsencrypt:/etc/letsencrypt \-v dtax_certbot-data:/var/www/certbot \certbot/certbot certonly \--webroot -w /var/www/certbot \-d tax.example.com \--agree-tos --email you@example.com -
启用 HTTPS
在
docker/nginx/nginx.conf中添加 HTTPS 服务块:server {listen 443 ssl http2;server_name tax.example.com;ssl_certificate /etc/letsencrypt/live/tax.example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/tax.example.com/privkey.pem;include /etc/nginx/snippets/ssl-params.conf;location /api/ {proxy_pass http://api/api/;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-Proto $scheme;proxy_buffering off;proxy_cache off;proxy_read_timeout 300s;}location / {proxy_pass http://web;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-Proto $scheme;}}Terminal window docker compose restart nginx -
自动续期证书
Terminal window echo "0 3 * * * docker run --rm \-v dtax_letsencrypt:/etc/letsencrypt \-v dtax_certbot-data:/var/www/certbot \certbot/certbot renew --quiet \&& docker compose restart nginx" | crontab -
创建管理员账号
- 访问
https://yourdomain.com/register注册账号 - 通过数据库将账号提升为管理员:
docker compose exec postgres psql -U dtax -c \ "UPDATE \"User\" SET role='ADMIN' WHERE email='your@email.com';"更新
git pulldocker compose builddocker compose up -dmigrate 服务会自动应用新的数据库迁移。
数据备份
# 执行备份chmod +x docker/scripts/backup.sh./docker/scripts/backup.sh ./backups
# 每天凌晨 2 点自动备份echo "0 2 * * * /path/to/dtax/docker/scripts/backup.sh /path/to/dtax/backups" | crontab -
# 从备份恢复gunzip -c backups/dtax_20260313_020000.sql.gz | \ docker compose exec -T postgres psql -U dtax dtax可选服务
| 服务 | 环境变量 | 用途 |
|---|---|---|
| Resend | RESEND_API_KEY、FROM_EMAIL | 邮件验证、密码重置和自动报税就绪通知 — 未配置则密码重置、邮件验证及价格回填完成后的税务报告邮件将被静默跳过 |
| Stripe | STRIPE_SECRET_KEY、STRIPE_WEBHOOK_SECRET、STRIPE_PRO_PRICE_ID、STRIPE_CPA_PRICE_ID | 订阅付费功能 |
| Anthropic | ANTHROPIC_API_KEY | AI 交易分类和智能对话 |
| Etherscan | ETHERSCAN_API_KEY | EVM 链上交易索引(以太坊、Polygon、BSC、Arbitrum、Optimism) |
| Solscan | SOLSCAN_API_KEY | Solana 链上交易索引 |
| PostHog | NEXT_PUBLIC_POSTHOG_KEY、NEXT_PUBLIC_POSTHOG_HOST | 产品数据分析 |
| Sentry | SENTRY_DSN | 错误追踪 |
所有可选服务未配置时均会优雅降级,不影响核心功能。
常见问题
服务启动失败
docker compose logs api # 查看 API 日志docker compose logs web # 查看 Web 日志docker compose logs nginx # 查看 nginx 日志API 立即崩溃
在 API 日志中查找 FATAL: ENCRYPTION_KEY — 这表示 ENCRYPTION_KEY 不是有效的 64 字符十六进制字符串。使用 openssl rand -hex 32 重新生成。
数据库连接错误
确认 .env 中的 POSTGRES_PASSWORD 与 postgres 卷首次创建时使用的密码一致:
docker compose ps postgresdocker compose logs postgres端口冲突
如果 80 或 443 端口已被占用,编辑 docker-compose.yml 修改 nginx 的端口映射。
磁盘空间不足
docker system prune -f # 清理未使用的镜像和容器重置所有数据
docker compose down -vdocker compose up -d