TodoList Docker 部署文档

适用环境:阿里云 ECS(全新服务器) + Docker Compose
架构:Nginx(80) → 静态前端 + /api 代理 → Spring Boot(8080) → MySQL(3306)
更新时间:2026-06-30


一、前置信息

项目
部署目录 /opt/todolist/
MySQL 密码 12345678
数据库名 todo_db
后端端口 8080(内部)
前端端口 80(对外)
Java 版本 17
Spring Boot 3.3.4

二、ECS 环境初始化

以下所有命令在 ECS 上以 root 身份执行。

2.1 连接 ECS

ssh root@<你的ECS公网IP>

2.2 安装 Docker

# 官方一键脚本(使用阿里云镜像加速)
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

# 启动并设置开机自启
systemctl enable docker
systemctl start docker

# 验证版本
docker --version
docker compose version

预期输出:Docker 26.x+,Docker Compose v2.x+

2.3 配置 Docker 镜像加速(可选但建议)

mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": [
    "https://mirror.ccs.tencentyun.com",
    "https://docker.m.daocloud.io"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  }
}
EOF

systemctl daemon-reload
systemctl restart docker

2.4 关闭防火墙/SELinux(ECS 默认已关闭,确认即可)

systemctl status firewalld   # 应该是 inactive
sestatus                     # 应该是 Disabled

三、上传部署包

方式一:压缩上传(推荐)

本地 Windows 桌面打开终端,进入部署文件夹后打包上传:

# 进入桌面部署文件夹
cd C:/Users/ASUS/Desktop/TodoList-Deploy

# 打包为 tar.gz
tar -czf todolist-deploy.tar.gz *

# 上传到 ECS
scp todolist-deploy.tar.gz root@<ECS公网IP>:/opt/

然后在 ECS 上解压:

mkdir -p /opt/todolist
cd /opt/todolist
tar -xzf /opt/todolist-deploy.tar.gz
rm /opt/todolist-deploy.tar.gz

方式二:直接 scp 整个文件夹

