Compare commits
10 Commits
4cf80fed45
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ff20f6f23a | |||
| 581bd40184 | |||
| 2851e8eb54 | |||
| 4ab2c167e5 | |||
| 9400889f29 | |||
| 4a16a0901c | |||
| 34ac109f93 | |||
| 07501975dc | |||
| 399b880f16 | |||
| 35f596ba69 |
@ -8,6 +8,10 @@ on:
|
||||
- '.gitea/workflows/deploy-admin.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUN_VERSION: 'latest'
|
||||
CACHE_KEY: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||
|
||||
jobs:
|
||||
test-and-build:
|
||||
name: 🧪 测试和构建
|
||||
@ -20,57 +24,44 @@ jobs:
|
||||
- name: 🥖 设置 Bun 环境
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
|
||||
- name: 💾 缓存 Bun 依赖
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.bun/install/cache
|
||||
admin/node_modules
|
||||
key: ${{ env.CACHE_KEY }}-${{ hashFiles('admin/bun.lock') }}
|
||||
restore-keys: |
|
||||
${{ env.CACHE_KEY }}-
|
||||
|
||||
- name: 📦 安装依赖
|
||||
working-directory: ./admin
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: 🔍 代码检查
|
||||
working-directory: ./admin
|
||||
run: |
|
||||
bun run lint
|
||||
bun run type-check
|
||||
|
||||
- name: 🎨 格式检查
|
||||
working-directory: ./admin
|
||||
run: bun run format
|
||||
|
||||
- name: 🧪 运行测试
|
||||
working-directory: ./admin
|
||||
run: bun run test
|
||||
|
||||
- name: 🔒 安全审计
|
||||
working-directory: ./admin
|
||||
run: bun audit || echo "⚠️ 安全审计警告,继续部署"
|
||||
|
||||
- name: 🏗️ 构建生产版本
|
||||
- name: 🏗️ 并行质量检查和构建
|
||||
working-directory: ./admin
|
||||
env:
|
||||
VITE_APP_TITLE: 摄影作品集管理后台
|
||||
VITE_API_BASE_URL: https://api.photography.iriver.top
|
||||
VITE_UPLOAD_URL: https://api.photography.iriver.top/upload
|
||||
run: bun run build
|
||||
|
||||
- name: 📊 构建分析
|
||||
working-directory: ./admin
|
||||
run: |
|
||||
echo "📦 构建产物分析:"
|
||||
du -sh dist/
|
||||
echo "📁 文件列表:"
|
||||
find dist/ -type f -name "*.js" -o -name "*.css" | head -10
|
||||
echo "📈 文件大小统计:"
|
||||
find dist/ -type f \( -name "*.js" -o -name "*.css" \) -exec ls -lh {} + | awk '{print $5, $9}' | sort -hr | head -10
|
||||
# 并行执行代码检查和构建
|
||||
bun run lint &
|
||||
bun run type-check &
|
||||
bun run build &
|
||||
wait
|
||||
|
||||
- name: 📦 打包构建产物
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: admin-dist
|
||||
name: admin-dist-${{ github.sha }}
|
||||
path: admin/dist/
|
||||
retention-days: 7
|
||||
retention-days: 1
|
||||
|
||||
deploy:
|
||||
name: 🚀 部署到生产环境
|
||||
name: 🚀 部署管理后台
|
||||
runs-on: ubuntu-latest
|
||||
needs: test-and-build
|
||||
if: github.ref == 'refs/heads/main'
|
||||
@ -79,240 +70,66 @@ jobs:
|
||||
- name: 📥 检出代码
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🥖 设置 Bun 环境
|
||||
uses: oven-sh/setup-bun@v1
|
||||
- name: 📥 下载构建产物
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
bun-version: latest
|
||||
name: admin-dist-${{ github.sha }}
|
||||
path: admin/dist/
|
||||
|
||||
- name: 📦 安装依赖
|
||||
working-directory: ./admin
|
||||
run: bun install --frozen-lockfile
|
||||
- name: 📤 上传并部署
|
||||
uses: appleboy/scp-action@v0.1.6
|
||||
with:
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
source: "admin/dist/"
|
||||
target: "/tmp/admin-build"
|
||||
rm: true
|
||||
|
||||
- name: 🏗️ 构建生产版本
|
||||
working-directory: ./admin
|
||||
env:
|
||||
VITE_APP_TITLE: 摄影作品集管理后台
|
||||
VITE_API_BASE_URL: https://api.photography.iriver.top
|
||||
VITE_UPLOAD_URL: https://api.photography.iriver.top/upload
|
||||
run: bun run build
|
||||
|
||||
- name: 📊 压缩构建产物
|
||||
working-directory: ./admin
|
||||
run: |
|
||||
# 使用国内镜像源安装压缩工具
|
||||
echo "🔄 使用国内镜像源..."
|
||||
sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
|
||||
sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30
|
||||
sudo apt-get install -y tar gzip
|
||||
|
||||
tar -czf admin-dist.tar.gz -C dist .
|
||||
echo "压缩完成: $(ls -lh admin-dist.tar.gz)"
|
||||
|
||||
- name: 🚀 部署到服务器
|
||||
- name: 🔄 部署文件到生产目录
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
script: |
|
||||
# 设置变量
|
||||
echo "🔄 部署管理后台文件..."
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p /home/gitea/www/photography-admin
|
||||
|
||||
# 清空旧文件
|
||||
rm -rf /home/gitea/www/photography-admin/*
|
||||
|
||||
# 移动新文件到生产目录
|
||||
cp -r /tmp/admin-build/admin/dist/* /home/gitea/www/photography-admin/ || exit 1
|
||||
|
||||
# 清理临时文件
|
||||
rm -rf /tmp/admin-build
|
||||
|
||||
# 验证部署结果
|
||||
echo "📋 验证部署文件..."
|
||||
ls -la /home/gitea/www/photography-admin/ | head -10
|
||||
|
||||
- name: 🔧 设置权限和健康检查
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
script: |
|
||||
echo "🔧 设置权限..."
|
||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
||||
BACKUP_DIR="/home/gitea/backups/photography-admin"
|
||||
TEMP_DIR="/tmp/photography-admin-deploy"
|
||||
|
||||
echo "🚀 开始部署管理后台..."
|
||||
chown -R gitea:gitea $ADMIN_DIR
|
||||
chmod -R 755 $ADMIN_DIR
|
||||
|
||||
# 创建临时目录
|
||||
mkdir -p "$TEMP_DIR"
|
||||
echo "✅ 管理后台部署完成!"
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 备份当前版本
|
||||
if [ -d "$ADMIN_DIR" ] && [ "$(ls -A $ADMIN_DIR)" ]; then
|
||||
echo "📦 备份当前版本..."
|
||||
BACKUP_NAME="admin-$(date +%Y%m%d-%H%M%S).tar.gz"
|
||||
tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$ADMIN_DIR" .
|
||||
echo "✅ 备份完成: $BACKUP_NAME"
|
||||
|
||||
# 保留最近10个备份
|
||||
cd "$BACKUP_DIR"
|
||||
ls -t admin-*.tar.gz | tail -n +11 | xargs -r rm
|
||||
echo "🧹 清理旧备份完成"
|
||||
fi
|
||||
|
||||
echo "📁 准备部署目录..."
|
||||
mkdir -p "$ADMIN_DIR"
|
||||
|
||||
- name: 📤 上传构建产物
|
||||
uses: appleboy/scp-action@v0.1.4
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
source: admin/admin-dist.tar.gz
|
||||
target: /tmp/photography-admin-deploy/
|
||||
strip_components: 1
|
||||
|
||||
- name: 🔄 解压并部署
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
# 设置变量
|
||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
||||
TEMP_DIR="/tmp/photography-admin-deploy"
|
||||
|
||||
echo "🔄 解压新版本..."
|
||||
cd "$TEMP_DIR"
|
||||
tar -xzf admin-dist.tar.gz
|
||||
|
||||
echo "📂 部署新版本..."
|
||||
# 清空目标目录
|
||||
rm -rf "$ADMIN_DIR"/*
|
||||
|
||||
# 复制新文件
|
||||
cp -r * "$ADMIN_DIR/"
|
||||
|
||||
echo "🔐 设置文件权限..."
|
||||
chown -R gitea:gitea "$ADMIN_DIR"
|
||||
chmod -R 755 "$ADMIN_DIR"
|
||||
|
||||
# 设置正确的文件权限
|
||||
find "$ADMIN_DIR" -type f -name "*.html" -o -name "*.js" -o -name "*.css" -o -name "*.json" | xargs chmod 644
|
||||
find "$ADMIN_DIR" -type d | xargs chmod 755
|
||||
|
||||
echo "🧹 清理临时文件..."
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
echo "✅ 管理后台部署完成!"
|
||||
echo "📊 部署统计:"
|
||||
echo "文件数量: $(find $ADMIN_DIR -type f | wc -l)"
|
||||
echo "目录大小: $(du -sh $ADMIN_DIR)"
|
||||
|
||||
- name: 🔍 健康检查
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
echo "🔍 执行健康检查..."
|
||||
|
||||
# 检查文件是否存在
|
||||
if [ -f "/home/gitea/www/photography-admin/index.html" ]; then
|
||||
echo "✅ index.html 文件存在"
|
||||
else
|
||||
echo "❌ index.html 文件不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查网站是否可访问 (本地检查)
|
||||
sleep 5
|
||||
if curl -f -s -o /dev/null https://admin.photography.iriver.top; then
|
||||
echo "✅ 管理后台访问正常"
|
||||
else
|
||||
echo "⚠️ 管理后台访问异常,请检查 Caddy 配置"
|
||||
fi
|
||||
|
||||
# 重新加载 Caddy (确保新文件被正确服务)
|
||||
sudo systemctl reload caddy
|
||||
echo "🔄 Caddy 配置已重新加载"
|
||||
|
||||
|
||||
rollback:
|
||||
name: 🔄 回滚部署
|
||||
runs-on: ubuntu-latest
|
||||
if: failure() && github.ref == 'refs/heads/main'
|
||||
needs: deploy
|
||||
|
||||
steps:
|
||||
- name: 🔄 执行回滚
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
||||
BACKUP_DIR="/home/gitea/backups/photography-admin"
|
||||
|
||||
echo "🔄 开始回滚管理后台..."
|
||||
|
||||
# 查找最新的备份
|
||||
LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/admin-*.tar.gz 2>/dev/null | head -n 1)
|
||||
|
||||
if [ -n "$LATEST_BACKUP" ]; then
|
||||
echo "📦 找到备份文件: $LATEST_BACKUP"
|
||||
|
||||
# 清空当前目录
|
||||
rm -rf "$ADMIN_DIR"/*
|
||||
|
||||
# 恢复备份
|
||||
tar -xzf "$LATEST_BACKUP" -C "$ADMIN_DIR"
|
||||
|
||||
# 设置权限
|
||||
chown -R gitea:gitea "$ADMIN_DIR"
|
||||
chmod -R 755 "$ADMIN_DIR"
|
||||
|
||||
# 重新加载 Caddy
|
||||
sudo systemctl reload caddy
|
||||
|
||||
echo "✅ 回滚完成"
|
||||
else
|
||||
echo "❌ 未找到备份文件,无法回滚"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
security-scan:
|
||||
name: 🔒 安全扫描
|
||||
runs-on: ubuntu-latest
|
||||
needs: test-and-build
|
||||
|
||||
steps:
|
||||
- name: 📥 检出代码
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🥖 设置 Bun 环境
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: 📦 安装依赖
|
||||
working-directory: ./admin
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: 🔒 运行安全扫描
|
||||
working-directory: ./admin
|
||||
run: |
|
||||
echo "🔍 扫描已知漏洞..."
|
||||
bun audit || echo "⚠️ 发现安全警告,请手动检查"
|
||||
|
||||
echo "📊 依赖分析..."
|
||||
echo "依赖数量: $(bun pm ls --depth=0 | wc -l)"
|
||||
|
||||
echo "🔍 检查过时依赖..."
|
||||
bun outdated || true
|
||||
|
||||
- name: 📊 生成安全报告
|
||||
working-directory: ./admin
|
||||
run: |
|
||||
echo "# 安全扫描报告 (Bun)" > security-report.md
|
||||
echo "## 日期: $(date)" >> security-report.md
|
||||
echo "## 依赖统计" >> security-report.md
|
||||
echo "依赖数量: $(bun pm ls --depth=0 | wc -l)" >> security-report.md
|
||||
echo "## Bun 版本" >> security-report.md
|
||||
bun --version >> security-report.md
|
||||
|
||||
- name: 📤 上传安全报告
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: security-report
|
||||
path: admin/security-report.md
|
||||
# 验证部署
|
||||
if [ -f "$ADMIN_DIR/index.html" ]; then
|
||||
echo "✅ index.html 已部署"
|
||||
fi
|
||||
@ -8,6 +8,10 @@ on:
|
||||
- '.gitea/workflows/deploy-frontend.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUN_VERSION: 'latest'
|
||||
CACHE_KEY: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||
|
||||
jobs:
|
||||
test-and-build:
|
||||
name: 🧪 测试和构建
|
||||
@ -20,17 +24,33 @@ jobs:
|
||||
- name: 🦀 设置 Bun 环境
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
|
||||
- name: 💾 缓存 Bun 依赖
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.bun/install/cache
|
||||
frontend/node_modules
|
||||
key: ${{ env.CACHE_KEY }}-${{ hashFiles('frontend/bun.lock') }}
|
||||
restore-keys: |
|
||||
${{ env.CACHE_KEY }}-
|
||||
|
||||
- name: 📦 安装依赖
|
||||
working-directory: ./frontend
|
||||
run: bun install
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: 🔍 代码检查
|
||||
- name: 🏗️ 并行构建和检查
|
||||
working-directory: ./frontend
|
||||
run: |
|
||||
bun run lint
|
||||
bun run type-check
|
||||
# 并行执行代码检查和构建
|
||||
bun run lint &
|
||||
bun run type-check &
|
||||
wait
|
||||
env:
|
||||
NEXT_PUBLIC_API_URL: https://api.photography.iriver.top
|
||||
NEXT_PUBLIC_SITE_URL: https://photography.iriver.top
|
||||
NEXT_PUBLIC_SITE_NAME: 摄影作品集
|
||||
|
||||
- name: 🏗️ 构建生产版本
|
||||
working-directory: ./frontend
|
||||
@ -43,9 +63,9 @@ jobs:
|
||||
- name: 📦 打包构建产物
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: frontend-dist
|
||||
name: frontend-dist-${{ github.sha }}
|
||||
path: frontend/out/
|
||||
retention-days: 7
|
||||
retention-days: 1
|
||||
|
||||
deploy:
|
||||
name: 🚀 部署到生产环境
|
||||
@ -60,11 +80,19 @@ jobs:
|
||||
- name: 🦀 设置 Bun 环境
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
|
||||
- name: 💾 缓存 Bun 依赖
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.bun/install/cache
|
||||
frontend/node_modules
|
||||
key: ${{ env.CACHE_KEY }}-${{ hashFiles('frontend/bun.lock') }}
|
||||
|
||||
- name: 📦 安装依赖
|
||||
working-directory: ./frontend
|
||||
run: bun install
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: 🏗️ 构建生产版本
|
||||
working-directory: ./frontend
|
||||
@ -74,59 +102,91 @@ jobs:
|
||||
NEXT_PUBLIC_SITE_NAME: 摄影作品集
|
||||
run: bun run build
|
||||
|
||||
- name: 🚀 部署到服务器
|
||||
run: |
|
||||
# 使用国内镜像源安装部署工具
|
||||
echo "🔄 使用国内镜像源..."
|
||||
sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
|
||||
sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30
|
||||
sudo apt-get install -y openssh-client rsync sshpass
|
||||
|
||||
# 设置 SSH 环境
|
||||
export SSHPASS=${{ secrets.ALIYUN_PWD }}
|
||||
|
||||
echo "🔗 测试 SSH 连接..."
|
||||
sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "echo 'SSH 连接成功'"
|
||||
|
||||
echo "📁 创建部署目录..."
|
||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "mkdir -p /home/gitea/www/photography"
|
||||
|
||||
echo "📦 备份当前版本..."
|
||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "
|
||||
if [ -d '/home/gitea/www/photography' ] && [ \"\$(ls -A /home/gitea/www/photography)\" ]; then
|
||||
mkdir -p /home/gitea/backups/photography-frontend
|
||||
tar -czf /home/gitea/backups/photography-frontend/frontend-\$(date +%Y%m%d-%H%M%S).tar.gz -C /home/gitea/www/photography .
|
||||
echo '✅ 备份完成'
|
||||
fi
|
||||
"
|
||||
|
||||
echo "🚀 部署新版本..."
|
||||
sshpass -e rsync -avz --delete --progress -e "ssh -o StrictHostKeyChecking=no" frontend/out/ ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }}:/home/gitea/www/photography/
|
||||
|
||||
echo "🔐 设置文件权限..."
|
||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "
|
||||
- name: 📤 上传文件到服务器
|
||||
uses: appleboy/scp-action@v0.1.6
|
||||
with:
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
source: "frontend/out/"
|
||||
target: "/tmp/frontend-build"
|
||||
rm: true
|
||||
|
||||
- name: 🔄 部署文件到生产目录
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
script: |
|
||||
echo "🔄 部署文件到生产目录..."
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p /home/gitea/www/photography
|
||||
|
||||
# 清空旧文件
|
||||
rm -rf /home/gitea/www/photography/*
|
||||
|
||||
# 移动新文件到生产目录
|
||||
cp -r /tmp/frontend-build/frontend/out/* /home/gitea/www/photography/ || exit 1
|
||||
|
||||
# 清理临时文件
|
||||
rm -rf /tmp/frontend-build
|
||||
|
||||
# 验证部署结果
|
||||
echo "📋 验证部署文件..."
|
||||
ls -la /home/gitea/www/photography/ | head -10
|
||||
|
||||
- name: 🔧 设置文件权限
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
script: |
|
||||
echo "🔧 设置文件权限..."
|
||||
|
||||
# 设置所有者
|
||||
chown -R gitea:gitea /home/gitea/www/photography
|
||||
|
||||
# 设置权限
|
||||
chmod -R 755 /home/gitea/www/photography
|
||||
find /home/gitea/www/photography -type f -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.json' | xargs chmod 644
|
||||
"
|
||||
|
||||
echo "🔄 重新加载 Web 服务器..."
|
||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "sudo systemctl reload caddy"
|
||||
|
||||
echo "✅ 前端部署完成!"
|
||||
echo "📁 部署路径:/home/gitea/www/photography/"
|
||||
echo "🌐 访问地址:https://photography.iriver.top"
|
||||
find /home/gitea/www/photography -type f \( -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.json' \) -exec chmod 644 {} \;
|
||||
|
||||
# 重新加载 Caddy
|
||||
if command -v sudo &> /dev/null; then
|
||||
sudo systemctl reload caddy
|
||||
else
|
||||
systemctl reload caddy || true
|
||||
fi
|
||||
|
||||
echo "✅ 前端部署完成!"
|
||||
|
||||
- name: 🔍 健康检查
|
||||
run: |
|
||||
echo "🔍 执行健康检查..."
|
||||
sleep 10
|
||||
|
||||
# 检查网站是否可访问
|
||||
if curl -f -s -o /dev/null https://photography.iriver.top; then
|
||||
echo "✅ 前端网站访问正常"
|
||||
else
|
||||
echo "⚠️ 前端网站访问异常"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.ALIYUN_IP }}
|
||||
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||
password: ${{ secrets.ALIYUN_PWD }}
|
||||
port: 22
|
||||
script: |
|
||||
echo "🔍 执行健康检查..."
|
||||
|
||||
# 检查文件是否存在
|
||||
if [ -f '/home/gitea/www/photography/index.html' ]; then
|
||||
echo '✅ index.html 文件存在'
|
||||
else
|
||||
echo '❌ index.html 文件不存在'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 快速检查
|
||||
sleep 3
|
||||
if curl -f -s -o /dev/null https://photography.iriver.top; then
|
||||
echo '✅ 前端网站访问正常'
|
||||
else
|
||||
echo '⚠️ 前端网站访问异常,请手动检查'
|
||||
fi
|
||||
23
.promptx/pouch.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"currentState": "service_discovery",
|
||||
"stateHistory": [
|
||||
{
|
||||
"from": "initial",
|
||||
"command": "init",
|
||||
"timestamp": "2025-07-21T14:37:13.506Z",
|
||||
"args": [
|
||||
{
|
||||
"workingDirectory": "/Users/iriver/workspace/photography",
|
||||
"ideType": "trae"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "initialized",
|
||||
"command": "welcome",
|
||||
"timestamp": "2025-07-21T14:37:23.299Z",
|
||||
"args": []
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2025-07-21T14:37:23.301Z"
|
||||
}
|
||||
17
.promptx/resource/project.registry.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"source": "project",
|
||||
"metadata": {
|
||||
"version": "2.0.0",
|
||||
"description": "project 级资源注册表",
|
||||
"createdAt": "2025-07-21T14:37:13.518Z",
|
||||
"updatedAt": "2025-07-21T14:37:13.519Z",
|
||||
"resourceCount": 0
|
||||
},
|
||||
"resources": [],
|
||||
"stats": {
|
||||
"totalResources": 0,
|
||||
"byProtocol": {},
|
||||
"bySource": {}
|
||||
}
|
||||
}
|
||||
226
docs/README.md
@ -2,211 +2,53 @@
|
||||
|
||||
## 📚 文档结构
|
||||
|
||||
本项目采用版本化的文档管理策略,按照功能迭代分为不同版本,便于开发和维护。
|
||||
本项目文档采用清晰的模块化结构,便于快速查找和维护。
|
||||
|
||||
```
|
||||
docs/
|
||||
├── README.md # 文档总览(当前文件)
|
||||
├── v1/ # v1.0 版本文档
|
||||
│ ├── admin/ # 管理后台相关
|
||||
│ ├── backend/ # 后端架构相关
|
||||
│ ├── database/ # 数据库设计相关
|
||||
│ ├── api/ # API接口相关
|
||||
│ └── README.md # v1版本说明
|
||||
├── v2/ # v2.0 版本文档(规划中)
|
||||
│ ├── admin/ # 管理后台升级
|
||||
│ ├── backend/ # 后端微服务化
|
||||
│ ├── database/ # 数据库优化
|
||||
│ ├── api/ # GraphQL接口
|
||||
│ └── README.md # v2版本说明
|
||||
├── 原始 prd/ # 原始需求文档
|
||||
│ ├── UI设计需求文档.md
|
||||
│ ├── 前端开发文档.md
|
||||
│ ├── 后端开发文档.md
|
||||
│ └── 测试需求文档.md
|
||||
└── [传统目录结构] # 保留现有结构
|
||||
├── design/ # 设计文档
|
||||
├── api/ # API文档
|
||||
├── user-guide/ # 用户指南
|
||||
├── development/ # 开发文档
|
||||
└── deployment/ # 部署文档
|
||||
├── README.md # 文档总览(当前文件)
|
||||
├── guides/ # 📖 用户指南
|
||||
├── technical/ # 🔧 技术文档
|
||||
├── operations/ # 🚀 运维部署
|
||||
└── api/ # 📡 API文档
|
||||
```
|
||||
|
||||
## 🚀 版本规划
|
||||
## 🎯 快速导航
|
||||
|
||||
### v1.0 - 核心功能版本 (当前开发)
|
||||
### 👥 普通用户
|
||||
- [用户指南](./guides/) - 网站使用教程
|
||||
|
||||
**目标**: 实现完整的摄影作品集网站核心功能
|
||||
### 💻 开发者
|
||||
- [技术文档](./technical/) - 架构设计和开发指南
|
||||
- [API文档](./api/) - 接口说明和示例
|
||||
|
||||
#### 📋 功能范围
|
||||
- ✅ **前端展示**: Next.js 15 + React 19 静态网站
|
||||
- 🔄 **管理后台**: React + TypeScript 管理界面
|
||||
- 🔄 **后端API**: Golang + Gin + PostgreSQL
|
||||
- 🔄 **图片处理**: 多格式转换和优化
|
||||
- 🔄 **用户管理**: JWT认证和权限控制
|
||||
- 🔄 **文件存储**: MinIO/S3 对象存储
|
||||
### 🛠️ 运维人员
|
||||
- [运维部署](./operations/) - 部署配置和运维指南
|
||||
|
||||
#### 📖 v1.0 文档
|
||||
- [管理后台开发文档](./v1/admin/管理后台开发文档.md)
|
||||
- [Golang项目架构文档](./v1/backend/Golang项目架构文档.md)
|
||||
- [数据库设计文档](./v1/database/数据库设计文档.md)
|
||||
- [API接口设计文档](./v1/api/API接口设计文档.md)
|
||||
## 📁 目录说明
|
||||
|
||||
#### 🛠️ 技术栈
|
||||
```yaml
|
||||
前端:
|
||||
- Next.js 15 + React 19
|
||||
- TypeScript + Tailwind CSS
|
||||
- TanStack Query + Zustand
|
||||
| 目录 | 用途 | 目标用户 |
|
||||
|---|---|---|
|
||||
| `guides/` | 使用教程和帮助文档 | 所有用户 |
|
||||
| `technical/` | 技术架构和开发文档 | 开发者 |
|
||||
| `operations/` | 部署配置和运维文档 | 运维人员 |
|
||||
| `api/` | API接口文档 | 前后端开发者 |
|
||||
|
||||
后端:
|
||||
- Golang + Gin Framework
|
||||
- GORM + PostgreSQL
|
||||
- Redis + MinIO/S3
|
||||
## 🚀 快速开始
|
||||
|
||||
部署:
|
||||
- Docker + Docker Compose
|
||||
- Caddy Web Server
|
||||
- Gitea Actions CI/CD
|
||||
```
|
||||
### 新用户入门
|
||||
1. 查看 [用户指南](./guides/) 了解网站功能
|
||||
2. 阅读 [技术文档](./technical/) 了解项目架构
|
||||
3. 参考 [运维部署](./operations/) 进行环境搭建
|
||||
|
||||
### v2.0 - 高级功能版本 (规划中)
|
||||
### 开发者工作流
|
||||
1. **前端开发**: 查看技术文档中的前端部分
|
||||
2. **后端开发**: 查看技术文档中的后端部分
|
||||
3. **API对接**: 查看api目录下的接口文档
|
||||
4. **部署上线**: 参考运维部署文档
|
||||
|
||||
**目标**: 扩展高级功能,优化性能和用户体验
|
||||
## 📞 技术支持
|
||||
|
||||
#### 🎯 规划功能
|
||||
- 🔮 **AI增强**: 自动标签、智能分类、内容推荐
|
||||
- 🔮 **社交功能**: 评论系统、点赞收藏、用户互动
|
||||
- 🔮 **高级搜索**: ElasticSearch全文搜索、地理位置搜索
|
||||
- 🔮 **性能优化**: CDN加速、图片懒加载、缓存优化
|
||||
- 🔮 **移动端**: PWA支持、移动端优化
|
||||
- 🔮 **多语言**: 国际化支持、多语言切换
|
||||
|
||||
#### 🏗️ 架构升级
|
||||
- **微服务化**: 服务拆分,独立部署
|
||||
- **GraphQL**: 统一数据查询接口
|
||||
- **消息队列**: RabbitMQ/Redis Streams
|
||||
- **监控体系**: Prometheus + Grafana
|
||||
- **日志中心**: ELK Stack
|
||||
|
||||
## 📝 文档使用指南
|
||||
|
||||
### 开发者快速开始
|
||||
|
||||
1. **前端开发者**
|
||||
```bash
|
||||
# 阅读前端相关文档
|
||||
cd docs/原始\ prd/
|
||||
# 查看 前端开发文档.md 和 UI设计需求文档.md
|
||||
```
|
||||
|
||||
2. **后端开发者**
|
||||
```bash
|
||||
# 阅读v1版本后端文档
|
||||
cd docs/v1/
|
||||
# 依次阅读:
|
||||
# - backend/Golang项目架构文档.md
|
||||
# - database/数据库设计文档.md
|
||||
# - api/API接口设计文档.md
|
||||
```
|
||||
|
||||
3. **全栈开发者**
|
||||
```bash
|
||||
# 完整了解项目
|
||||
# 1. 先看原始需求: docs/原始\ prd/
|
||||
# 2. 再看具体实现: docs/v1/
|
||||
# 3. 了解未来规划: docs/v2/README.md
|
||||
```
|
||||
|
||||
### 管理员和产品经理
|
||||
|
||||
1. **项目概览**: 从 `docs/README.md` (本文件) 开始
|
||||
2. **功能规划**: 查看各版本的 README.md 了解功能范围
|
||||
3. **进度跟踪**: 根据文档中的状态标识了解开发进度
|
||||
|
||||
## 🎯 当前开发状态
|
||||
|
||||
### v1.0 开发进度
|
||||
|
||||
| 模块 | 状态 | 完成度 | 负责人 | 备注 |
|
||||
|------|------|---------|--------|------|
|
||||
| 前端展示 | ✅ 已完成 | 100% | - | Next.js静态网站 |
|
||||
| 管理后台 | 📋 设计中 | 20% | - | React管理界面 |
|
||||
| 后端API | 📋 设计中 | 15% | - | Golang架构设计 |
|
||||
| 数据库 | 📋 设计中 | 30% | - | PostgreSQL表设计 |
|
||||
| 图片处理 | ⏳ 待开发 | 0% | - | 多格式转换 |
|
||||
| 用户认证 | ⏳ 待开发 | 0% | - | JWT + 权限 |
|
||||
| 文件存储 | ⏳ 待开发 | 0% | - | MinIO/S3集成 |
|
||||
| 部署配置 | ⏳ 待开发 | 0% | - | Docker + CI/CD |
|
||||
|
||||
### 下一步计划
|
||||
|
||||
#### 近期计划 (1-2周)
|
||||
1. **完成管理后台前端开发**
|
||||
- React + TypeScript 管理界面
|
||||
- 照片上传和管理功能
|
||||
- 分类标签管理
|
||||
|
||||
2. **开始后端核心开发**
|
||||
- Golang项目框架搭建
|
||||
- 数据库表创建和迁移
|
||||
- 基础API接口实现
|
||||
|
||||
#### 中期计划 (1个月)
|
||||
1. **完善后端功能**
|
||||
- 用户认证和权限系统
|
||||
- 图片处理和存储
|
||||
- 完整的CRUD操作
|
||||
|
||||
2. **前后端联调**
|
||||
- API接口对接
|
||||
- 数据流测试
|
||||
- 功能完整性验证
|
||||
|
||||
#### 长期计划 (2-3个月)
|
||||
1. **系统优化**
|
||||
- 性能优化和缓存
|
||||
- 安全性加固
|
||||
- 错误处理完善
|
||||
|
||||
2. **部署上线**
|
||||
- 生产环境配置
|
||||
- CI/CD流程
|
||||
- 监控和日志
|
||||
|
||||
## 📞 联系方式
|
||||
|
||||
### 项目维护者
|
||||
- **项目负责人**: [待填写]
|
||||
- **技术负责人**: [待填写]
|
||||
- **项目地址**: https://photography.iriver.top
|
||||
- **文档维护**: Claude Code Assistant
|
||||
|
||||
### 沟通渠道
|
||||
- **技术讨论**: [GitHub Issues/Discussions]
|
||||
- **进度同步**: [项目管理工具链接]
|
||||
- **紧急联系**: [联系方式]
|
||||
|
||||
## 📋 文档维护
|
||||
|
||||
### 更新频率
|
||||
- **设计文档**: 功能变更时及时更新
|
||||
- **API文档**: 接口变更时同步更新
|
||||
- **架构文档**: 重大架构调整时更新
|
||||
- **状态跟踪**: 每周更新开发进度
|
||||
|
||||
### 贡献指南
|
||||
1. 所有文档使用 Markdown 格式
|
||||
2. 图片和图表存放在对应的 `assets/` 目录
|
||||
3. 重大更新需要更新对应的 README.md
|
||||
4. 保持文档结构清晰,便于检索
|
||||
|
||||
### 版本控制
|
||||
- 文档跟随代码版本管理
|
||||
- 重大版本升级创建新的版本目录
|
||||
- 保留历史版本文档,便于回溯
|
||||
|
||||
---
|
||||
|
||||
📅 **最后更新**: 2024-01-15
|
||||
📝 **文档版本**: v1.0
|
||||
👨💻 **维护者**: Claude Code Assistant
|
||||
- **最后更新**: 2024-12-21
|
||||
@ -1,212 +0,0 @@
|
||||
# 使用现有服务的部署指南
|
||||
|
||||
本指南适用于已有 PostgreSQL 和 Redis 服务的情况。
|
||||
|
||||
## 📋 前提条件
|
||||
|
||||
确保你的服务器上已经安装并运行:
|
||||
- **PostgreSQL** (推荐版本 14+)
|
||||
- **Redis** (推荐版本 6+)
|
||||
|
||||
## ⚙️ 配置步骤
|
||||
|
||||
### 1. 环境变量配置
|
||||
|
||||
复制环境变量模板:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
编辑 `.env` 文件,配置你的现有服务:
|
||||
|
||||
```bash
|
||||
# 数据库配置
|
||||
DB_HOST=localhost # 或你的 PostgreSQL 服务器地址
|
||||
DB_PORT=5432 # PostgreSQL 端口
|
||||
DB_NAME=photography # 数据库名称
|
||||
DB_USER=postgres # 数据库用户
|
||||
DB_PASSWORD=your_actual_password # 数据库密码
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=localhost # 或你的 Redis 服务器地址
|
||||
REDIS_PORT=6379 # Redis 端口
|
||||
REDIS_PASSWORD=your_redis_password # Redis 密码 (如果有)
|
||||
|
||||
# JWT 配置
|
||||
JWT_SECRET=your_jwt_secret_at_least_32_characters_long
|
||||
JWT_EXPIRES_IN=24h
|
||||
```
|
||||
|
||||
### 2. 数据库准备
|
||||
|
||||
连接到你的 PostgreSQL,创建数据库:
|
||||
|
||||
```sql
|
||||
-- 创建数据库
|
||||
CREATE DATABASE photography;
|
||||
|
||||
-- 创建用户 (如果需要)
|
||||
CREATE USER photography_user WITH ENCRYPTED PASSWORD 'your_password';
|
||||
GRANT ALL PRIVILEGES ON DATABASE photography TO photography_user;
|
||||
|
||||
-- 使用数据库
|
||||
\c photography;
|
||||
|
||||
-- 创建必要的扩展
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
|
||||
```
|
||||
|
||||
### 3. 后端服务部署
|
||||
|
||||
#### 方式一:Docker 部署 (推荐)
|
||||
|
||||
```bash
|
||||
# 构建并启动后端服务
|
||||
docker-compose up -d backend
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f backend
|
||||
|
||||
# 检查健康状态
|
||||
curl http://localhost:8080/health
|
||||
```
|
||||
|
||||
#### 方式二:直接运行
|
||||
|
||||
```bash
|
||||
# 进入后端目录
|
||||
cd backend
|
||||
|
||||
# 安装依赖
|
||||
go mod download
|
||||
|
||||
# 运行数据库迁移
|
||||
go run cmd/server/main.go migrate
|
||||
|
||||
# 启动服务
|
||||
go run cmd/server/main.go
|
||||
```
|
||||
|
||||
### 4. 数据库迁移
|
||||
|
||||
如果你的后端支持自动迁移,服务启动时会自动创建表结构。
|
||||
|
||||
如果需要手动迁移:
|
||||
```bash
|
||||
# 使用 Docker
|
||||
docker-compose exec backend ./main migrate
|
||||
|
||||
# 或者直接运行
|
||||
cd backend && go run cmd/server/main.go migrate
|
||||
```
|
||||
|
||||
### 5. 验证部署
|
||||
|
||||
```bash
|
||||
# 检查后端健康状态
|
||||
curl http://localhost:8080/health
|
||||
|
||||
# 检查数据库连接
|
||||
curl http://localhost:8080/api/v1/health
|
||||
|
||||
# 检查 Redis 连接 (如果有相关接口)
|
||||
curl http://localhost:8080/api/v1/cache/health
|
||||
```
|
||||
|
||||
## 🔧 常见问题
|
||||
|
||||
### 数据库连接失败
|
||||
|
||||
1. **检查数据库是否运行**:
|
||||
```bash
|
||||
sudo systemctl status postgresql
|
||||
```
|
||||
|
||||
2. **检查连接权限**:
|
||||
```bash
|
||||
psql -h localhost -U postgres -d photography
|
||||
```
|
||||
|
||||
3. **检查防火墙**:
|
||||
```bash
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
### Redis 连接失败
|
||||
|
||||
1. **检查 Redis 状态**:
|
||||
```bash
|
||||
sudo systemctl status redis
|
||||
```
|
||||
|
||||
2. **测试 Redis 连接**:
|
||||
```bash
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
### 容器网络问题
|
||||
|
||||
如果容器无法访问宿主机服务,尝试:
|
||||
|
||||
1. **使用 host 网络模式** (已配置)
|
||||
2. **检查服务绑定地址**:
|
||||
- PostgreSQL: 确保监听 `0.0.0.0:5432` 或 `localhost:5432`
|
||||
- Redis: 确保监听 `0.0.0.0:6379` 或 `localhost:6379`
|
||||
|
||||
## 📊 监控和维护
|
||||
|
||||
### 日志查看
|
||||
|
||||
```bash
|
||||
# 后端日志
|
||||
docker-compose logs -f backend
|
||||
|
||||
# 系统日志
|
||||
journalctl -u your-service-name -f
|
||||
```
|
||||
|
||||
### 性能监控
|
||||
|
||||
```bash
|
||||
# 运行监控脚本
|
||||
./scripts/monitor.sh
|
||||
|
||||
# 手动检查资源使用
|
||||
docker stats photography_backend
|
||||
```
|
||||
|
||||
### 备份
|
||||
|
||||
```bash
|
||||
# 手动备份数据库
|
||||
./scripts/backup.sh
|
||||
|
||||
# 或者使用 Docker 备份服务
|
||||
docker-compose --profile backup up backup
|
||||
```
|
||||
|
||||
## 🚀 自动化部署
|
||||
|
||||
如果你使用 CI/CD,确保在部署环境中设置正确的环境变量:
|
||||
|
||||
```yaml
|
||||
# .github/workflows 或 .gitea/workflows
|
||||
env:
|
||||
DB_HOST: your-db-host
|
||||
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
|
||||
REDIS_HOST: your-redis-host
|
||||
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }}
|
||||
```
|
||||
|
||||
## 🔒 安全建议
|
||||
|
||||
1. **使用强密码**
|
||||
2. **限制数据库访问**:只允许必要的 IP 连接
|
||||
3. **启用 SSL/TLS**:用于数据库和 Redis 连接
|
||||
4. **定期更新**:保持服务和依赖的最新版本
|
||||
5. **监控日志**:定期检查异常访问
|
||||
|
||||
---
|
||||
|
||||
这种配置更加轻量和实用,避免了重复安装已有服务的资源浪费。
|
||||
@ -1,760 +0,0 @@
|
||||
# 摄影作品集项目部署文档
|
||||
|
||||
本文档详细说明了摄影作品集项目的完整部署流程,包括前端、管理后台、后端 API 和数据库的部署配置。
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [系统要求](#系统要求)
|
||||
- [环境配置](#环境配置)
|
||||
- [后端部署](#后端部署)
|
||||
- [前端部署](#前端部署)
|
||||
- [管理后台部署](#管理后台部署)
|
||||
- [数据库配置](#数据库配置)
|
||||
- [Web 服务器配置](#web-服务器配置)
|
||||
- [SSL 证书配置](#ssl-证书配置)
|
||||
- [监控和备份](#监控和备份)
|
||||
- [故障排除](#故障排除)
|
||||
|
||||
## 🖥️ 系统要求
|
||||
|
||||
### 硬件要求
|
||||
- **CPU**: 2 核心以上
|
||||
- **内存**: 4GB 以上 (推荐 8GB)
|
||||
- **存储**: 20GB 以上 SSD 存储
|
||||
- **网络**: 稳定的互联网连接
|
||||
|
||||
### 软件要求
|
||||
- **操作系统**: Ubuntu 20.04 LTS / CentOS 8 / Debian 11
|
||||
- **Docker**: 20.10 或更高版本
|
||||
- **Docker Compose**: 2.0 或更高版本
|
||||
- **Git**: 2.20 或更高版本
|
||||
- **域名**: 用于生产环境部署
|
||||
|
||||
## ⚙️ 环境配置
|
||||
|
||||
### 1. 安装 Docker 和 Docker Compose
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# 安装 Docker Compose
|
||||
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
|
||||
|
||||
# 验证安装
|
||||
docker --version
|
||||
docker-compose --version
|
||||
```
|
||||
|
||||
### 2. 克隆项目仓库
|
||||
|
||||
```bash
|
||||
git clone <repository-url> photography
|
||||
cd photography
|
||||
```
|
||||
|
||||
### 3. 创建环境变量文件
|
||||
|
||||
```bash
|
||||
# 复制环境变量模板
|
||||
cp .env.example .env
|
||||
|
||||
# 编辑环境变量
|
||||
nano .env
|
||||
```
|
||||
|
||||
## 🚀 后端部署
|
||||
|
||||
### 1. 后端 Docker 配置
|
||||
|
||||
查看后端 Dockerfile:
|
||||
|
||||
```dockerfile
|
||||
# backend/Dockerfile
|
||||
FROM golang:1.21-alpine AS builder
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装依赖
|
||||
RUN apk add --no-cache git ca-certificates tzdata
|
||||
|
||||
# 复制 go mod 文件
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# 复制源代码
|
||||
COPY . .
|
||||
|
||||
# 构建应用
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main cmd/server/main.go
|
||||
|
||||
# 生产环境镜像
|
||||
FROM alpine:latest
|
||||
|
||||
# 安装必要的包
|
||||
RUN apk --no-cache add ca-certificates wget
|
||||
|
||||
# 创建用户
|
||||
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 从构建阶段复制文件
|
||||
COPY --from=builder /app/main .
|
||||
COPY --from=builder /app/configs ./configs
|
||||
COPY --from=builder /app/migrations ./migrations
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p uploads logs && chown -R appuser:appgroup /app
|
||||
|
||||
# 切换到非 root 用户
|
||||
USER appuser
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8080
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
|
||||
|
||||
# 启动命令
|
||||
CMD ["./main"]
|
||||
```
|
||||
|
||||
### 2. 后端 Docker Compose 服务
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml - 后端部分
|
||||
services:
|
||||
# PostgreSQL 数据库
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: photography_postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${DB_NAME:-photography}
|
||||
POSTGRES_USER: ${DB_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./backend/migrations:/docker-entrypoint-initdb.d
|
||||
ports:
|
||||
- "127.0.0.1:5432:5432"
|
||||
networks:
|
||||
- photography_network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-photography}"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
# Redis 缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: photography_redis
|
||||
restart: unless-stopped
|
||||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
ports:
|
||||
- "127.0.0.1:6379:6379"
|
||||
networks:
|
||||
- photography_network
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
# 后端 API 服务
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: photography_backend
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
# 数据库配置
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${DB_NAME:-photography}
|
||||
DB_USER: ${DB_USER:-postgres}
|
||||
DB_PASSWORD: ${DB_PASSWORD}
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
||||
|
||||
# JWT 配置
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-24h}
|
||||
|
||||
# 服务器配置
|
||||
PORT: 8080
|
||||
GIN_MODE: release
|
||||
|
||||
# 文件存储配置
|
||||
STORAGE_TYPE: ${STORAGE_TYPE:-local}
|
||||
STORAGE_PATH: /app/uploads
|
||||
MAX_UPLOAD_SIZE: ${MAX_UPLOAD_SIZE:-10MB}
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||
LOG_FORMAT: json
|
||||
volumes:
|
||||
- ./backend/uploads:/app/uploads
|
||||
- ./backend/logs:/app/logs
|
||||
- ./backend/configs:/app/configs
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080"
|
||||
networks:
|
||||
- photography_network
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 60s
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
photography_network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
```
|
||||
|
||||
### 3. 启动后端服务
|
||||
|
||||
```bash
|
||||
# 构建并启动后端服务
|
||||
docker-compose up -d postgres redis
|
||||
docker-compose up -d backend
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f backend
|
||||
|
||||
# 验证服务状态
|
||||
curl http://localhost:8080/health
|
||||
```
|
||||
|
||||
## 🌐 前端部署
|
||||
|
||||
### 1. 前端构建配置
|
||||
|
||||
```bash
|
||||
# 进入前端目录
|
||||
cd frontend/
|
||||
|
||||
# 安装依赖
|
||||
bun install
|
||||
|
||||
# 构建生产版本
|
||||
bun run build
|
||||
|
||||
# 验证构建结果
|
||||
ls -la out/
|
||||
```
|
||||
|
||||
### 2. 前端部署脚本
|
||||
|
||||
创建前端部署脚本:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# scripts/deploy-frontend.sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 开始部署前端..."
|
||||
|
||||
# 配置变量
|
||||
FRONTEND_DIR="/home/gitea/www/photography"
|
||||
BACKUP_DIR="/home/gitea/backups/photography-frontend"
|
||||
BUILD_DIR="./frontend/out"
|
||||
|
||||
# 创建备份
|
||||
echo "📦 创建当前版本备份..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
if [ -d "$FRONTEND_DIR" ]; then
|
||||
tar -czf "$BACKUP_DIR/frontend-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$FRONTEND_DIR" .
|
||||
fi
|
||||
|
||||
# 创建部署目录
|
||||
echo "📁 准备部署目录..."
|
||||
mkdir -p "$FRONTEND_DIR"
|
||||
|
||||
# 部署新版本
|
||||
echo "🔄 部署新版本..."
|
||||
rsync -av --delete "$BUILD_DIR/" "$FRONTEND_DIR/"
|
||||
|
||||
# 设置权限
|
||||
echo "🔐 设置文件权限..."
|
||||
chown -R gitea:gitea "$FRONTEND_DIR"
|
||||
chmod -R 755 "$FRONTEND_DIR"
|
||||
|
||||
# 清理旧备份 (保留最近5个)
|
||||
echo "🧹 清理旧备份..."
|
||||
cd "$BACKUP_DIR"
|
||||
ls -t frontend-*.tar.gz | tail -n +6 | xargs -r rm
|
||||
|
||||
echo "✅ 前端部署完成!"
|
||||
echo "🌐 访问地址: https://photography.iriver.top"
|
||||
```
|
||||
|
||||
## 🛠️ 管理后台部署
|
||||
|
||||
### 1. 管理后台构建配置
|
||||
|
||||
```bash
|
||||
# 进入管理后台目录
|
||||
cd admin/
|
||||
|
||||
# 安装依赖
|
||||
npm install
|
||||
|
||||
# 构建生产版本
|
||||
npm run build
|
||||
|
||||
# 验证构建结果
|
||||
ls -la dist/
|
||||
```
|
||||
|
||||
### 2. 管理后台部署脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# scripts/deploy-admin.sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 开始部署管理后台..."
|
||||
|
||||
# 配置变量
|
||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
||||
BACKUP_DIR="/home/gitea/backups/photography-admin"
|
||||
BUILD_DIR="./admin/dist"
|
||||
|
||||
# 创建备份
|
||||
echo "📦 创建当前版本备份..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
if [ -d "$ADMIN_DIR" ]; then
|
||||
tar -czf "$BACKUP_DIR/admin-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$ADMIN_DIR" .
|
||||
fi
|
||||
|
||||
# 创建部署目录
|
||||
echo "📁 准备部署目录..."
|
||||
mkdir -p "$ADMIN_DIR"
|
||||
|
||||
# 部署新版本
|
||||
echo "🔄 部署新版本..."
|
||||
rsync -av --delete "$BUILD_DIR/" "$ADMIN_DIR/"
|
||||
|
||||
# 设置权限
|
||||
echo "🔐 设置文件权限..."
|
||||
chown -R gitea:gitea "$ADMIN_DIR"
|
||||
chmod -R 755 "$ADMIN_DIR"
|
||||
|
||||
# 清理旧备份 (保留最近5个)
|
||||
echo "🧹 清理旧备份..."
|
||||
cd "$BACKUP_DIR"
|
||||
ls -t admin-*.tar.gz | tail -n +6 | xargs -r rm
|
||||
|
||||
echo "✅ 管理后台部署完成!"
|
||||
echo "🌐 访问地址: https://admin.photography.iriver.top"
|
||||
```
|
||||
|
||||
## 🗄️ 数据库配置
|
||||
|
||||
### 1. 数据库初始化
|
||||
|
||||
```sql
|
||||
-- 创建数据库
|
||||
CREATE DATABASE photography;
|
||||
CREATE USER photography_user WITH ENCRYPTED PASSWORD 'your_password';
|
||||
GRANT ALL PRIVILEGES ON DATABASE photography TO photography_user;
|
||||
|
||||
-- 使用数据库
|
||||
\c photography;
|
||||
|
||||
-- 创建必要的扩展
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
|
||||
|
||||
-- 设置时区
|
||||
SET timezone = 'Asia/Shanghai';
|
||||
```
|
||||
|
||||
### 2. 数据库备份脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# scripts/backup.sh
|
||||
|
||||
set -e
|
||||
|
||||
# 配置变量
|
||||
DB_HOST="${DB_HOST:-postgres}"
|
||||
DB_NAME="${DB_NAME:-photography}"
|
||||
DB_USER="${DB_USER:-postgres}"
|
||||
BACKUP_DIR="/backups"
|
||||
DATE=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
echo "🗄️ 开始数据库备份..."
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 执行备份
|
||||
pg_dump -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" \
|
||||
--no-password --verbose --clean --no-acl --no-owner \
|
||||
-f "$BACKUP_DIR/photography-$DATE.sql"
|
||||
|
||||
# 压缩备份文件
|
||||
gzip "$BACKUP_DIR/photography-$DATE.sql"
|
||||
|
||||
# 清理旧备份 (保留最近7天)
|
||||
find "$BACKUP_DIR" -name "photography-*.sql.gz" -mtime +7 -delete
|
||||
|
||||
echo "✅ 数据库备份完成: photography-$DATE.sql.gz"
|
||||
```
|
||||
|
||||
## 🌐 Web 服务器配置
|
||||
|
||||
### Caddy 配置文件
|
||||
|
||||
```caddyfile
|
||||
# docs/deployment/Caddyfile
|
||||
|
||||
# 前端网站
|
||||
photography.iriver.top {
|
||||
# 根目录
|
||||
root * /home/gitea/www/photography
|
||||
|
||||
# 静态文件服务
|
||||
file_server
|
||||
|
||||
# SPA 路由支持
|
||||
try_files {path} /index.html
|
||||
|
||||
# 压缩
|
||||
encode gzip
|
||||
|
||||
# 缓存配置
|
||||
header {
|
||||
# 静态资源缓存
|
||||
Cache-Control "public, max-age=31536000" {
|
||||
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2
|
||||
}
|
||||
|
||||
# HTML 文件不缓存
|
||||
Cache-Control "no-cache" {
|
||||
path *.html
|
||||
}
|
||||
|
||||
# 安全头
|
||||
X-Frame-Options "DENY"
|
||||
X-Content-Type-Options "nosniff"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
}
|
||||
|
||||
# 日志
|
||||
log {
|
||||
output file /var/log/caddy/photography.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# 管理后台
|
||||
admin.photography.iriver.top {
|
||||
# 根目录
|
||||
root * /home/gitea/www/photography-admin
|
||||
|
||||
# 静态文件服务
|
||||
file_server
|
||||
|
||||
# SPA 路由支持
|
||||
try_files {path} /index.html
|
||||
|
||||
# 压缩
|
||||
encode gzip
|
||||
|
||||
# 基本认证 (可选)
|
||||
# basicauth {
|
||||
# admin $2a$14$encrypted_password_hash
|
||||
# }
|
||||
|
||||
# 缓存配置
|
||||
header {
|
||||
Cache-Control "public, max-age=31536000" {
|
||||
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2
|
||||
}
|
||||
Cache-Control "no-cache" {
|
||||
path *.html
|
||||
}
|
||||
X-Frame-Options "SAMEORIGIN"
|
||||
X-Content-Type-Options "nosniff"
|
||||
}
|
||||
|
||||
# 日志
|
||||
log {
|
||||
output file /var/log/caddy/admin.photography.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# API 服务
|
||||
api.photography.iriver.top {
|
||||
# 反向代理到后端服务
|
||||
reverse_proxy localhost:8080 {
|
||||
# 健康检查
|
||||
health_uri /health
|
||||
health_interval 30s
|
||||
health_timeout 10s
|
||||
|
||||
# 请求头
|
||||
header_up Host {upstream_hostport}
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
}
|
||||
|
||||
# CORS 处理
|
||||
header {
|
||||
Access-Control-Allow-Origin "https://photography.iriver.top, https://admin.photography.iriver.top"
|
||||
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
||||
Access-Control-Allow-Headers "Content-Type, Authorization"
|
||||
Access-Control-Max-Age "86400"
|
||||
}
|
||||
|
||||
# 预检请求处理
|
||||
@options method OPTIONS
|
||||
respond @options 204
|
||||
|
||||
# 上传文件大小限制
|
||||
request_body {
|
||||
max_size 10MB
|
||||
}
|
||||
|
||||
# 日志
|
||||
log {
|
||||
output file /var/log/caddy/api.photography.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# 全局配置
|
||||
{
|
||||
# 自动 HTTPS
|
||||
auto_https on
|
||||
|
||||
# Let's Encrypt 邮箱
|
||||
email admin@iriver.top
|
||||
|
||||
# 日志级别
|
||||
log {
|
||||
level INFO
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔒 SSL 证书配置
|
||||
|
||||
Caddy 会自动处理 SSL 证书,但也可以手动配置:
|
||||
|
||||
```bash
|
||||
# 手动获取证书 (如果需要)
|
||||
certbot certonly --webroot -w /var/www/html -d photography.iriver.top -d admin.photography.iriver.top -d api.photography.iriver.top
|
||||
|
||||
# 设置自动续期
|
||||
echo "0 3 * * * certbot renew --quiet && systemctl reload caddy" | crontab -
|
||||
```
|
||||
|
||||
## 📊 监控和备份
|
||||
|
||||
### 1. 系统监控脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# scripts/monitor.sh
|
||||
|
||||
# 检查服务状态
|
||||
check_service() {
|
||||
local service=$1
|
||||
local url=$2
|
||||
|
||||
echo "检查 $service..."
|
||||
if curl -f -s "$url" > /dev/null; then
|
||||
echo "✅ $service 正常运行"
|
||||
else
|
||||
echo "❌ $service 服务异常"
|
||||
# 发送告警 (可集成邮件、微信等)
|
||||
# send_alert "$service 服务异常"
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查磁盘空间
|
||||
check_disk() {
|
||||
local usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
|
||||
echo "磁盘使用率: $usage%"
|
||||
|
||||
if [ "$usage" -gt 80 ]; then
|
||||
echo "⚠️ 磁盘空间不足"
|
||||
# send_alert "磁盘空间不足: $usage%"
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查内存使用
|
||||
check_memory() {
|
||||
local usage=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
|
||||
echo "内存使用率: $usage%"
|
||||
}
|
||||
|
||||
# 执行检查
|
||||
echo "🔍 开始系统监控..."
|
||||
check_service "前端" "https://photography.iriver.top"
|
||||
check_service "管理后台" "https://admin.photography.iriver.top"
|
||||
check_service "API" "https://api.photography.iriver.top/health"
|
||||
check_disk
|
||||
check_memory
|
||||
echo "✅ 监控检查完成"
|
||||
```
|
||||
|
||||
### 2. 自动备份任务
|
||||
|
||||
```bash
|
||||
# 设置定时任务
|
||||
crontab -e
|
||||
|
||||
# 添加以下内容:
|
||||
# 每天凌晨2点备份数据库
|
||||
0 2 * * * /path/to/photography/scripts/backup.sh
|
||||
|
||||
# 每周日凌晨3点重启服务 (可选)
|
||||
0 3 * * 0 cd /path/to/photography && docker-compose restart
|
||||
|
||||
# 每小时检查一次服务状态
|
||||
0 * * * * /path/to/photography/scripts/monitor.sh
|
||||
```
|
||||
|
||||
## 🐛 故障排除
|
||||
|
||||
### 常见问题和解决方案
|
||||
|
||||
#### 1. 后端服务无法启动
|
||||
```bash
|
||||
# 查看日志
|
||||
docker-compose logs backend
|
||||
|
||||
# 检查配置
|
||||
docker-compose config
|
||||
|
||||
# 重新构建
|
||||
docker-compose build backend --no-cache
|
||||
```
|
||||
|
||||
#### 2. 数据库连接失败
|
||||
```bash
|
||||
# 检查数据库状态
|
||||
docker-compose ps postgres
|
||||
|
||||
# 检查数据库日志
|
||||
docker-compose logs postgres
|
||||
|
||||
# 手动连接测试
|
||||
docker-compose exec postgres psql -U postgres -d photography
|
||||
```
|
||||
|
||||
#### 3. 前端/管理后台访问异常
|
||||
```bash
|
||||
# 检查文件权限
|
||||
ls -la /home/gitea/www/photography/
|
||||
ls -la /home/gitea/www/photography-admin/
|
||||
|
||||
# 检查 Caddy 配置
|
||||
caddy validate --config /etc/caddy/Caddyfile
|
||||
|
||||
# 重新加载 Caddy
|
||||
systemctl reload caddy
|
||||
```
|
||||
|
||||
#### 4. SSL 证书问题
|
||||
```bash
|
||||
# 检查证书状态
|
||||
curl -I https://photography.iriver.top
|
||||
|
||||
# 查看 Caddy 日志
|
||||
tail -f /var/log/caddy/photography.log
|
||||
|
||||
# 手动重新申请证书
|
||||
systemctl stop caddy
|
||||
caddy run --config /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
### 日志文件位置
|
||||
- **后端日志**: `./backend/logs/`
|
||||
- **Caddy 日志**: `/var/log/caddy/`
|
||||
- **数据库日志**: `docker-compose logs postgres`
|
||||
- **系统日志**: `/var/log/syslog`
|
||||
|
||||
## 🚀 部署命令速查
|
||||
|
||||
```bash
|
||||
# 完整部署流程
|
||||
git pull origin main
|
||||
cd photography
|
||||
|
||||
# 后端部署
|
||||
docker-compose build backend
|
||||
docker-compose up -d
|
||||
|
||||
# 前端部署
|
||||
cd frontend && bun run build && cd ..
|
||||
./scripts/deploy-frontend.sh
|
||||
|
||||
# 管理后台部署
|
||||
cd admin && npm run build && cd ..
|
||||
./scripts/deploy-admin.sh
|
||||
|
||||
# 重启 Web 服务器
|
||||
sudo systemctl reload caddy
|
||||
|
||||
# 检查服务状态
|
||||
docker-compose ps
|
||||
curl https://photography.iriver.top
|
||||
curl https://admin.photography.iriver.top
|
||||
curl https://api.photography.iriver.top/health
|
||||
```
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如果在部署过程中遇到问题,请:
|
||||
|
||||
1. 查看相关日志文件
|
||||
2. 检查系统资源使用情况
|
||||
3. 验证配置文件语法
|
||||
4. 联系技术支持团队
|
||||
|
||||
---
|
||||
|
||||
📝 **文档版本**: v1.0
|
||||
🕒 **最后更新**: 2024年
|
||||
👥 **维护团队**: 摄影作品集项目组
|
||||
0
ui/.gitignore → docs/ui/.gitignore
vendored
0
ui/pnpm-lock.yaml → docs/ui/pnpm-lock.yaml
generated
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 568 B |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@ -1,289 +0,0 @@
|
||||
# 摄影作品集网站 v1.0 - 开发文档
|
||||
|
||||
## 📋 v1.0 版本概述
|
||||
|
||||
v1.0 是摄影作品集网站的核心功能版本,实现了完整的摄影作品展示、管理和用户交互功能。
|
||||
|
||||
### 🎯 版本目标
|
||||
- 构建稳定可靠的摄影作品集展示平台
|
||||
- 实现高效的照片管理和处理系统
|
||||
- 提供完善的用户认证和权限控制
|
||||
- 支持多种图片格式和优化策略
|
||||
|
||||
### 📅 开发周期
|
||||
- **开始时间**: 2024-01-15
|
||||
- **预计完成**: 2024-04-15
|
||||
- **当前状态**: 设计阶段
|
||||
|
||||
## 🏗️ 架构设计
|
||||
|
||||
### 整体架构
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 用户界面层 │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ 前端展示网站 │ │ 管理后台界面 │ │
|
||||
│ │ (Next.js) │ │ (React) │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ API 接口层 │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ RESTful API │ │
|
||||
│ │ (Gin Framework) │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 业务逻辑层 │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ 照片管理 │ │ 用户认证 │ │ 文件处理 │ │
|
||||
│ │ 服务 │ │ 服务 │ │ 服务 │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 数据访问层 │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ PostgreSQL │ │ Redis │ │ MinIO/S3 │ │
|
||||
│ │ 数据库 │ │ 缓存 │ │ 对象存储 │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 技术选型
|
||||
```yaml
|
||||
前端技术栈:
|
||||
- Framework: Next.js 15 + React 19
|
||||
- Language: TypeScript
|
||||
- Styling: Tailwind CSS
|
||||
- State: TanStack Query + Zustand
|
||||
- UI Components: shadcn/ui + Radix UI
|
||||
|
||||
后端技术栈:
|
||||
- Framework: Golang + Gin
|
||||
- Database: PostgreSQL 15
|
||||
- Cache: Redis 7
|
||||
- ORM: GORM
|
||||
- Authentication: JWT
|
||||
- Image Processing: libvips/bimg
|
||||
|
||||
存储和部署:
|
||||
- Object Storage: MinIO/AWS S3
|
||||
- Web Server: Caddy
|
||||
- Container: Docker + Docker Compose
|
||||
- CI/CD: Gitea Actions
|
||||
```
|
||||
|
||||
## 📚 文档导航
|
||||
|
||||
### 核心设计文档
|
||||
1. **[管理后台开发文档](./admin/管理后台开发文档.md)**
|
||||
- 功能模块详细设计
|
||||
- 界面交互规范
|
||||
- 组件架构设计
|
||||
|
||||
2. **[Golang项目架构文档](./backend/Golang项目架构文档.md)**
|
||||
- 项目结构设计
|
||||
- 分层架构实现
|
||||
- 依赖注入配置
|
||||
|
||||
3. **[数据库设计文档](./database/数据库设计文档.md)**
|
||||
- 表结构设计
|
||||
- 索引优化策略
|
||||
- 数据迁移方案
|
||||
|
||||
4. **[API接口设计文档](./api/API接口设计文档.md)**
|
||||
- RESTful API规范
|
||||
- 接口定义和示例
|
||||
- 错误处理机制
|
||||
|
||||
### 开发指南
|
||||
- **前端开发**: 参考 [前端开发文档](../原始\ prd/前端开发文档.md)
|
||||
- **后端开发**: 参考 [后端开发文档](../原始\ prd/后端开发文档.md)
|
||||
- **UI设计**: 参考 [UI设计需求文档](../原始\ prd/UI设计需求文档.md)
|
||||
|
||||
## 🚀 功能特性
|
||||
|
||||
### 核心功能
|
||||
- ✅ **前端展示**
|
||||
- 响应式照片网格展示
|
||||
- 时间线视图
|
||||
- 照片详情模态框
|
||||
- 分类和标签筛选
|
||||
|
||||
- 🔄 **管理后台**
|
||||
- 照片批量上传和管理
|
||||
- 分类和标签管理
|
||||
- 用户权限控制
|
||||
- 系统设置配置
|
||||
|
||||
- 🔄 **后端API**
|
||||
- 完整的CRUD操作
|
||||
- 文件上传处理
|
||||
- 图片多格式转换
|
||||
- 用户认证授权
|
||||
|
||||
- 🔄 **数据管理**
|
||||
- PostgreSQL关系数据库
|
||||
- Redis缓存加速
|
||||
- MinIO对象存储
|
||||
- 数据备份恢复
|
||||
|
||||
### 性能特性
|
||||
- **图片优化**: 多格式转换 (JPG, WebP, AVIF)
|
||||
- **懒加载**: 视口外图片延迟加载
|
||||
- **缓存策略**: 多级缓存提升响应速度
|
||||
- **CDN加速**: 静态资源分发优化
|
||||
|
||||
### 安全特性
|
||||
- **用户认证**: JWT令牌机制
|
||||
- **权限控制**: 基于角色的访问控制
|
||||
- **数据加密**: 敏感数据加密存储
|
||||
- **API限流**: 防止接口滥用
|
||||
|
||||
## 📈 开发进度
|
||||
|
||||
### 当前状态
|
||||
|
||||
| 模块 | 设计 | 开发 | 测试 | 部署 | 完成度 |
|
||||
|------|------|------|------|------|--------|
|
||||
| 前端展示 | ✅ | ✅ | ✅ | ✅ | 100% |
|
||||
| 管理后台 | ✅ | ⏳ | ⏳ | ⏳ | 20% |
|
||||
| 后端API | ✅ | ⏳ | ⏳ | ⏳ | 15% |
|
||||
| 数据库 | ✅ | ⏳ | ⏳ | ⏳ | 30% |
|
||||
| 图片处理 | ✅ | ⏳ | ⏳ | ⏳ | 10% |
|
||||
| 用户认证 | ✅ | ⏳ | ⏳ | ⏳ | 5% |
|
||||
| 文件存储 | ✅ | ⏳ | ⏳ | ⏳ | 5% |
|
||||
| 部署配置 | ✅ | ⏳ | ⏳ | ⏳ | 10% |
|
||||
|
||||
### 里程碑计划
|
||||
|
||||
#### 第一阶段 (2024-01-15 ~ 2024-02-15)
|
||||
- [x] 完成技术选型和架构设计
|
||||
- [x] 完成详细设计文档编写
|
||||
- [ ] 搭建开发环境和基础框架
|
||||
- [ ] 实现管理后台核心界面
|
||||
|
||||
#### 第二阶段 (2024-02-15 ~ 2024-03-15)
|
||||
- [ ] 完成后端API核心功能
|
||||
- [ ] 实现数据库表结构和迁移
|
||||
- [ ] 完成用户认证和权限系统
|
||||
- [ ] 实现图片上传和处理功能
|
||||
|
||||
#### 第三阶段 (2024-03-15 ~ 2024-04-15)
|
||||
- [ ] 完成前后端功能对接
|
||||
- [ ] 实现文件存储和CDN配置
|
||||
- [ ] 完成系统测试和性能优化
|
||||
- [ ] 部署到生产环境
|
||||
|
||||
## 🔧 开发环境
|
||||
|
||||
### 环境要求
|
||||
```yaml
|
||||
开发环境:
|
||||
- Node.js: 18+
|
||||
- Golang: 1.21+
|
||||
- PostgreSQL: 15+
|
||||
- Redis: 7+
|
||||
- Docker: 24+
|
||||
|
||||
推荐配置:
|
||||
- 内存: 8GB+
|
||||
- 硬盘: 50GB+
|
||||
- 操作系统: macOS/Linux
|
||||
```
|
||||
|
||||
### 快速开始
|
||||
```bash
|
||||
# 1. 克隆项目
|
||||
git clone <repository>
|
||||
cd photography
|
||||
|
||||
# 2. 前端开发
|
||||
cd frontend
|
||||
make setup
|
||||
make dev
|
||||
|
||||
# 3. 后端开发 (开发中)
|
||||
cd backend
|
||||
make setup
|
||||
make dev
|
||||
|
||||
# 4. 数据库初始化
|
||||
make migrate-up
|
||||
```
|
||||
|
||||
## 🧪 测试策略
|
||||
|
||||
### 测试类型
|
||||
- **单元测试**: 核心业务逻辑测试
|
||||
- **集成测试**: API接口和数据库交互测试
|
||||
- **端到端测试**: 完整用户流程测试
|
||||
- **性能测试**: 系统负载和响应时间测试
|
||||
|
||||
### 测试覆盖率目标
|
||||
- **后端代码**: 80%+
|
||||
- **前端组件**: 70%+
|
||||
- **API接口**: 90%+
|
||||
|
||||
## 📊 质量保证
|
||||
|
||||
### 代码质量
|
||||
- **代码规范**: ESLint + Prettier (前端), golangci-lint (后端)
|
||||
- **类型检查**: TypeScript 严格模式
|
||||
- **代码审查**: Pull Request必须通过审查
|
||||
- **自动化测试**: CI/CD流水线集成
|
||||
|
||||
### 性能指标
|
||||
- **页面加载时间**: < 3s
|
||||
- **图片处理时间**: < 10s
|
||||
- **API响应时间**: < 500ms
|
||||
- **数据库查询**: < 100ms
|
||||
|
||||
## 🔍 监控和日志
|
||||
|
||||
### 应用监控
|
||||
- **错误监控**: 应用错误和异常追踪
|
||||
- **性能监控**: 响应时间和资源使用
|
||||
- **用户行为**: 用户操作和页面访问统计
|
||||
|
||||
### 日志管理
|
||||
- **结构化日志**: JSON格式日志记录
|
||||
- **日志级别**: Debug, Info, Warn, Error
|
||||
- **日志轮转**: 按大小和时间自动轮转
|
||||
|
||||
## 📋 发布计划
|
||||
|
||||
### 发布流程
|
||||
1. **功能开发**: 在feature分支开发
|
||||
2. **代码审查**: 创建Pull Request
|
||||
3. **测试验证**: 自动化测试通过
|
||||
4. **合并主分支**: 合并到main分支
|
||||
5. **部署发布**: 自动部署到生产环境
|
||||
|
||||
### 版本管理
|
||||
- **版本号**: 遵循语义化版本规范
|
||||
- **发布说明**: 详细的变更日志
|
||||
- **回滚策略**: 快速回滚机制
|
||||
|
||||
## 💡 未来规划
|
||||
|
||||
### v1.1 增强功能
|
||||
- 移动端PWA支持
|
||||
- 图片水印功能
|
||||
- 批量操作优化
|
||||
- 搜索功能增强
|
||||
|
||||
### v1.2 扩展功能
|
||||
- 评论系统
|
||||
- 社交分享
|
||||
- 数据导出
|
||||
- 多语言支持
|
||||
|
||||
### v2.0 升级计划
|
||||
- 微服务架构
|
||||
- AI智能标签
|
||||
- 实时通知
|
||||
- 高级分析
|
||||
|
||||
---
|
||||
|
||||
📅 **最后更新**: 2024-01-15
|
||||
📝 **文档版本**: v1.0
|
||||
👨💻 **维护者**: Claude Code Assistant
|
||||