# Nunu 高级布局项目部署指南

本文档提供在宝塔Linux服务器上部署此Go项目的详细步骤。项目支持同时部署API服务和Task任务服务。

## 方法一：使用Docker部署（推荐）

从项目结构和Dockerfile看，项目已经准备好了Docker化部署，这是最简单的方式：

### 1. 在宝塔面板安装Docker管理器
- 登录宝塔面板
- 在软件商店中搜索并安装"Docker管理器"插件

### 2. 上传项目到服务器
- 通过SFTP或Git将项目上传到服务器
- 例如：`git clone 您的仓库地址 /www/wwwroot/go_project`

### 3. 构建Docker镜像
- 通过SSH连接到服务器
- 进入项目目录：`cd /www/wwwroot/go_project`
- 执行构建命令：
  ```bash
  docker build -t go-app:v1 -f deploy/build/Dockerfile .
  
 // docker build -t go-app:v1 --build-arg APP_RELATIVE_PATH=./cmd/server/... -f deploy/build/Dockerfile .
  ```

### 4. 使用优化部署脚本

项目提供了优化的部署脚本，支持同时部署API服务和Task任务服务，并且可以显著提高构建速度：

```bash
# 将脚本权限设置为可执行
chmod +x deploy/deploy.sh

# 默认部署全部服务（API和Task）
./deploy/deploy.sh

# 只部署API服务
./deploy/deploy.sh --api

# 只部署Task服务
./deploy/deploy.sh --task

# 强制重新创建容器
./deploy/deploy.sh --force

# 不使用Docker缓存构建
./deploy/deploy.sh --no-cache
```

脚本会自动：
1. 创建必要的目录结构
2. 利用Docker卷缓存Go模块以加快构建速度
3. 挂载配置和日志目录
4. 仅在需要时重新创建容器

### 5. 手动运行Docker容器
如果您想手动管理容器，可以使用以下命令：

```bash
# API服务
docker run -d --restart=always --name nunu-api -p 8000:8000 -v /www/wwwroot/nunu/storage:/data/app/storage -v /www/wwwroot/nunu/config:/data/app/config nunu-api:v1

# Task服务
docker run -d --restart=always --name nunu-task -v /www/wwwroot/nunu/storage:/data/app/storage -v /www/wwwroot/nunu/config:/data/app/config nunu-task:v1
```

### 6. Docker容器管理命令

```bash
# 停止容器
docker stop go-app

# 启动已停止的容器
docker start go-app

# 重启容器
docker restart go-app

# 查看容器日志
docker logs go-app

# 查看正在运行的容器
docker ps

# 查看所有容器（包括已停止的）
docker ps -a

# 删除容器（需要先停止）
docker rm go-app
```

### 7. 配置反向代理（可选）
- 在宝塔面板中添加站点
- 设置反向代理到 `http://127.0.0.1:8000`

## 方法二：直接部署Go应用

如果不想使用Docker，也可以直接在服务器上编译运行：

### 1. 安装Go环境
- 在宝塔面板中通过"软件管理"安装"Go语言"
- 或通过SSH手动安装：
  ```bash
  wget https://golang.org/dl/go1.19.linux-amd64.tar.gz
  tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
  echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
  source ~/.profile
  ```

### 2. 上传并编译项目
```bash
mkdir -p /www/wwwroot/go_project
cd /www/wwwroot/go_project
# 上传您的代码到这个目录
export GOPROXY=https://goproxy.cn,direct
go mod tidy
go build -o bin/server ./cmd/server/...
cp -r config bin/
```

### 3. 创建服务
创建systemd服务文件以便管理应用：
```bash
cat > /etc/systemd/system/go-app.service << EOF
[Unit]
Description=Go Application Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/www/wwwroot/go_project/bin
ExecStart=/www/wwwroot/go_project/bin/server
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable go-app
systemctl start go-app
```

### 4. 配置反向代理
- 在宝塔面板中添加站点
- 设置反向代理到 `http://127.0.0.1:8000`

## 重要提示

1. 确保服务器防火墙开放了8000端口，或者您配置的其他端口
2. 如果使用Docker部署，请确保配置文件路径正确
3. 生产环境中，建议配置SSL证书以启用HTTPS
4. 您可能需要调整配置文件中的数据库连接信息等配置

## 部署问题解决

### 1. Go版本不匹配问题

如果在构建Docker镜像时遇到如下错误：

```
invalid go version '1.23.0': must match format 1.23
unknown directive: toolchain
```

或者：

```
go: go.mod requires go >= 1.23.0 (running go 1.22.12; GOTOOLCHAIN=local)
```

这是因为Dockerfile使用的Go版本与go.mod中声明的版本不匹配。有两种解决方案：

#### 方案一：更新Dockerfile中的Go版本

修改`deploy/build/Dockerfile`文件，将：
```dockerfile
FROM ${REGISTRY}/golang:1.19-alpine AS builder
```
更改为：
```dockerfile
FROM ${REGISTRY}/golang:1.24-alpine AS builder
```

#### 方案二：修改go.mod文件

如果无法更新Docker环境中的Go版本，可以修改go.mod文件：

1. 将`go 1.23.0`更改为`go 1.19`
2. 删除`toolchain go1.24.1`行

### 2. 多包编译问题

如果遇到这样的错误：

```
go: cannot write multiple packages to non-directory ./bin/server
```
或
```
go: cannot write multiple packages to non-directory ./bin/server/main
```
或
```
go: cannot write multiple packages to non-directory ./bin/app
```

这是因为`./cmd/server/...`路径下包含了多个包（main包和wire包），但编译命令在尝试将它们编译到一个单一文件。

需要修改Dockerfile中的以下内容：

1. 将：
```dockerfile
RUN rm -rf /data/app/bin/
RUN export GOPROXY=https://goproxy.cn,direct && go mod tidy && go build -ldflags="-s -w" -o ./bin/server ${APP_RELATIVE_PATH}
```

更改为（指定具体的main.go文件而不是整个目录）：
```dockerfile
RUN mkdir -p /data/app/bin/
RUN export GOPROXY=https://goproxy.cn,direct && go mod tidy && go build -ldflags="-s -w" -o ./bin/app ./cmd/server/main.go
```

2. 同时需要更新ENTRYPOINT：
```dockerfile
ENTRYPOINT [ "./server" ]
```

更改为：
```dockerfile
ENTRYPOINT [ "./app" ]
```

这种方法的关键是直接指定main.go文件而不是使用通配符，这样就只编译单个入口文件，避免了多包编译问题。

## 验证部署
部署完成后，您可以通过以下方式验证服务是否正常运行：

1. 访问 `http://您的服务器IP:8000` 检查API是否正常响应
2. 访问 `http://您的服务器IP:8000/swagger/index.html` 查看API文档

## 故障排除

如遇到问题，请检查：

1. 日志信息：`docker logs go-app` 或 `journalctl -u go-app`
2. 配置文件是否正确
3. 数据库连接是否正常
4. 防火墙规则是否允许访问相关端口