scp -r C:/Users/ASUS/Desktop/TodoList-Deploy/* root@<ECS公网IP>:/opt/todolist/

四、开始部署

4.1 给脚本执行权限

cd /opt/todolist
chmod +x deploy.sh

4.2 构建并启动(二选一)

自动部署:

./deploy.sh

手动部署:

cd /opt/todolist

# 1. 构建后端镜像
docker compose build

# 2. 启动所有服务(后台运行)
docker compose up -d

# 3. 查看启动状态
docker compose ps

# 4. 查看日志(Ctrl+C 退出)
docker compose logs -f

4.3 启动顺序说明

MySQL 启动(约15秒)
    ↓ 健康检查通过
后端启动(约30秒-60秒,首次需等 MySQL 建表)
    ↓ 容器启动
Nginx 启动
    ↓
全栈可用 ✅

五、配置阿里云安全组

关键步骤! 否则外网无法访问。

  1. 登录 阿里云控制台
  2. 进入 ECS → 实例 → 点击你的实例 → 安全组
  3. 点击 配置规则 → 入方向 → 手动添加
优先级 协议类型 端口范围 授权对象 说明
1 TCP 80 0.0.0.0/0 HTTP 前端页面
1 TCP 22 0.0.0.0/0 SSH 远程管理

⚠️ 不要开放 3306、8080、8081,这些端口仅在 Docker 内网通信。


六、验证部署

6.1 浏览器访问

http://<ECS公网IP>

应能看到 TodoList 登录/注册页面。

6.2 命令行测试 API

# 测试 Nginx 可达
curl http://localhost/

# 测试 API 代理
curl http://localhost/api/dict/priorities

# 预期返回 JSON 格式的优先级字典

6.3 检查容器状态

docker compose ps

预期输出 3 个容器均为 UpUp (healthy)

容器名 状态
todo-mysql Up (healthy)
todo-backend Up (healthy)
todo-nginx Up

6.4 检查后端日志

docker compose logs backend | tail -50

看到 Started TodoBackendApplication in X.XXX seconds 即启动成功。


七、文件结构

/opt/todolist/
├── deploy.sh                    # 一键部署脚本
├── docker-compose.yml           # 服务编排配置
├── Dockerfile.backend           # 后端镜像构建文件
├── .dockerignore                # 构建排除
├── backend/
│   └── target/
│       └── todo-backend.jar     # Spring Boot JAR(29MB)
├── frontend/
│   └── dist/                    # Vue 前端构建产物
│       ├── index.html
│       └── assets/
├── nginx/
│   └── nginx.conf               # Nginx 反向代理 + 静态文件配置
└── mysql/
    └── init/
        └── 01-init.sql          # 数据库建表 + 预置字典数据

八、常用运维命令

# 查看所有容器状态
docker compose ps

# 查看实时日志
docker compose logs -f

# 只查看某个服务日志
docker compose logs -f backend
docker compose logs -f nginx

# 重启某个服务
docker compose restart backend

# 重新构建并启动(代码更新后)
docker compose up -d --build

# 停止所有服务
docker compose down

# 停止 + 删除数据库数据(⚠️ 会清空所有用户数据!)
docker compose down -v

# 进入容器调试
docker compose exec backend sh
docker compose exec mysql1 mysql -uroot -p12345678 todo_db

九、更新部署

当本地代码修改后,重新部署的流程:

# 1. 本地重新打包
#    后端:cd backend && ./mvnw clean package -DskipTests
#    前端:cd frontend && npm run build

# 2. 上传更新文件
scp backend/target/todo-backend.jar root@<IP>:/opt/todolist/backend/target/
scp -r frontend/dist/* root@<IP>:/opt/todolist/frontend/dist/

# 3. ECS 上重新构建后端 + 重启
ssh root@<IP> "cd /opt/todolist && docker compose up -d --build"

只改前端:只需上传 frontend/dist/,Nginx 无需重启(文件挂载实时生效)。
只改后端:上传 JAR 后执行 docker compose up -d --build backend
改了 nginx 配置:上传 nginx/nginx.conf 后执行 docker compose restart nginx


十、故障排查

10.1 浏览器访问不了

  1. 确认安全组:80 端口是否已开放入方向
  2. 确认服务运行中docker compose ps 查看状态
  3. 确认 Nginx 监听docker compose exec nginx netstat -tlnp | grep 80

10.2 后端启动失败

# 查看详细日志
docker compose logs backend

# 常见原因:
# 1. MySQL 还没就绪 → 等 MySQL healty 后 docker compose restart backend
# 2. 数据库表不存在 → 检查 mysql/init/01-init.sql 是否正确执行
# 3. 端口被占用 → lsof -i :8080

10.3 MySQL 连接失败

# 进入 MySQL 检查
docker compose exec mysql1 mysql -uroot -p12345678

# 查看数据库
SHOW DATABASES;
USE todo_db;
SHOW TABLES;

10.4 API 返回 502

# 检查后端是否在运行
docker compose ps backend

# 检查 Nginx 能否连通后端
docker compose exec nginx wget -qO- http://backend:8080/api/actuator/health 2>&1 || echo "后端不可达"

10.5 端口冲突

如果 ECS 上已有 Nginx/Apache 占用 80 端口:

# 查看是谁占用
lsof -i :80

# 如果不需要就停掉
systemctl stop nginx    # 或 httpd / apache2
systemctl disable nginx

十一、安全加固建议

  • 修改 JWT 密钥:生成随机密钥替换 docker-compose.yml 中的 JWT_SECRETopenssl rand -base64 32
  • 更换 API Key:将 AI_DEEPSEEK_API_KEY 换成你自己的 DeepSeek Key
  • 修改 MySQL 密码:使用强密码,同步修改 MYSQL_ROOT_PASSWORDSPRING_DATASOURCE_PASSWORD
  • 配置 HTTPS:使用 acme.sh + 阿里云 DNS API 申请免费 SSL 证书
  • 最小化安全组:SSH 端口限制只允许你的 IP 访问
  • Spring Boot 生产模式:确认 app.debug: false@TOC

更多推荐