Files
ocdp-go/backend/docs/deployment.md
mangomqy c5e51ed069 ocdp v1
2025-11-13 02:54:06 +00:00

1547 lines
33 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🚀 部署文档
## 目录
- [快速开始](#快速开始)
- [2.4.1 Mock 模式](#241-mock-模式)
- [2.4.2 Dev 模式](#242-dev-模式)
- [2.4.3 Up 模式](#243-up-模式)
- [环境变量配置](#环境变量配置)
- [故障排查](#故障排查)
---
## 快速开始
### 三种部署模式
| 模式 | 命令 | Backend | 数据库 | 热重载 | 适用场景 |
|------|------|---------|--------|--------|----------|
| **Mock** | `make mock` | 本地 | 内存 | ✅ | 快速开发、API 测试 |
| **Dev** | `make db-up`<br>`make dev` | 本地 | Docker | ✅ | 日常开发 ⭐ 推荐 |
| **Up** | `make up` | Docker | Docker | ❌ | 集成测试、生产预演 |
### 使用 Makefile
```bash
# 查看所有命令
make help
# Mock 模式(零依赖,最快启动)
make mock
# Dev 模式(推荐日常开发)
make db-up # 启动数据库
make dev # 启动 Backend热重载
# Up 模式(完全容器化)
make up
# 管理服务
make logs # 查看日志
make stop # 停止服务
```
### 验证服务
```bash
# 健康检查
curl http://localhost:8080/health
# 测试 API
curl http://localhost:8080/api/v1/registries | jq
# 访问 Swagger UI
open http://localhost:8080/api/docs
```
---
# 2.4.1 Mock 模式
## 概述
Mock 模式使用内存存储,无需任何外部依赖,适合快速开发和测试。
**特点**:
-**零依赖** - 无需数据库、Docker 等
-**快速启动** - 3 秒内启动
-**热重载** - 支持 Air 自动重载
-**自带测试数据** - Bootstrap 预注入
-**无需容器** - 本地直接运行
-**数据不持久** - 重启后数据丢失
**适用场景**:
- 🚀 快速功能开发
- 🧪 API 接口测试
- 🎨 前端开发联调
- 📝 编写单元测试
**架构**:
```
┌─────────────────────────────────────────┐
│ Mock 模式(本地直接运行) │
│ │
│ ┌──────────────────────────────────┐ │
│ │ OCDP Backend (Go Process) │ │
│ │ Port: 8080 │ │
│ │ │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ Air (Hot Reload) │ │ │
│ │ │ 监听文件变化自动重载 │ │ │
│ │ └─────────────────────────┘ │ │
│ │ │ │
│ │ Adapter: Mock │ │
│ │ Storage: Memory │ │
│ └──────────────────────────────────┘ │
│ │
│ 无外部依赖 ✨ │
└─────────────────────────────────────────┘
```
---
## 环境准备
```bash
# 1. 确保已安装 Go
go version # 需要 Go 1.21+
# 2. 安装 Air热重载工具
go install github.com/air-verse/air@latest
# 3. 验证安装
air -v
```
---
## 运行方式
### 方式 1: 使用 Makefile推荐
```bash
make mock
```
### 方式 2: 使用 Air
```bash
# 1. 设置环境变量
export ADAPTER_MODE=mock
export PORT=8080
export JWT_SECRET=dev-secret-key
# 2. 启动 Air
air -c .air.toml
# 输出示例:
# __ _ ___
# / /\ | | | |_)
# /_/--\ |_| |_| \_ v1.49.0
#
# watching .
# building...
# running...
# 🚀 Starting OCDP Backend (mode=mock)
# 🌐 Server starting on :8080
```
### 方式 3: 直接运行 Go
```bash
# 设置环境变量
export ADAPTER_MODE=mock
export PORT=8080
export JWT_SECRET=dev-secret-key
# 运行
go run cmd/api/main.go
```
---
## 热重载演示
修改任何 `.go` 文件后Air 会自动检测并重启:
```
main.go has changed
building...
running...
🚀 Starting OCDP Backend (mode=mock)
🌐 Server starting on :8080
```
**支持的文件类型**:
- `.go` - Go 源文件
- `.yaml`, `.json` - 配置文件
- `.toml` - Air 配置文件
---
## 配置文件
Air 配置文件 `.air.toml` 已包含在项目中:
```toml
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
cmd = "go build -o ./tmp/main cmd/api/main.go"
bin = "./tmp/main"
include_ext = ["go", "tpl", "tmpl", "html", "yaml", "json"]
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_regex = ["_test.go"]
delay = 1000
```
---
## 测试数据
Mock 模式自动加载 `config/bootstrap.json` 中的测试数据:
```json
{
"enabled": true,
"users": [
{
"username": "admin",
"password": "admin123",
"email": "admin@example.com"
}
],
"registries": [
{
"name": "Harbor Production",
"url": "https://harbor.example.com",
"username": "admin",
"password": "secret"
}
],
"clusters": [
{
"name": "Production Cluster",
"host": "https://k8s.example.com:6443",
"description": "生产环境集群"
}
]
}
```
---
## 测试 API
```bash
# 登录
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}' | jq
# 响应:
# {
# "accessToken": "eyJhbGciOiJIUzI1NiIs...",
# "userId": "user-123",
# "username": "admin"
# }
# 查看 Registries
curl http://localhost:8080/api/v1/registries | jq
# 查看 Clusters
curl http://localhost:8080/api/v1/clusters | jq
```
---
## 环境变量
| 变量 | 说明 | 默认值 | 必需 |
|------|------|--------|------|
| `ADAPTER_MODE` | 适配器模式 | `mock` | ✅ |
| `PORT` | 服务端口 | `8080` | ❌ |
| `JWT_SECRET` | JWT 密钥 | - | ✅ |
---
## 优势与限制
### ✅ 优势
1. **启动极快** - 3 秒内启动,无需等待数据库
2. **零配置** - 无需配置数据库连接、证书等
3. **自带数据** - Bootstrap 自动注入测试数据
4. **热重载** - 代码修改立即生效
5. **易于调试** - 本地运行,支持 IDE 断点调试
6. **完美测试** - 适合 API 测试和前端联调
### ❌ 限制
1. **数据不持久** - 重启后数据丢失
2. **功能简化** - 某些功能(如真实 K8s 操作)被模拟
3. **不适合生产** - 仅用于开发调试
---
# 2.4.2 Dev 模式
## 概述
Dev 模式使用 Docker 运行 PostgreSQL 数据库Backend 在本地热重载运行,适合日常开发。
**特点**:
-**隔离的依赖服务** - 数据库在容器中,避免污染本地环境
-**本地热重载** - Backend 支持 Air 自动重载
-**完整的 IDE 支持** - 断点调试、代码补全、性能分析
-**快速迭代** - 代码修改立即生效,无需重新构建镜像
-**数据持久化** - PostgreSQL 数据持久保存
-**最佳开发体验** - 兼顾隔离性和开发效率
**适用场景**:
- 📝 **日常功能开发** ⭐ 最推荐
- 🐛 **代码调试** - 支持 IDE 断点
- 🔄 **快速迭代** - 热重载提升效率
- 🧪 **数据持久化测试** - 验证数据库操作
**架构**:
```
┌──────────────────────────────────────────────────────────┐
│ Dev 模式(部分容器化,推荐日常开发) │
│ │
│ ┌────────────────────────┐ ┌────────────────────┐ │
│ │ OCDP Backend │ │ PostgreSQL │ │
│ │ (本地进程) │───▶│ (Docker 容器) │ │
│ │ Port: 8080 │ │ Port: 5432 │ │
│ │ │ │ │ │
│ │ ┌─────────────────┐ │ │ Volume: │ │
│ │ │ Air (Hot Reload) │ │ │ postgres_data │ │
│ │ └─────────────────┘ │ └────────────────────┘ │
│ └────────────────────────┘ │
│ │
│ Backend: 本地运行(热重载) │
│ Database: Docker 容器(隔离环境) │
└──────────────────────────────────────────────────────────┘
```
---
## 环境准备
```bash
# 1. 确保已安装 Docker 和 Docker Compose
docker --version
docker compose version
# 2. 安装 Air热重载工具
go install github.com/air-verse/air@latest
# 3. 验证安装
air -v
```
---
## 运行步骤
### 步骤 1: 启动数据库
```bash
# 使用 Makefile推荐
make db-up
# 或手动启动
docker compose up -d postgres
# 等待数据库启动(查看健康状态)
docker compose ps
# 预期输出:
# NAME IMAGE STATUS PORTS
# ocdp-postgres postgres:17-alpine Up 10s (healthy) 0.0.0.0:5432->5432/tcp
```
**验证数据库连接**:
```bash
# 方式 1: 使用 psql
psql -h localhost -U postgres -d ocdp
# 方式 2: 使用 Docker
docker exec -it ocdp-postgres psql -U postgres -d ocdp
# 测试查询
SELECT current_database();
\q
```
---
### 步骤 2: 启动 Backend热重载
**选项 A: 使用 Makefile推荐**
```bash
# 设置环境变量(首次)
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable"
export ENCRYPTION_KEY="12345678901234567890123456789012"
# 启动 Backend
make dev
# 输出:
# 🚀 启动 Dev 模式 - Backend本地热重载...
# 🔌 Connecting to database...
# ✅ Database connected
# 🌱 Bootstrap seeding...
# 🌐 Server starting on :8080
```
**选项 B: 使用 Air**
```bash
# 设置环境变量
export ADAPTER_MODE=production
export PORT=8080
export JWT_SECRET=dev-secret-key
export ENCRYPTION_KEY=12345678901234567890123456789012
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable"
# 启动 Air
air -c .air.toml
```
**选项 C: 直接运行 Go**
```bash
export ADAPTER_MODE=production
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable"
export JWT_SECRET=dev-secret-key
export ENCRYPTION_KEY=12345678901234567890123456789012
go run cmd/api/main.go
```
---
## 验证服务
```bash
# 健康检查
curl http://localhost:8080/health
# 输出: {"status":"healthy"}
# 注册用户
curl -X POST http://localhost:8080/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"password": "test123",
"email": "test@example.com"
}'
# 登录
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"password": "test123"
}' | jq
```
---
## 热重载演示
修改代码后Air 会自动检测并重启:
```bash
# 终端 1: Air 运行中
# 修改文件: internal/domain/service/cluster_service.go
# Air 输出:
# cluster_service.go has changed
# building...
# running...
# 🚀 Starting OCDP Backend (mode=production)
# 🔌 Connecting to database...
# ✅ Database connected
# 🌐 Server starting on :8080
# 终端 2: 测试
curl http://localhost:8080/api/v1/clusters | jq
```
---
## 开发工作流
```bash
# 1. 启动数据库(首次或停止后)
make db-up
# 2. 启动 Backend热重载
make dev
# 3. 修改代码
vim internal/domain/service/cluster_service.go
# Air 自动检测并重启
# 4. 测试 API
curl http://localhost:8080/api/v1/clusters | jq
# 5. 查看数据库
make db
SELECT * FROM users;
\q
# 6. 停止服务
# - Backend: Ctrl+C
# - Database: make stop
```
---
## 管理服务
**查看服务状态**:
```bash
# 查看所有容器
docker compose ps
# 查看 PostgreSQL 日志
docker compose logs -f postgres
# 查看 Backend 日志(在 Air 终端中)
```
**停止服务**:
```bash
# 停止 Backend: 在 Air 终端按 Ctrl+C
# 停止数据库
docker compose stop postgres
# 停止并删除容器(数据保留)
docker compose down
# 停止并删除容器和数据卷(⚠️ 数据丢失)
docker compose down -v
```
**重启服务**:
```bash
# 重启数据库
docker compose restart postgres
# 重启 Backend: 在 Air 终端按 Ctrl+C 后重新运行 make dev
```
---
## 数据库管理
**连接数据库**:
```bash
# 使用 Makefile
make db
# 使用 psql
psql -h localhost -U postgres -d ocdp
# 或使用 Docker
docker exec -it ocdp-postgres psql -U postgres -d ocdp
```
**常用查询**:
```sql
-- 查看所有表
\dt
-- 查看用户
SELECT id, username, email, created_at FROM users;
-- 查看 Registry
SELECT id, name, url, created_at FROM registries;
-- 查看集群
SELECT id, name, host, created_at FROM clusters;
-- 清空测试数据
TRUNCATE users, registries, clusters, instances CASCADE;
-- 退出
\q
```
**数据库备份与恢复**:
```bash
# 备份
docker exec ocdp-postgres pg_dump -U postgres ocdp > backup-$(date +%Y%m%d).sql
# 恢复
docker exec -i ocdp-postgres psql -U postgres ocdp < backup.sql
# 压缩备份
docker exec ocdp-postgres pg_dump -U postgres ocdp | gzip > backup.sql.gz
# 从压缩文件恢复
gunzip -c backup.sql.gz | docker exec -i ocdp-postgres psql -U postgres ocdp
```
---
## IDE 调试配置
### VS Code (launch.json)
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch OCDP Backend (Dev Mode)",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/api/main.go",
"env": {
"ADAPTER_MODE": "production",
"PORT": "8080",
"JWT_SECRET": "dev-secret-key",
"ENCRYPTION_KEY": "12345678901234567890123456789012",
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable"
},
"args": []
}
]
}
```
### GoLand / IntelliJ IDEA
1. Run → Edit Configurations
2. Add New → Go Build
3. 配置:
- **Files**: `cmd/api/main.go`
- **Working directory**: 项目根目录
- **Environment**:
```
ADAPTER_MODE=production
PORT=8080
JWT_SECRET=dev-secret-key
ENCRYPTION_KEY=12345678901234567890123456789012
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable
```
---
## 环境变量
| 变量 | 说明 | 示例 | 必需 |
|------|------|------|------|
| `ADAPTER_MODE` | 适配器模式 | `production` | ✅ |
| `PORT` | 服务端口 | `8080` | ❌ |
| `JWT_SECRET` | JWT 密钥 | `dev-secret` | ✅ |
| `ENCRYPTION_KEY` | 加密密钥32字节 | `12345678901234567890123456789012` | ✅ |
| `DATABASE_URL` | 数据库连接 | `postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable` | ✅ |
**生成密钥**:
```bash
# JWT Secret
openssl rand -base64 32
# Encryption Key32 字节)
openssl rand -base64 32
```
---
## 故障排查
**问题 1: 数据库连接失败**
```bash
# 错误: connection refused
# 检查数据库是否启动
docker compose ps postgres
# 检查端口
netstat -tuln | grep 5432
# 或
lsof -i :5432
# 测试连接
psql -h localhost -U postgres -d ocdp -c "SELECT 1;"
```
**问题 2: 数据库未初始化**
```bash
# 重新初始化数据库
docker compose down postgres
docker compose up -d postgres
# 等待健康检查通过
docker compose ps postgres
```
**问题 3: 端口冲突**
```bash
# 修改 docker-compose.yml 中的端口映射
# ports:
# - "5433:5432" # 使用 5433 而不是 5432
# 更新 DATABASE_URL
export DATABASE_URL="postgresql://postgres:postgres@localhost:5433/ocdp?sslmode=disable"
```
---
# 2.4.3 Up 模式
## 概述
Up 模式使用 Docker Compose 完全容器化部署PostgreSQL 和 Backend 都在容器中运行。
**特点**:
- ✅ **完全容器化** - 一致的运行环境
- ✅ **一键部署** - 简单快速
- ✅ **接近生产** - 与生产环境高度一致
- ✅ **易于分享** - 团队成员快速启动相同环境
- ❌ **无热重载** - 代码修改需重新构建镜像
- ❌ **调试受限** - 需要通过日志调试
**适用场景**:
- 🧪 **集成测试** - 测试完整系统
- 🎯 **生产预演** - 验证部署流程
- 👥 **团队协作** - 快速搭建统一环境
- 📦 **交付演示** - 向客户展示系统
**架构**:
```
┌──────────────────────────────────────────────────────────┐
│ Up 模式(完全容器化) │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Docker Compose Network │ │
│ │ │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ │ │
│ │ │ OCDP Backend │ │ PostgreSQL │ │ │
│ │ │ (Docker 容器) │───▶│ (Docker 容器) │ │ │
│ │ │ Port: 8080 │ │ Port: 5432 │ │ │
│ │ └──────────────────┘ └──────────────────┘ │ │
│ │ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Persistent Volumes │ │
│ │ postgres_data: /var/lib/postgresql/data │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
```
---
## 环境准备
```bash
# 确保已安装 Docker 和 Docker Compose
docker --version
docker compose version
```
---
## 目录结构
```
backend/
├── docker-compose.yml # Docker Compose 配置
├── Dockerfile # Backend 镜像
├── .env # 环境变量
├── env.example # 环境变量示例
└── config/
└── bootstrap.json # 初始数据(可选)
```
---
## 部署步骤
### 步骤 1: 准备环境变量
```bash
# 复制示例文件
cp env.example .env
# 编辑环境变量
nano .env
```
**.env 文件内容**:
```bash
# 适配器模式
ADAPTER_MODE=production
# 端口配置
BACKEND_PORT=8080
POSTGRES_PORT=5432
# 安全密钥(⚠️ 生产环境必须修改)
JWT_SECRET=your-jwt-secret-change-in-production
ENCRYPTION_KEY=your-32-character-encryption-key-here
# 数据库配置
POSTGRES_DB=ocdp
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-postgres-password-change-it
# 数据库连接 URL容器内部使用
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable
```
**生成安全密钥**:
```bash
# 生成随机 JWT Secret
openssl rand -base64 32
# 生成随机 Encryption Key32 字节)
openssl rand -base64 32
# 生成随机数据库密码
openssl rand -base64 16
```
---
### 步骤 2: 启动服务
**使用 Makefile推荐**:
```bash
make up
# 查看服务状态
docker compose ps
# 预期输出:
# NAME IMAGE STATUS PORTS
# ocdp-backend backend:latest Up 30s (healthy) 0.0.0.0:8080->8080/tcp
# ocdp-postgres postgres:17-alpine Up 40s (healthy) 0.0.0.0:5432->5432/tcp
```
**手动启动**:
```bash
# 使用 profile 启动完整服务
docker compose --profile backend up -d
# 查看日志
docker compose logs -f backend postgres
```
---
### 步骤 3: 验证部署
```bash
# 健康检查
curl http://localhost:8080/health
# 输出: {"status":"healthy"}
# 测试 API
curl http://localhost:8080/api/v1/registries | jq
# 访问 Swagger UI
open http://localhost:8080/api/docs
# 查看容器状态
docker compose ps
# 进入 Backend 容器
docker compose exec backend sh
# 连接数据库
make db
```
---
## 管理服务
**停止服务**:
```bash
# 停止所有服务
make stop
# 或
docker compose down
# 停止并删除数据卷(⚠️ 会删除数据)
docker compose down -v
# 仅停止 Backend
docker compose stop backend
```
**重启服务**:
```bash
# 重启所有服务
make restart
# 或
docker compose restart
# 重启 Backend
docker compose restart backend
# 重启数据库
docker compose restart postgres
```
**查看日志**:
```bash
# 查看所有日志
make logs
# 或
docker compose logs -f
# 查看 Backend 日志
docker compose logs -f backend
# 查看最近 100 行
docker compose logs --tail=100 backend
```
---
## 重新构建镜像
**代码修改后需要重新构建**:
```bash
# 方式 1: 使用 Makefile
make up-build
# 方式 2: 手动构建
docker compose build backend
docker compose --profile backend up -d
# 方式 3: 强制重新构建(不使用缓存)
make up-rebuild
# 或
docker compose build --no-cache backend
docker compose --profile backend up -d
```
---
## 数据备份和恢复
```bash
# 备份数据库
docker compose exec postgres pg_dump -U postgres ocdp > backup-$(date +%Y%m%d).sql
# 恢复数据库
docker compose exec -T postgres psql -U postgres ocdp < backup.sql
# 导出为压缩文件
docker compose exec postgres pg_dump -U postgres ocdp | gzip > backup-$(date +%Y%m%d).sql.gz
# 从压缩文件恢复
gunzip -c backup.sql.gz | docker compose exec -T postgres psql -U postgres ocdp
```
---
## docker-compose.yml 配置
```yaml
version: '3.8'
services:
# PostgreSQL 数据库
postgres:
image: postgres:17-alpine
container_name: ocdp-postgres
environment:
- POSTGRES_DB=${POSTGRES_DB:-ocdp}
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
ports:
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ${INIT_DB_SQL_PATH:-./scripts/init-db.sql}:/docker-entrypoint-initdb.d/01-init.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-ocdp}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- ocdp-network
# Backend 服务(需要 --profile backend 才启动)
backend:
profiles: ["backend"]
build:
context: .
dockerfile: Dockerfile
container_name: ocdp-backend
ports:
- "${BACKEND_PORT:-8080}:8080"
environment:
- ADAPTER_MODE=${ADAPTER_MODE:-production}
- PORT=8080
- JWT_SECRET=${JWT_SECRET}
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
networks:
- ocdp-network
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
networks:
ocdp-network:
driver: bridge
volumes:
postgres_data:
driver: local
```
> 💡 **提示**
> 如果与仓库根目录下的 `docker-compose.yml` 联合使用(例如通过 `docker compose -f docker-compose.yml -f backend/docker-compose.yml --profile backend ...`),请确保设置环境变量 `INIT_DB_SQL_PATH=./backend/scripts/init-db.sql`(或绝对路径),以便 PostgreSQL 容器挂载到正确的初始化脚本。
---
## Dockerfile 配置
```dockerfile
# 多阶段构建,优化镜像大小
# 构建阶段
FROM golang:1.21-alpine AS builder
WORKDIR /app
# 复制依赖文件
COPY go.mod go.sum ./
RUN go mod download
# 复制源代码
COPY . .
# 编译(静态链接)
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w -s' -o ocdp-backend cmd/api/main.go
# 运行阶段
FROM alpine:latest
# 安装 CA 证书
RUN apk --no-cache add ca-certificates tzdata wget
# 设置时区
ENV TZ=Asia/Shanghai
WORKDIR /root/
# 复制二进制文件
COPY --from=builder /app/ocdp-backend .
# 复制配置文件(如果有)
COPY config/ config/
# 暴露端口
EXPOSE 8080
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
# 运行
CMD ["./ocdp-backend"]
```
---
## 环境变量
| 变量 | 说明 | 示例 | 必需 |
|------|------|------|------|
| `ADAPTER_MODE` | 适配器模式 | `production` | ✅ |
| `BACKEND_PORT` | Backend 端口 | `8080` | ❌ |
| `POSTGRES_PORT` | PostgreSQL 端口 | `5432` | ❌ |
| `JWT_SECRET` | JWT 密钥 | `随机字符串` | ✅ |
| `ENCRYPTION_KEY` | 加密密钥32字节 | `随机字符串` | ✅ |
| `POSTGRES_DB` | 数据库名 | `ocdp` | ✅ |
| `POSTGRES_USER` | 数据库用户 | `postgres` | ✅ |
| `POSTGRES_PASSWORD` | 数据库密码 | `随机字符串` | ✅ |
| `DATABASE_URL` | 数据库连接 | `postgresql://...` | ✅ |
---
## 故障排查
**问题 1: Backend 容器无法启动**
```bash
# 查看容器日志
docker compose logs backend
# 查看容器状态
docker compose ps
# 重新构建镜像
docker compose build --no-cache backend
docker compose --profile backend up -d
```
**问题 2: 数据库连接失败**
```bash
# 检查数据库健康状态
docker compose exec postgres pg_isready -U postgres
# 查看数据库日志
docker compose logs postgres
# 检查网络连接
docker compose exec backend ping postgres
# 等待数据库完全启动后重启 Backend
sleep 10
docker compose restart backend
```
**问题 3: 端口冲突**
```bash
# 修改 .env 文件中的端口
BACKEND_PORT=8081
POSTGRES_PORT=5433
# 重新启动
docker compose down
docker compose --profile backend up -d
```
**问题 4: 完全重置**
```bash
# 停止所有服务
docker compose down
# 删除数据卷(⚠️ 会删除数据)
docker compose down -v
# 清理 Docker 系统
docker system prune -a --volumes
# 重新部署
make up
```
---
# 环境变量配置
## 环境变量对比
| 变量 | Mock | Dev | Up | 说明 |
|------|------|-----|-----|------|
| `ADAPTER_MODE` | `mock` | `production` | `production` | 适配器模式 |
| `PORT` | `8080` | `8080` | `8080` | 服务端口 |
| `JWT_SECRET` | 简单值 | 开发值 | 强随机值 | JWT 密钥 |
| `ENCRYPTION_KEY` | - | 开发值 | 强随机值 | 加密密钥 |
| `DATABASE_URL` | - | 本地 PostgreSQL | 容器内 PostgreSQL | 数据库连接 |
---
## 模式对比
| 特性 | Mock | Dev | Up |
|------|------|-----|-----|
| **Backend 运行位置** | 本地进程 | 本地进程 | Docker 容器 |
| **依赖服务** | 无 | Docker (PostgreSQL) | Docker (PostgreSQL) |
| **热重载** | ✅ Air | ✅ Air | ❌ 需重新构建 |
| **数据库** | ❌ 内存 | ✅ PostgreSQL | ✅ PostgreSQL |
| **数据持久化** | ❌ | ✅ | ✅ |
| **启动时间** | 3 秒 | 5-8 秒 | 15-30 秒 |
| **调试能力** | ✅ IDE 断点 | ✅ IDE 断点 | ⚠️ 日志调试 |
| **适用场景** | 快速开发、API 测试 | 日常开发 ⭐ 推荐 | 集成测试、生产预演 |
| **环境隔离** | ✅ 完全隔离 | ⚠️ 部分隔离 | ✅ 完全隔离 |
| **生产一致性** | ❌ 低 | ⚠️ 中 | ✅ 高 |
---
## 推荐使用场景
### 🚀 Mock 模式
- ✅ 快速功能开发
- ✅ API 接口测试
- ✅ 前端联调
- ✅ 单元测试
### ⭐ Dev 模式(推荐日常开发)
- ✅ 日常功能开发
- ✅ 代码调试
- ✅ 数据持久化测试
- ✅ 快速迭代
### 🎯 Up 模式
- ✅ 集成测试
- ✅ 生产环境预演
- ✅ 团队协作环境搭建
- ✅ 交付演示
---
# 故障排查
## 通用问题
### 1. 端口被占用
```bash
# 查找占用端口的进程
lsof -i :8080
# 或
netstat -tuln | grep 8080
# 关闭进程
kill -9 <PID>
# 或使用其他端口
export PORT=8081
```
### 2. Go 环境问题
```bash
# 检查 Go 版本
go version # 需要 Go 1.21+
# 更新 Go 模块
go mod download
go mod tidy
# 清理 Go 缓存
go clean -cache -modcache
```
### 3. Air 找不到命令
```bash
# 确保 GOPATH/bin 在 PATH 中
export PATH=$PATH:$(go env GOPATH)/bin
# 重新安装 Air
go install github.com/air-verse/air@latest
# 验证安装
air -v
```
---
## Mock 模式问题
### 1. 服务无法启动
```bash
# 检查环境变量
echo $ADAPTER_MODE # 应该是 mock
echo $PORT # 应该是 8080
echo $JWT_SECRET # 不应为空
# 手动运行查看详细错误
export ADAPTER_MODE=mock
export JWT_SECRET=test-secret
go run cmd/api/main.go
```
### 2. Bootstrap 数据未加载
```bash
# 检查 bootstrap.json 文件
cat config/bootstrap.json
# 确保 enabled 为 true
# {
# "enabled": true,
# ...
# }
```
---
## Dev 模式问题
### 1. 数据库连接失败
```bash
# 检查 PostgreSQL 是否运行
docker compose ps postgres
# 检查端口
lsof -i :5432
# 测试连接
psql -h localhost -U postgres -d ocdp -c "SELECT 1;"
# 重启数据库
docker compose restart postgres
```
### 2. 数据库未初始化
```bash
# 重新初始化数据库
docker compose down postgres
docker compose up -d postgres
# 等待健康检查通过
docker compose ps postgres
```
### 3. Air 热重载失败
```bash
# 清理临时文件
rm -rf tmp/
# 重新启动 Air
air -c .air.toml
# 检查 .air.toml 配置
cat .air.toml
```
---
## Up 模式问题
### 1. Backend 容器无法启动
```bash
# 查看容器日志
docker compose logs backend
# 查看容器状态
docker compose ps
# 重新构建镜像
make up-rebuild
```
### 2. 镜像构建失败
```bash
# 清理 Docker 缓存
docker builder prune -a
# 重新构建
docker compose build --no-cache backend
# 检查 Dockerfile
cat Dockerfile
```
### 3. 容器健康检查失败
```bash
# 查看容器日志
docker compose logs backend
# 手动执行健康检查
docker compose exec backend wget --no-verbose --tries=1 --spider http://localhost:8080/health
# 检查 healthcheck 配置
docker compose config | grep -A 5 healthcheck
```
---
## 数据库问题
### 1. 数据库连接超时
```bash
# 检查数据库是否启动完成
docker compose ps postgres
# 查看数据库日志
docker compose logs postgres
# 手动测试连接
docker compose exec postgres pg_isready -U postgres
# 等待更长时间
sleep 10
docker compose restart backend
```
### 2. 数据丢失
```bash
# 检查数据卷
docker volume ls | grep postgres
# 备份当前数据
docker compose exec postgres pg_dump -U postgres ocdp > backup.sql
# 恢复数据
docker compose exec -T postgres psql -U postgres ocdp < backup.sql
```
### 3. 权限问题
```bash
# 检查数据卷权限
docker volume inspect ocdp_postgres_data
# 重新创建数据卷
docker compose down -v
docker compose up -d postgres
```
---
## 健康检查
```bash
# 服务健康检查
curl http://localhost:8080/health
# 预期: {"status":"healthy"}
# 数据库健康检查
# Docker 方式
docker compose exec postgres pg_isready -U postgres
# 本地方式
pg_isready -h localhost -p 5432 -U postgres
# 检查所有服务状态
docker compose ps
```
---
## 资源监控
```bash
# 查看容器资源使用
docker stats
# 查看磁盘使用
docker system df
# 查看日志大小
du -sh $(docker inspect --format='{{.LogPath}}' ocdp-backend)
du -sh $(docker inspect --format='{{.LogPath}}' ocdp-postgres)
# 清理 Docker 资源
docker system prune -a --volumes
```
---
## 完全重置
### Mock 模式
```bash
# 清理临时文件
rm -rf tmp/
# 重新启动
make mock
```
### Dev 模式
```bash
# 停止服务
docker compose down
# 删除数据卷(⚠️ 数据丢失)
docker compose down -v
# 重新启动
make db-up
make dev
```
### Up 模式
```bash
# 停止所有服务
docker compose down
# 删除数据卷(⚠️ 数据丢失)
docker compose down -v
# 清理 Docker 系统
docker system prune -a --volumes
# 重新部署
make up
```
---
## 服务访问地址
| 服务 | Mock | Dev | Up | 说明 |
|------|------|-----|-----|------|
| **Backend API** | http://localhost:8080/api/v1 | http://localhost:8080/api/v1 | http://localhost:8080/api/v1 | REST API |
| **Health Check** | http://localhost:8080/health | http://localhost:8080/health | http://localhost:8080/health | 健康检查 |
| **Swagger UI** | http://localhost:8080/api/docs | http://localhost:8080/api/docs | http://localhost:8080/api/docs | API 文档 |
| **PostgreSQL** | - | localhost:5432 | localhost:5432 | 数据库 |
---
## 相关文档
- [架构文档](architecture.md) - 六边形架构、技术选型
- [API 与测试](api-and-test.md) - API 文档、测试指南
- [主 README](../README.md) - 项目概览
---
**Last Updated**: 2025-11-09
**Version**: v3.0.0