LotDB Vue 阿里云 ECS 部署实战记录
本文档总结 lotdb-vue 部署到阿里云 ECS 的完整流程,覆盖代码上传、Docker Compose 启动、域名映射、宿主机 Nginx 反代、HTTPS 证书接入,以及部署过程中常见问题排查。
1. 推荐部署架构
当服务器已有宿主机 Nginx,并且还有其他二级域名在使用时,推荐使用以下结构:
text
浏览器
-> https://lotdb.wkylin.cn
-> 宿主机 Nginx 80/443
-> 反代到 127.0.0.1:18081
-> Docker frontend 容器 Nginx
/ -> Vue 静态页面
/api -> backend:3000
/uploads -> backend:3000
backend
-> mysql:3306
-> iotdb:6667 / 18080
公网安全组只建议开放:
22/tcp:SSH80/tcp:HTTP443/tcp:HTTPS
不要开放:
3000/tcp3306/tcp6667/tcp18080/tcp
2. 服务器准备
确认 Docker 和 Compose 已安装:
bash
docker --version
docker compose version
如果 ECS 是 2核 2G,建议增加 swap。该项目同时运行 MySQL + IoTDB + Node backend + Nginx frontend,2G 内存比较紧张,没有 swap 时 MySQL 或 IoTDB 容易反复重启。
bash
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
grep -q '^/swapfile ' /etc/fstab || echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
free -h
3. 上传代码
建议部署目录:
bash
mkdir -p /opt/lotdb-vue
cd /opt/lotdb-vue
可以用 Git 拉取:
bash
git clone <your-repository-url> .
也可以本地打包后通过 scp 上传到 /opt/lotdb-vue。
4. 配置生产环境变量
复制生产环境模板:
bash
cp backend/.env.prod.example backend/.env.prod
编辑:
bash
vim backend/.env.prod
关键配置示例:
env
# Runtime
PORT=3000
NODE_ENV=production
JWT_SECRET=replace-with-a-long-random-secret
ADMIN_REGISTER_CODE=replace-with-your-admin-register-code
# MySQL
MYSQL_ROOT_PASSWORD=replace-with-strong-root-password
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_USER=lotdb
MYSQL_PASSWORD=replace-with-strong-app-password
MYSQL_DATABASE=lotdb
# IoTDB
IOTDB_HOST=iotdb
IOTDB_PORT=6667
IOTDB_REST_PORT=18080
IOTDB_USERNAME=root
IOTDB_PASSWORD=root
# Files
UPLOAD_DIR=uploads
注意:
ADMIN_REGISTER_CODE只用于注册管理员,不是登录密码。- 默认管理员账号是
admin / Admin@123。 - 默认客户账号是
buyer / Admin@123。 - MySQL 官方镜像只会在空数据卷第一次初始化时读取
MYSQL_USER、MYSQL_PASSWORD等变量。已经初始化过的数据卷不会因为修改.env.prod自动重建用户。
5. Docker Compose 端口设置
服务器已有宿主机 Nginx 时,容器不要直接占用 80 或 443。
推荐使用 docker-compose.prod.yml,由宿主机 Nginx 负责 HTTPS,Docker 内部只提供 HTTP。
将 frontend 服务端口设置为:
yaml
frontend:
ports:
- "127.0.0.1:18081:80"
不要使用:
yaml
ports:
- "80:80"
也不建议在这种场景下使用 docker-compose.prod.https.yml,否则 HTTPS 入口会分散到宿主机 Nginx 和容器 Nginx 两处,容易和已有站点冲突。
6. 启动服务
bash
cd /opt/lotdb-vue
docker compose -f docker-compose.prod.yml up -d --build
查看状态:
bash
docker compose -f docker-compose.prod.yml ps
正常状态应类似:
text
lotdb-frontend Up 127.0.0.1:18081->80/tcp
lotdb-backend Up 3000/tcp
lotdb-mysql Up 3306/tcp
lotdb-iotdb Up 6667/tcp
如果 mysql 或 iotdb 的 STATUS 类似 Up 4 seconds、Up 15 seconds,但容器已创建数分钟,说明容器在反复重启,需要查看日志和内存状态。
7. 域名解析
在阿里云 DNS 添加 A 记录:
text
主机记录:lotdb
记录类型:A
记录值:*.*.*.*
对应访问域名:
text
lotdb.wkylin.cn
8. 宿主机 Nginx 反代与 HTTPS
如果证书已手动上传到 /etc/nginx/ssl,可以由宿主机 Nginx 终止 HTTPS,然后反代到 127.0.0.1:18081。
示例配置:
nginx
server {
listen 80;
server_name lotdb.wkylin.cn;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name lotdb.wkylin.cn;
ssl_certificate /etc/nginx/ssl/your-cert.pem;
ssl_certificate_key /etc/nginx/ssl/your-cert.key;
location / {
proxy_pass http://127.0.0.1:18081;
proxy_http_version 1.1;
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;
}
}
检查并重载:
bash
nginx -t
systemctl reload nginx
验证:
bash
curl https://lotdb.wkylin.cn
curl https://lotdb.wkylin.cn/api/v1/products
9. 分层排查 502
502 Bad Gateway 需要先判断是哪一层断了。
9.1 宿主机 Nginx 到 frontend 容器
bash
curl -I http://127.0.0.1:18081
如果失败,说明宿主机 Nginx 配置或 Docker frontend 端口映射有问题。
9.2 frontend 容器到 backend 容器
bash
curl http://127.0.0.1:18081/api/v1/products
如果首页 200、API 502,说明 frontend 容器无法反代到 backend:3000。
继续看后端日志:
bash
docker compose -f docker-compose.prod.yml logs --tail=150 backend
也可以在容器内测试:
bash
docker compose -f docker-compose.prod.yml exec backend sh -lc "wget -qO- http://127.0.0.1:3000/health || true"
docker compose -f docker-compose.prod.yml exec frontend sh -lc "wget -S -O- http://backend:3000/health || true"
10. MySQL 常见问题
10.1 MySQL 未就绪
后端日志可能出现:
text
AppError: MySQL 未就绪
connect ECONNREFUSED mysql:3306
如果 MySQL 刚启动,可以等待 1 到 2 分钟后重启后端:
bash
docker compose -f docker-compose.prod.yml restart backend
10.2 MySQL 用户权限错误
日志可能出现:
text
Host '172.x.x.x' is not allowed to connect to this MySQL server
通常原因是 MySQL 数据卷已经初始化过,之后又修改了 MYSQL_USER 或 MYSQL_PASSWORD,但 MySQL 不会自动重建用户。
新部署、无重要数据时可以直接重置所有 volume:
bash
docker compose -f docker-compose.prod.yml down -v
docker compose -f docker-compose.prod.yml up -d --build
注意:down -v 会删除 MySQL、IoTDB、uploads 等 Docker volume。
如需保留数据,需要进入 MySQL 手动创建和授权用户:
bash
docker compose -f docker-compose.prod.yml exec mysql mysql -uroot -p
然后执行:
sql
CREATE USER IF NOT EXISTS 'lotdb'@'%' IDENTIFIED BY 'your-app-password';
ALTER USER 'lotdb'@'%' IDENTIFIED BY 'your-app-password';
GRANT ALL PRIVILEGES ON lotdb.* TO 'lotdb'@'%';
FLUSH PRIVILEGES;
11. IoTDB 常见问题
11.1 REST 端口未就绪
后端日志可能出现:
text
connect ECONNREFUSED iotdb:18080
说明 IoTDB REST 服务还没起来,先查看容器状态:
bash
docker compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml logs --tail=200 iotdb
待 IoTDB 稳定后重启后端:
bash
docker compose -f docker-compose.prod.yml restart backend
11.2 IoTDB 密码错误
后端日志可能出现:
text
WRONG_LOGIN_PASSWORD
新部署且没有重要 IoTDB 数据时,可以重置 IoTDB 数据卷:
bash
docker compose -f docker-compose.prod.yml down
docker volume rm lotdb-vue_iotdb_data
docker compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.prod.yml restart backend
分析页接口如 /api/v1/analytics/inventory 依赖 IoTDB。如果 IoTDB 异常,普通商品和订单功能可能仍可用,但分析图表会报 500。
12. 容器反复重启排查
如果 docker compose ps 显示容器创建已久但 STATUS 只有几秒:
text
lotdb-iotdb Up 4 seconds
lotdb-mysql Up 15 seconds
说明容器正在崩溃并被 restart: unless-stopped 拉起。
查看日志:
bash
docker compose -f docker-compose.prod.yml logs --tail=200 mysql
docker compose -f docker-compose.prod.yml logs --tail=200 iotdb
查看内存:
bash
free -h
docker stats --no-stream
2G ECS 上优先确认 swap 已启用。
13. 登录与接口排查
默认账号:
text
管理员:admin / Admin@123
客户:buyer / Admin@123
登录接口:
bash
curl -i -X POST https://lotdb.wkylin.cn/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"account":"admin","password":"Admin@123"}'
如果登录接口 500,查看后端日志:
bash
docker compose -f docker-compose.prod.yml logs --tail=120 backend
如果是表结构不完整,检查数据库:
bash
docker compose -f docker-compose.prod.yml exec mysql mysql -ulotdb -p lotdb -e "show tables; describe users; describe operation_logs;"
operation_logs 表用于记录登录、注册、退出等操作日志。缺表或字段不一致可能导致登录成功后写日志失败。
14. 最终验证清单
服务器本机验证:
bash
curl -I http://127.0.0.1:18081
curl http://127.0.0.1:18081/api/v1/products
公网验证:
bash
curl https://lotdb.wkylin.cn
curl https://lotdb.wkylin.cn/api/v1/products
容器状态:
bash
docker compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml logs --tail=100 backend
浏览器验证:
- 访问
https://lotdb.wkylin.cn - 使用
admin / Admin@123登录后台 - 使用
buyer / Admin@123登录客户侧 - 检查商品列表、订单页面、库存页面
- 检查分析页面是否能正常加载 IoTDB 图表
15. 关键经验
- 已有宿主机 Nginx 时,Docker frontend 只绑定
127.0.0.1:18081:80。 - 只修改实际启动使用的 Compose 文件。例如使用
docker-compose.prod.yml启动,就只需要改这个文件。 502要按链路分层排查,先测127.0.0.1:18081,再测/api/v1/products。- MySQL 用户和密码只在空 volume 首次初始化时生效。
- IoTDB 问题主要影响分析页,MySQL 问题会影响商品、订单、登录等核心接口。
- 2G ECS 必须关注内存和 swap,否则 MySQL、IoTDB 容易反复重启。