242 lines
6.0 KiB
Markdown
242 lines
6.0 KiB
Markdown
|
|
# Docker 部署说明
|
|||
|
|
|
|||
|
|
## 项目概述
|
|||
|
|
|
|||
|
|
基于 Next.js 15 的 AI 智能体门户系统,使用 Prisma + SQLite 作为数据存储,采用 `output: 'standalone'` 模式构建自包含的生产镜像。
|
|||
|
|
|
|||
|
|
## 前置要求
|
|||
|
|
|
|||
|
|
- Docker >= 20.10
|
|||
|
|
- Docker Compose >= 2.0(可选,推荐使用)
|
|||
|
|
|
|||
|
|
## 目录结构说明
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
├── Dockerfile # 多阶段构建(3 阶段)
|
|||
|
|
├── docker-compose.yml # 编排配置
|
|||
|
|
├── .dockerignore # 构建上下文排除
|
|||
|
|
├── .env # 环境变量(仅开发参考)
|
|||
|
|
└── prisma/
|
|||
|
|
├── schema.prisma # 数据库模型
|
|||
|
|
├── seed.ts # 种子数据脚本
|
|||
|
|
└── migrations/ # 数据库迁移文件
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 环境变量
|
|||
|
|
|
|||
|
|
| 变量名 | 说明 | 示例值 |
|
|||
|
|
|--------|------|--------|
|
|||
|
|
| `DATABASE_URL` | SQLite 数据库文件路径 | `file:/app/data/dev.db` |
|
|||
|
|
| `NEXTAUTH_SECRET` | NextAuth JWT 加密密钥 | `your-secret-key` |
|
|||
|
|
| `NEXTAUTH_URL` | 应用公网访问地址 | `http://your-domain.com` |
|
|||
|
|
|
|||
|
|
> **注意**:生产环境请使用强随机字符串替换 `NEXTAUTH_SECRET`,可通过 `openssl rand -base64 32` 生成。
|
|||
|
|
|
|||
|
|
## 快速启动
|
|||
|
|
|
|||
|
|
### 方式一:使用 docker-compose(推荐)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 1. 创建数据持久化目录
|
|||
|
|
sudo mkdir -p /opt/nextapp/data
|
|||
|
|
|
|||
|
|
# 2. 启动服务
|
|||
|
|
docker-compose up -d
|
|||
|
|
|
|||
|
|
# 3. 查看日志
|
|||
|
|
docker-compose logs -f
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方式二:手动 docker 命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 1. 构建镜像
|
|||
|
|
docker build -t nextapp .
|
|||
|
|
|
|||
|
|
# 2. 创建数据目录
|
|||
|
|
mkdir -p /opt/nextapp/data
|
|||
|
|
|
|||
|
|
# 3. 运行容器
|
|||
|
|
docker run -d \
|
|||
|
|
--name nextapp \
|
|||
|
|
-p 3000:3000 \
|
|||
|
|
-e DATABASE_URL=file:/app/data/dev.db \
|
|||
|
|
-e NEXTAUTH_SECRET=your-secret-key \
|
|||
|
|
-e NEXTAUTH_URL=http://localhost:3000 \
|
|||
|
|
-v /opt/nextapp/data/dev.db:/app/data/dev.db \
|
|||
|
|
--restart unless-stopped \
|
|||
|
|
nextapp
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方式三:使用 Docker Compose 带数据库初始化
|
|||
|
|
|
|||
|
|
若需在首次启动时自动执行数据库迁移和种子数据初始化,可使用如下 `docker-compose.yml`:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
version: '3.8'
|
|||
|
|
services:
|
|||
|
|
nextapp:
|
|||
|
|
build: .
|
|||
|
|
ports:
|
|||
|
|
- "3000:3000"
|
|||
|
|
environment:
|
|||
|
|
- DATABASE_URL=file:/app/data/dev.db
|
|||
|
|
- NEXTAUTH_SECRET=your-secret-key
|
|||
|
|
- NEXTAUTH_URL=http://localhost:3000
|
|||
|
|
volumes:
|
|||
|
|
- /opt/nextapp/data:/app/data
|
|||
|
|
command: >
|
|||
|
|
sh -c "npx prisma migrate deploy && npx prisma db seed && node server.js"
|
|||
|
|
restart: unless-stopped
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Dockerfile 多阶段构建详解
|
|||
|
|
|
|||
|
|
| 阶段 | 基础镜像 | 作用 |
|
|||
|
|
|------|----------|------|
|
|||
|
|
| `base` | `node:20-alpine` | 基础环境,设置工作目录 |
|
|||
|
|
| `deps` | `base` | 安装全部 npm 依赖(含 devDependencies) |
|
|||
|
|
| `builder` | `base` | 生成 Prisma Client + `next build` |
|
|||
|
|
| `runner` | `base` | 最小运行时:仅复制 standalone 产物、静态文件、prisma schema,创建非 root 用户 |
|
|||
|
|
|
|||
|
|
构建产出:`.next/standalone/` 目录下的自包含 Node.js 服务器(`server.js`),无需 `next start`。
|
|||
|
|
|
|||
|
|
## 数据库管理
|
|||
|
|
|
|||
|
|
### 手动执行迁移
|
|||
|
|
|
|||
|
|
若容器已运行,需手动执行数据库迁移:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker exec -it nextapp sh -c "npx prisma migrate deploy"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 手动执行种子数据
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker exec -it nextapp sh -c "npx prisma db seed"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
初始化后可使用以下默认账号登录管理后台:
|
|||
|
|
- 地址:`http://localhost:3000/admin/login`
|
|||
|
|
- 用户名:`admin`
|
|||
|
|
- 密码:`admin123`
|
|||
|
|
|
|||
|
|
### 数据持久化
|
|||
|
|
|
|||
|
|
SQLite 数据库文件通过 volume 挂载到宿主机,路径为 `/opt/nextapp/data/dev.db`。建议定期备份此文件:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cp /opt/nextapp/data/dev.db /opt/nextapp/data/backup-$(date +%Y%m%d).db
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 生产部署建议
|
|||
|
|
|
|||
|
|
### 反向代理(Nginx)
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
server {
|
|||
|
|
listen 80;
|
|||
|
|
server_name your-domain.com;
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
proxy_pass http://127.0.0.1:3000;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
proxy_set_header Upgrade $http_upgrade;
|
|||
|
|
proxy_set_header Connection 'upgrade';
|
|||
|
|
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_cache_bypass $http_upgrade;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
使用 HTTPS(推荐使用 certbot / acme.sh 自动申请证书):
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
server {
|
|||
|
|
listen 443 ssl;
|
|||
|
|
server_name your-domain.com;
|
|||
|
|
|
|||
|
|
ssl_certificate /path/to/cert.pem;
|
|||
|
|
ssl_certificate_key /path/to/key.pem;
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
proxy_pass http://127.0.0.1:3000;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
proxy_set_header Upgrade $http_upgrade;
|
|||
|
|
proxy_set_header Connection 'upgrade';
|
|||
|
|
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_cache_bypass $http_upgrade;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 更新部署
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 拉取最新代码
|
|||
|
|
git pull
|
|||
|
|
|
|||
|
|
# 重新构建并启动
|
|||
|
|
docker-compose down
|
|||
|
|
docker-compose up -d --build
|
|||
|
|
|
|||
|
|
# 执行数据库迁移(如有 schema 变更)
|
|||
|
|
docker exec -it nextapp sh -c "npx prisma migrate deploy"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 查看日志
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 实时日志
|
|||
|
|
docker-compose logs -f
|
|||
|
|
|
|||
|
|
# 最近 100 行
|
|||
|
|
docker-compose logs --tail=100
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### 1. 数据库文件权限问题
|
|||
|
|
|
|||
|
|
确保宿主机上的数据目录对容器内 `nextjs` 用户(UID 1001)可写:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo chown -R 1001:1001 /opt/nextapp/data
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 端口冲突
|
|||
|
|
|
|||
|
|
修改 `docker-compose.yml` 中的宿主机端口映射:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
ports:
|
|||
|
|
- "8080:3000" # 将宿主机 8080 映射到容器 3000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 构建性能
|
|||
|
|
|
|||
|
|
首次构建较慢,可配置 Docker BuildKit 加速:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
export DOCKER_BUILDKIT=1
|
|||
|
|
docker-compose build
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. NEXTAUTH_URL 配置错误
|
|||
|
|
|
|||
|
|
若通过反向代理访问,`NEXTAUTH_URL` 需设置为公网可访问的地址(含 https),否则 NextAuth 回调会失败。
|
|||
|
|
|
|||
|
|
## 镜像优化说明
|
|||
|
|
|
|||
|
|
- 使用 `node:20-alpine` 作为基础镜像(约 120MB)
|
|||
|
|
- 采用多阶段构建,最终运行时镜像仅包含必要产物
|
|||
|
|
- `output: 'standalone'` 模式将应用代码打包为单文件 `server.js`
|
|||
|
|
- 运行阶段使用非 root 用户 `nextjs`,提升安全性
|