LotDB Vue 阿里云 ECS 部署实战记录

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:SSH
  • 80/tcp:HTTP
  • 443/tcp:HTTPS

不要开放:

  • 3000/tcp
  • 3306/tcp
  • 6667/tcp
  • 18080/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_USERMYSQL_PASSWORD 等变量。已经初始化过的数据卷不会因为修改 .env.prod 自动重建用户。

5. Docker Compose 端口设置

服务器已有宿主机 Nginx 时,容器不要直接占用 80443

推荐使用 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

如果 mysqliotdbSTATUS 类似 Up 4 secondsUp 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_USERMYSQL_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 容易反复重启。
相关推荐
卷无止境1 小时前
SimPy 进程通信:让仿真世界里的"对话"变得优雅
后端
ZengLiangYi1 小时前
多格式文件解析:JSONL / SQLite / Event Stream
前端·javascript·后端
前端市界1 小时前
使用 `acme.sh` + 阿里云 DNS API 申请 Let’s Encrypt 通配符证书,并配置 Nginx 自动续期
后端
卷无止境1 小时前
SimPy Events 深度解析:仿真世界的时间引擎
后端
Oo_行者_oO1 小时前
Spring Cloud 实现文件服务预览与静态资源映射
后端·spring
万少1 小时前
湖南卫视的秘密武器曝光!芒果灵创,专业AI影视创作平台
前端·javascript·后端
金銀銅鐵1 小时前
[Java] 自己写程序,来解析方法的 descriptor
java·后端
Yang96111 小时前
0.5 米超短盲区!鼎讯信通 GO-50PRO 光时域反射仪科普
开发语言·后端·golang
一个做软件开发的牛马2 小时前
Java 继承与多态:从"是什么"到"能做什么"的设计思维
java·后端