774 lines
20 KiB
Markdown
774 lines
20 KiB
Markdown
# PandaWiki Ubuntu 22.04 内网部署指南
|
||
|
||
本文档涵盖从源码传输、构建 Docker 镜像到部署运行的完整流程。
|
||
|
||
---
|
||
|
||
## 一、整体部署架构
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────┐
|
||
│ Ubuntu 22.04 Server │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Nginx/Caddy │ │ Admin 前端 │ │
|
||
│ │ (反向代理) │ │ (Nginx) │ │
|
||
│ │ 端口: 80/443│ │ 端口: 5000 │ │
|
||
│ └──────┬──────┘ └─────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌──────────────────────┐ │
|
||
│ │ API 服务 (Go) │ 端口: 8000 │
|
||
│ │ Consumer 服务 (Go) │ 后台异步任务 │
|
||
│ └──────────┬───────────┘ │
|
||
│ │ │ │ │ │
|
||
│ ▼ ▼ ▼ ▼ │
|
||
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
|
||
│ │ PG │ │Redis │ │ NATS │ │MinIO │ │
|
||
│ │ :5432│ │:6379 │ │:4222 │ │:9000 │ │
|
||
│ └──────┘ └──────┘ └──────┘ └──────┘ │
|
||
│ │
|
||
│ ┌──────────────────────┐ │
|
||
│ │ RAG 向量检索服务 │ 端口: 5050 │
|
||
│ └──────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────┐ │
|
||
│ │ AI 大模型 API │ 外部配置 │
|
||
│ └──────────────────────┘ │
|
||
└──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、服务器环境准备
|
||
|
||
### 2.1 系统要求
|
||
|
||
```bash
|
||
# 确认系统版本
|
||
lsb_release -a
|
||
# Ubuntu 22.04.x LTS
|
||
|
||
# 建议配置
|
||
# CPU: 4 核以上
|
||
# 内存: 8 GB 以上 (AI 相关功能需要更多)
|
||
# 磁盘: 50 GB 以上
|
||
```
|
||
|
||
### 2.2 安装 Docker
|
||
|
||
```bash
|
||
# 卸载旧版本 (如果有)
|
||
sudo apt-get remove docker docker-engine docker.io containerd runc
|
||
|
||
# 安装依赖
|
||
sudo apt-get update
|
||
sudo apt-get install -y \
|
||
ca-certificates \
|
||
curl \
|
||
gnupg \
|
||
lsb-release
|
||
|
||
# 添加 Docker 官方 GPG 密钥
|
||
sudo mkdir -p /etc/apt/keyrings
|
||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
|
||
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||
|
||
# 添加 Docker 仓库
|
||
echo \
|
||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||
https://download.docker.com/linux/ubuntu \
|
||
$(lsb_release -cs) stable" | \
|
||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
|
||
# 安装 Docker Engine
|
||
sudo apt-get update
|
||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
|
||
docker-buildx-plugin docker-compose-plugin
|
||
|
||
# 验证安装
|
||
sudo docker --version
|
||
sudo docker compose version
|
||
|
||
# 将当前用户加入 docker 组 (免 sudo)
|
||
sudo usermod -aG docker $USER
|
||
newgrp docker
|
||
|
||
# 设置 Docker 开机自启
|
||
sudo systemctl enable docker
|
||
```
|
||
|
||
### 2.3 安装 Docker Compose (独立版,可选)
|
||
|
||
Docker 新版已内置 `docker compose` 插件。如需独立版:
|
||
|
||
```bash
|
||
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \
|
||
-o /usr/local/bin/docker-compose
|
||
sudo chmod +x /usr/local/bin/docker-compose
|
||
```
|
||
|
||
### 2.4 安装 Git (用于获取源码)
|
||
|
||
```bash
|
||
sudo apt-get install -y git
|
||
```
|
||
|
||
---
|
||
|
||
## 三、传输源码到服务器
|
||
|
||
### 方式 A:Git 仓库 (服务器有网络)
|
||
|
||
```bash
|
||
# 在服务器上
|
||
git clone https://github.com/chaitin/PandaWiki.git
|
||
cd PandaWiki
|
||
|
||
# 然后将你 Windows 上修改过的文件传输到服务器覆盖对应文件
|
||
# 需要覆盖的文件:
|
||
# backend/domain/license.go
|
||
# backend/usecase/stat.go
|
||
# backend/repo/pg/auth.go
|
||
# web/admin/src/constant/version.ts
|
||
```
|
||
|
||
### 方式 B:直接 SCP 传输整个项目 (推荐)
|
||
|
||
在 Windows 上使用 PowerShell 或 WSL:
|
||
|
||
```powershell
|
||
# 在 Windows 上执行,将整个项目传到服务器
|
||
scp -r "E:\code project\PandaWiki-3.85.0" user@your-server-ip:/home/user/
|
||
|
||
# 或者用 rsync (WSL/Linux)
|
||
rsync -avz --progress \
|
||
"/mnt/e/code project/PandaWiki-3.85.0/" \
|
||
user@your-server-ip:/home/user/PandaWiki/
|
||
```
|
||
|
||
### 方式 C:打包传输
|
||
|
||
```bash
|
||
# 在 Windows 上打包 (Git Bash / WSL)
|
||
cd "E:\code project\PandaWiki-3.85.0"
|
||
tar --exclude='.git' -czf panda-wiki.tar.gz .
|
||
|
||
# 传输到服务器
|
||
scp panda-wiki.tar.gz user@your-server-ip:/home/user/
|
||
|
||
# 在服务器上解压
|
||
mkdir -p ~/PandaWiki && cd ~/PandaWiki
|
||
tar -xzf ~/panda-wiki.tar.gz
|
||
```
|
||
|
||
---
|
||
|
||
## 四、创建 Docker Compose 配置
|
||
|
||
在项目根目录创建 `docker-compose.yml`:
|
||
|
||
```bash
|
||
cd ~/PandaWiki
|
||
```
|
||
|
||
```yaml
|
||
# docker-compose.yml
|
||
version: '3.8'
|
||
|
||
services:
|
||
# ========== 基础设施 ==========
|
||
|
||
postgres:
|
||
image: postgres:16-alpine
|
||
container_name: panda-wiki-postgres
|
||
restart: unless-stopped
|
||
environment:
|
||
POSTGRES_USER: panda-wiki
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe123!}
|
||
POSTGRES_DB: panda-wiki
|
||
volumes:
|
||
- pg_data:/var/lib/postgresql/data
|
||
ports:
|
||
- "127.0.0.1:5432:5432"
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U panda-wiki"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 5
|
||
networks:
|
||
- panda-wiki
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: panda-wiki-redis
|
||
restart: unless-stopped
|
||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-ChangeMe123!}
|
||
volumes:
|
||
- redis_data:/data
|
||
ports:
|
||
- "127.0.0.1:6379:6379"
|
||
healthcheck:
|
||
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 5
|
||
networks:
|
||
- panda-wiki
|
||
|
||
nats:
|
||
image: nats:2-alpine
|
||
container_name: panda-wiki-nats
|
||
restart: unless-stopped
|
||
command: >
|
||
-js
|
||
-m 8222
|
||
--user ${NATS_USER:-panda-wiki}
|
||
--pass ${NATS_PASSWORD:-ChangeMe123!}
|
||
ports:
|
||
- "127.0.0.1:4222:4222"
|
||
- "127.0.0.1:8222:8222"
|
||
networks:
|
||
- panda-wiki
|
||
|
||
minio:
|
||
image: minio/minio:latest
|
||
container_name: panda-wiki-minio
|
||
restart: unless-stopped
|
||
command: server /data --console-address ":9001"
|
||
environment:
|
||
MINIO_ROOT_USER: ${S3_ACCESS_KEY:-s3panda-wiki}
|
||
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:-ChangeMe123!}
|
||
volumes:
|
||
- minio_data:/data
|
||
ports:
|
||
- "127.0.0.1:9000:9000"
|
||
- "127.0.0.1:9001:9001"
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
networks:
|
||
- panda-wiki
|
||
|
||
# ========== 业务服务 ==========
|
||
|
||
api:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile.api
|
||
image: panda-wiki-api:latest
|
||
container_name: panda-wiki-api
|
||
restart: unless-stopped
|
||
environment:
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe123!}
|
||
NATS_PASSWORD: ${NATS_PASSWORD:-ChangeMe123!}
|
||
REDIS_PASSWORD: ${REDIS_PASSWORD:-ChangeMe123!}
|
||
JWT_SECRET: ${JWT_SECRET:-your-jwt-secret-change-me}
|
||
S3_SECRET_KEY: ${S3_SECRET_KEY:-ChangeMe123!}
|
||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123}
|
||
LOG_LEVEL: ${LOG_LEVEL:-0}
|
||
ENV: ${ENV:-production}
|
||
SENTRY_ENABLED: "false"
|
||
PG_DSN: "host=panda-wiki-postgres user=panda-wiki password=${POSTGRES_PASSWORD:-ChangeMe123!} dbname=panda-wiki port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
||
MQ_NATS_SERVER: "nats://panda-wiki-nats:4222"
|
||
REDIS_ADDR: "panda-wiki-redis:6379"
|
||
S3_ENDPOINT: "panda-wiki-minio:9000"
|
||
RAG_CT_RAG_BASE_URL: ${RAG_BASE_URL:-http://host.docker.internal:5050}
|
||
ports:
|
||
- "127.0.0.1:8000:8000"
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
redis:
|
||
condition: service_healthy
|
||
nats:
|
||
condition: service_started
|
||
minio:
|
||
condition: service_healthy
|
||
networks:
|
||
- panda-wiki
|
||
|
||
consumer:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile.consumer
|
||
image: panda-wiki-consumer:latest
|
||
container_name: panda-wiki-consumer
|
||
restart: unless-stopped
|
||
environment:
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe123!}
|
||
NATS_PASSWORD: ${NATS_PASSWORD:-ChangeMe123!}
|
||
REDIS_PASSWORD: ${REDIS_PASSWORD:-ChangeMe123!}
|
||
JWT_SECRET: ${JWT_SECRET:-your-jwt-secret-change-me}
|
||
S3_SECRET_KEY: ${S3_SECRET_KEY:-ChangeMe123!}
|
||
LOG_LEVEL: ${LOG_LEVEL:-0}
|
||
ENV: ${ENV:-production}
|
||
SENTRY_ENABLED: "false"
|
||
PG_DSN: "host=panda-wiki-postgres user=panda-wiki password=${POSTGRES_PASSWORD:-ChangeMe123!} dbname=panda-wiki port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
||
MQ_NATS_SERVER: "nats://panda-wiki-nats:4222"
|
||
REDIS_ADDR: "panda-wiki-redis:6379"
|
||
S3_ENDPOINT: "panda-wiki-minio:9000"
|
||
RAG_CT_RAG_BASE_URL: ${RAG_BASE_URL:-http://host.docker.internal:5050}
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
redis:
|
||
condition: service_healthy
|
||
nats:
|
||
condition: service_started
|
||
minio:
|
||
condition: service_healthy
|
||
networks:
|
||
- panda-wiki
|
||
|
||
# Nginx 反向代理 (可选,用于统一入口)
|
||
nginx:
|
||
image: nginx:alpine
|
||
container_name: panda-wiki-nginx
|
||
restart: unless-stopped
|
||
volumes:
|
||
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||
ports:
|
||
- "80:80"
|
||
depends_on:
|
||
- api
|
||
networks:
|
||
- panda-wiki
|
||
|
||
volumes:
|
||
pg_data:
|
||
redis_data:
|
||
minio_data:
|
||
|
||
networks:
|
||
panda-wiki:
|
||
driver: bridge
|
||
```
|
||
|
||
### 创建 Nginx 反向代理配置
|
||
|
||
```bash
|
||
cat > nginx.conf << 'EOF'
|
||
server {
|
||
listen 80;
|
||
server_name _;
|
||
client_max_body_size 100M;
|
||
|
||
# API 服务
|
||
location /api/ {
|
||
proxy_pass http://panda-wiki-api:8000;
|
||
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;
|
||
}
|
||
|
||
location /share/ {
|
||
proxy_pass http://panda-wiki-api:8000;
|
||
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;
|
||
}
|
||
|
||
# 健康检查
|
||
location /health {
|
||
proxy_pass http://panda-wiki-api:8000;
|
||
}
|
||
}
|
||
EOF
|
||
```
|
||
|
||
### 创建环境变量文件
|
||
|
||
```bash
|
||
cat > .env << 'EOF'
|
||
# 数据库密码
|
||
POSTGRES_PASSWORD=ChangeMe123!
|
||
|
||
# Redis 密码
|
||
REDIS_PASSWORD=ChangeMe123!
|
||
|
||
# NATS 密码
|
||
NATS_USER=panda-wiki
|
||
NATS_PASSWORD=ChangeMe123!
|
||
|
||
# MinIO/S3
|
||
S3_ACCESS_KEY=s3panda-wiki
|
||
S3_SECRET_KEY=ChangeMe123!
|
||
|
||
# JWT 密钥 (务必修改为随机字符串)
|
||
JWT_SECRET=your-jwt-secret-change-me-to-random-string
|
||
|
||
# 管理员初始密码 (首次登录后修改)
|
||
ADMIN_PASSWORD=admin123
|
||
|
||
# 日志级别: -4=debug, 0=info, 4=warn, 8=error
|
||
LOG_LEVEL=0
|
||
|
||
# RAG 向量检索服务地址
|
||
RAG_BASE_URL=http://host.docker.internal:5050
|
||
EOF
|
||
```
|
||
|
||
---
|
||
|
||
## 五、构建并启动
|
||
|
||
### 5.1 构建后端 Docker 镜像
|
||
|
||
```bash
|
||
cd ~/PandaWiki
|
||
|
||
# 构建 API 镜像 (包含数据库迁移)
|
||
docker build -f backend/Dockerfile.api -t panda-wiki-api:latest ./backend
|
||
|
||
# 构建 Consumer 镜像
|
||
docker build -f backend/Dockerfile.consumer -t panda-wiki-consumer:latest ./backend
|
||
```
|
||
|
||
### 5.2 构建前端 (可选)
|
||
|
||
如果需要在服务器上运行前端:
|
||
|
||
```bash
|
||
# 安装 Node.js 22 (管理员前端构建)
|
||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||
sudo apt-get install -y nodejs
|
||
|
||
# 安装 pnpm
|
||
sudo npm install -g pnpm
|
||
|
||
# 构建管理员前端
|
||
cd ~/PandaWiki/web
|
||
pnpm install
|
||
pnpm --filter panda-wiki-admin build
|
||
|
||
# 构建用户端前端
|
||
pnpm --filter panda-wiki-app build
|
||
|
||
# 管理员前端会输出到 web/admin/dist/
|
||
# 用户端前端会输出到 web/app/dist/
|
||
# 可以用 Nginx 托管这些静态文件
|
||
```
|
||
|
||
### 5.3 启动全部服务
|
||
|
||
```bash
|
||
cd ~/PandaWiki
|
||
|
||
# 先启动基础设施
|
||
docker compose up -d postgres redis nats minio
|
||
|
||
# 等待基础设施就绪
|
||
sleep 15
|
||
|
||
# 启动业务服务
|
||
docker compose up -d api consumer nginx
|
||
|
||
# 查看所有容器状态
|
||
docker compose ps
|
||
|
||
# 查看日志
|
||
docker compose logs -f api
|
||
```
|
||
|
||
### 5.4 验证部署
|
||
|
||
```bash
|
||
# 检查 API 是否正常
|
||
curl http://localhost:8000/api/v1/health
|
||
|
||
# 查看容器日志
|
||
docker compose logs api | tail -50
|
||
docker compose logs consumer | tail -50
|
||
|
||
# 确认数据库迁移成功
|
||
docker compose logs api | grep -i migrate
|
||
```
|
||
|
||
---
|
||
|
||
## 六、AI 模型配置
|
||
|
||
首次登录管理后台后,需要配置 AI 大模型才能使用 AI 创作、AI 问答等功能。
|
||
|
||
### 支持的模型接入方式
|
||
|
||
| 方式 | 说明 |
|
||
|------|------|
|
||
| OpenAI 兼容 API | 任何兼容 OpenAI 接口的模型服务 |
|
||
| 本地 Ollama | 在内网服务器上自建 Ollama 服务 |
|
||
| DeepSeek API | DeepSeek 官方 API |
|
||
| Gemini API | Google Gemini |
|
||
|
||
### 内网环境推荐:自建 Ollama
|
||
|
||
```bash
|
||
# 在服务器上安装 Ollama
|
||
curl -fsSL https://ollama.com/install.sh | sh
|
||
|
||
# 拉取模型 (根据服务器配置选择)
|
||
ollama pull qwen2.5:7b # 7B 参数,需要约 8GB 显存/内存
|
||
ollama pull qwen2.5:14b # 14B 参数
|
||
ollama pull llama3.1:8b # 8B 参数
|
||
|
||
# Ollama API 默认监听 11434 端口
|
||
# 在 PandaWiki 管理后台配置模型时,填写:
|
||
# API 地址: http://host.docker.internal:11434/v1
|
||
# 模型名称: qwen2.5:7b
|
||
```
|
||
|
||
---
|
||
|
||
## 七、Nginx 前端托管 (可选)
|
||
|
||
将构建好的前端静态文件用 Nginx 托管:
|
||
|
||
```bash
|
||
# 创建前端部署目录
|
||
sudo mkdir -p /var/www/panda-wiki/{admin,app}
|
||
|
||
# 复制构建产物
|
||
sudo cp -r ~/PandaWiki/web/admin/dist/* /var/www/panda-wiki/admin/
|
||
sudo cp -r ~/PandaWiki/web/app/dist/* /var/www/panda-wiki/app/
|
||
|
||
# Nginx 配置
|
||
sudo tee /etc/nginx/sites-available/panda-wiki << 'EOF'
|
||
server {
|
||
listen 80;
|
||
server_name your-domain.com;
|
||
|
||
client_max_body_size 100M;
|
||
|
||
# 管理后台
|
||
location /admin {
|
||
alias /var/www/panda-wiki/admin;
|
||
index index.html;
|
||
try_files $uri $uri/ /admin/index.html;
|
||
}
|
||
|
||
# Wiki 用户端
|
||
location / {
|
||
root /var/www/panda-wiki/app;
|
||
index index.html;
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
|
||
# API 代理
|
||
location /api/ {
|
||
proxy_pass http://127.0.0.1:8000;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
}
|
||
|
||
location /share/ {
|
||
proxy_pass http://127.0.0.1:8000;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
}
|
||
}
|
||
EOF
|
||
|
||
sudo ln -s /etc/nginx/sites-available/panda-wiki /etc/nginx/sites-enabled/
|
||
sudo nginx -t
|
||
sudo systemctl reload nginx
|
||
```
|
||
|
||
---
|
||
|
||
## 八、内网完全离线部署
|
||
|
||
如果服务器**完全无法访问外网**,需要在有网络的机器上预先准备所有材料。
|
||
|
||
### 8.1 准备阶段 (在有网络的机器上)
|
||
|
||
```bash
|
||
# 1. 拉取所有基础 Docker 镜像
|
||
docker pull postgres:16-alpine
|
||
docker pull redis:7-alpine
|
||
docker pull nats:2-alpine
|
||
docker pull minio/minio:latest
|
||
docker pull nginx:alpine
|
||
docker pull golang:1.24.3-alpine
|
||
docker pull alpine:3.21
|
||
|
||
# 2. 导出镜像为 tar 文件
|
||
docker save -o postgres-16.tar postgres:16-alpine
|
||
docker save -o redis-7.tar redis:7-alpine
|
||
docker save -o nats-2.tar nats:2-alpine
|
||
docker save -o minio-latest.tar minio/minio:latest
|
||
docker save -o nginx-alpine.tar nginx:alpine
|
||
docker save -o golang-1.24.tar golang:1.24.3-alpine
|
||
docker save -o alpine-3.21.tar alpine:3.21
|
||
|
||
# 3. 下载 Go 依赖 (可选,Docker 构建时会自动处理)
|
||
# 如果有网络,直接 Docker build 即可
|
||
# 如果完全离线,需要预先 go mod download 并复制缓存
|
||
|
||
# 4. 打包项目源码
|
||
cd ~/PandaWiki
|
||
tar czf panda-wiki-source.tar.gz \
|
||
--exclude='.git' \
|
||
--exclude='node_modules' \
|
||
--exclude='web/.pnpm-store' \
|
||
.
|
||
|
||
# 5. 将镜像 tar 和源码 tar 传输到内网服务器
|
||
scp *.tar user@internal-server:/home/user/
|
||
```
|
||
|
||
### 8.2 部署阶段 (在内网服务器上)
|
||
|
||
```bash
|
||
# 1. 导入 Docker 镜像
|
||
cd /home/user
|
||
for f in *.tar; do
|
||
docker load -i "$f"
|
||
done
|
||
|
||
# 2. 解压项目源码
|
||
mkdir -p ~/PandaWiki && cd ~/PandaWiki
|
||
tar xzf ~/panda-wiki-source.tar.gz
|
||
|
||
# 3. 修改 docker-compose.yml 中的 build 部分
|
||
# 将 BUILDKIT 缓存挂载移除 (离线环境不支持)
|
||
# 将 Dockerfile 中的 --mount=type=cache 替换为普通 COPY
|
||
|
||
# 4. 创建离线版 Dockerfile
|
||
cat > backend/Dockerfile.api.offline << 'DOCKERFILE'
|
||
FROM golang:1.24.3-alpine AS builder
|
||
WORKDIR /src
|
||
ENV CGO_ENABLED=0
|
||
COPY backend/go.mod backend/go.sum ./
|
||
RUN go mod download
|
||
COPY backend/ .
|
||
ARG TARGETOS TARGETARCH VERSION
|
||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build \
|
||
-ldflags "-s -w -extldflags '-static'" \
|
||
-o /build/panda-wiki-api \
|
||
cmd/api/main.go cmd/api/wire_gen.go \
|
||
&& GOOS=$TARGETOS GOARCH=$TARGETARCH go build \
|
||
-ldflags "-s -w -extldflags '-static'" \
|
||
-o /build/panda-wiki-migrate \
|
||
cmd/migrate/main.go cmd/migrate/wire_gen.go
|
||
|
||
FROM alpine:3.21 AS api
|
||
RUN apk update && apk upgrade && apk add --no-cache ca-certificates tzdata \
|
||
&& update-ca-certificates 2>/dev/null || true && rm -rf /var/cache/apk/*
|
||
WORKDIR /app
|
||
COPY --from=builder /build/panda-wiki-api /app/panda-wiki-api
|
||
COPY --from=builder /build/panda-wiki-migrate /app/panda-wiki-migrate
|
||
COPY --from=builder /src/store/pg/migration /app/migration
|
||
CMD ["sh", "-c", "/app/panda-wiki-migrate && /app/panda-wiki-api"]
|
||
DOCKERFILE
|
||
|
||
# 5. 使用离线 Dockerfile 构建
|
||
docker build -f backend/Dockerfile.api.offline -t panda-wiki-api:latest .
|
||
|
||
# 6. 启动服务
|
||
docker compose up -d
|
||
```
|
||
|
||
---
|
||
|
||
## 九、常用运维命令
|
||
|
||
```bash
|
||
# 查看所有服务状态
|
||
docker compose ps
|
||
|
||
# 查看某个服务的实时日志
|
||
docker compose logs -f api
|
||
docker compose logs -f consumer
|
||
|
||
# 重启某个服务
|
||
docker compose restart api
|
||
|
||
# 进入容器调试
|
||
docker exec -it panda-wiki-api sh
|
||
|
||
# 数据库备份
|
||
docker exec panda-wiki-postgres pg_dump -U panda-wiki panda-wiki > backup.sql
|
||
|
||
# 数据库恢复
|
||
docker exec -i panda-wiki-postgres psql -U panda-wiki panda-wiki < backup.sql
|
||
|
||
# 更新代码后重新构建
|
||
docker compose build api consumer
|
||
docker compose up -d api consumer
|
||
|
||
# 查看资源占用
|
||
docker stats
|
||
|
||
# 完全停止
|
||
docker compose down
|
||
|
||
# 停止并删除数据卷 (危险!会丢失所有数据)
|
||
docker compose down -v
|
||
```
|
||
|
||
---
|
||
|
||
## 十、访问地址
|
||
|
||
部署完成后:
|
||
|
||
| 地址 | 说明 |
|
||
|------|------|
|
||
| `http://服务器IP:8000` | 后端 API (通过 Nginx 代理则为 80 端口) |
|
||
| `http://服务器IP:2443` | 管理后台 (如使用官方 Caddy 配置) |
|
||
| `http://服务器IP:9001` | MinIO 管理控制台 |
|
||
|
||
首次登录使用 `.env` 中配置的 `ADMIN_PASSWORD` 密码,用户名为 `admin`。
|
||
|
||
---
|
||
|
||
## 十一、故障排查
|
||
|
||
### 数据库连接失败
|
||
|
||
```bash
|
||
# 检查 postgres 是否就绪
|
||
docker compose logs postgres
|
||
|
||
# 手动连接测试
|
||
docker exec -it panda-wiki-postgres psql -U panda-wiki -d panda-wiki
|
||
```
|
||
|
||
### API 启动失败
|
||
|
||
```bash
|
||
# 查看详细日志
|
||
docker compose logs api
|
||
|
||
# 常见原因:
|
||
# 1. 数据库迁移失败 - 检查 PG_DSN 配置
|
||
# 2. NATS 连接失败 - 检查 MQ_NATS_SERVER 配置
|
||
# 3. Redis 连接失败 - 检查 REDIS_ADDR 配置
|
||
```
|
||
|
||
### 前端页面空白
|
||
|
||
```bash
|
||
# 检查 API 是否可达
|
||
curl http://localhost:8000/api/v1/health
|
||
|
||
# 检查浏览器控制台是否有 CORS 或 API 404 错误
|
||
# 确保前端配置的 API 地址正确
|
||
```
|
||
|
||
### 容器之间网络不通
|
||
|
||
```bash
|
||
# 检查网络
|
||
docker network inspect panda-wiki_panda-wiki
|
||
|
||
# 容器间通信测试
|
||
docker exec panda-wiki-api ping panda-wiki-postgres
|
||
```
|