feat: Add deployment scripts, Docker configuration, and documentation for Cloud MCP project
This commit is contained in:
20
.dockerignore
Normal file
20
.dockerignore
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
data
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
tests
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
28
.github/workflows/deploy.yml
vendored
Normal file
28
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: Deploy to Server
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Deploy to server
|
||||||
|
uses: appleboy/ssh-action@master
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USERNAME }}
|
||||||
|
key: ${{ secrets.SERVER_SSH_KEY }}
|
||||||
|
script: |
|
||||||
|
cd /path/to/cloud-mcp
|
||||||
|
git pull origin main
|
||||||
|
./deploy.sh --rebuild
|
||||||
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,3 +9,7 @@ data/
|
|||||||
*.sqlite
|
*.sqlite
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
|
|
||||||
|
# Deployment
|
||||||
|
deploy.log
|
||||||
|
*.log
|
||||||
|
|
||||||
|
|||||||
308
DEPLOY.md
Normal file
308
DEPLOY.md
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
# 部署文档
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
本项目支持使用 Docker 进行部署,可以通过手动脚本或 Gitea Webhook 自动部署。
|
||||||
|
|
||||||
|
## 前置要求
|
||||||
|
|
||||||
|
- Docker 和 Docker Compose 已安装
|
||||||
|
- Git 已安装
|
||||||
|
- 服务器有足够的资源(建议至少 512MB 内存)
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 1. 克隆项目到服务器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <your-gitea-repo-url> /path/to/cloud-mcp
|
||||||
|
cd /path/to/cloud-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 配置环境变量
|
||||||
|
|
||||||
|
复制环境变量模板并编辑:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp env.template .env
|
||||||
|
nano .env # 或使用你喜欢的编辑器
|
||||||
|
```
|
||||||
|
|
||||||
|
配置必要的环境变量(NAS、服务器、路由器等)。
|
||||||
|
|
||||||
|
### 3. 创建数据目录
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p data
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 首次部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy.sh --rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
## 部署方式
|
||||||
|
|
||||||
|
### 方式一:手动部署脚本
|
||||||
|
|
||||||
|
使用 `deploy.sh` 脚本进行手动部署:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 基本部署(使用缓存)
|
||||||
|
./deploy.sh
|
||||||
|
|
||||||
|
# 从 Git 拉取最新代码并部署
|
||||||
|
./deploy.sh --pull
|
||||||
|
|
||||||
|
# 强制重新构建(不使用缓存)
|
||||||
|
./deploy.sh --rebuild
|
||||||
|
|
||||||
|
# 拉取代码并重新构建
|
||||||
|
./deploy.sh --pull --rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式二:Gitea Webhook 自动部署
|
||||||
|
|
||||||
|
#### 1. 配置部署脚本
|
||||||
|
|
||||||
|
编辑 `deploy-gitea.sh`,更新以下变量:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PROJECT_DIR="/path/to/cloud-mcp" # 你的项目路径
|
||||||
|
BRANCH="main" # 或 "master"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 在 Gitea 中配置 Webhook
|
||||||
|
|
||||||
|
1. 进入仓库:**Settings** -> **Webhooks** -> **Add Webhook**
|
||||||
|
2. 配置如下:
|
||||||
|
- **Target URL**: `http://your-server:port/gitea-webhook` (如果使用 webhook 服务器)
|
||||||
|
- 或者直接在服务器上设置 Git Hook
|
||||||
|
3. **Content Type**: `application/json`
|
||||||
|
4. **Secret**: (可选) 设置一个密钥
|
||||||
|
5. **Events**: 选择 `Push` 事件
|
||||||
|
|
||||||
|
#### 3. 设置 Git Hook(推荐)
|
||||||
|
|
||||||
|
在服务器上设置 Git post-receive hook:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/cloud-mcp/.git/hooks
|
||||||
|
cat > post-receive << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
cd /path/to/cloud-mcp
|
||||||
|
/path/to/cloud-mcp/deploy-gitea.sh
|
||||||
|
EOF
|
||||||
|
chmod +x post-receive
|
||||||
|
```
|
||||||
|
|
||||||
|
或者使用 Gitea 的 Webhook 触发脚本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装 webhook 服务器(如 webhook)
|
||||||
|
# 然后配置 webhook 调用 deploy-gitea.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. 测试自动部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在本地推送代码
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
# 在服务器上查看日志
|
||||||
|
tail -f /path/to/cloud-mcp/deploy.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Compose 命令
|
||||||
|
|
||||||
|
### 基本操作
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动服务
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# 重启服务
|
||||||
|
docker-compose restart
|
||||||
|
|
||||||
|
# 查看状态
|
||||||
|
docker-compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### 手动更新
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 拉取最新代码
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# 重新构建并启动
|
||||||
|
docker-compose build --no-cache
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 部署脚本命令
|
||||||
|
|
||||||
|
`deploy-gitea.sh` 支持多种操作:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 完整部署(默认)
|
||||||
|
./deploy-gitea.sh
|
||||||
|
|
||||||
|
# 仅拉取代码
|
||||||
|
./deploy-gitea.sh --pull-only
|
||||||
|
|
||||||
|
# 重新构建
|
||||||
|
./deploy-gitea.sh --rebuild
|
||||||
|
|
||||||
|
# 查看状态
|
||||||
|
./deploy-gitea.sh --status
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
./deploy-gitea.sh --logs
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
./deploy-gitea.sh --stop
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
./deploy-gitea.sh --start
|
||||||
|
|
||||||
|
# 重启服务
|
||||||
|
./deploy-gitea.sh --restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据持久化
|
||||||
|
|
||||||
|
数据存储在 `./data` 目录,通过 Docker volume 挂载:
|
||||||
|
|
||||||
|
- 代码片段:`data/codeSnippets.json`
|
||||||
|
- 笔记:`data/notes.json`
|
||||||
|
- 任务:`data/tasks.json`
|
||||||
|
- 其他数据文件...
|
||||||
|
|
||||||
|
**重要**:定期备份 `data` 目录!
|
||||||
|
|
||||||
|
## 监控和维护
|
||||||
|
|
||||||
|
### 查看容器状态
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker ps --filter "name=cloud-mcp"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看日志
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 实时日志
|
||||||
|
docker logs -f cloud-mcp
|
||||||
|
|
||||||
|
# 最近 100 行
|
||||||
|
docker logs --tail 100 cloud-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### 进入容器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it cloud-mcp /bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 清理资源
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 清理未使用的镜像
|
||||||
|
docker image prune -f
|
||||||
|
|
||||||
|
# 清理未使用的容器和网络
|
||||||
|
docker system prune -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
### 容器无法启动
|
||||||
|
|
||||||
|
1. 检查日志:`docker logs cloud-mcp`
|
||||||
|
2. 检查环境变量:确保 `.env` 文件配置正确
|
||||||
|
3. 检查端口冲突:确保没有其他服务占用端口
|
||||||
|
4. 检查磁盘空间:`df -h`
|
||||||
|
|
||||||
|
### 数据丢失
|
||||||
|
|
||||||
|
1. 检查 volume 挂载:`docker inspect cloud-mcp | grep Mounts`
|
||||||
|
2. 检查数据目录权限
|
||||||
|
3. 从备份恢复数据
|
||||||
|
|
||||||
|
### 自动部署不工作
|
||||||
|
|
||||||
|
1. 检查 webhook 配置
|
||||||
|
2. 检查脚本权限:`chmod +x deploy-gitea.sh`
|
||||||
|
3. 检查日志:`tail -f deploy.log`
|
||||||
|
4. 手动测试脚本:`./deploy-gitea.sh --status`
|
||||||
|
|
||||||
|
## 安全建议
|
||||||
|
|
||||||
|
1. **不要将 `.env` 文件提交到 Git**
|
||||||
|
2. 使用强密码和 SSH 密钥
|
||||||
|
3. 定期更新 Docker 镜像
|
||||||
|
4. 限制服务器访问权限
|
||||||
|
5. 使用防火墙限制端口访问
|
||||||
|
6. 定期备份数据
|
||||||
|
|
||||||
|
## 性能优化
|
||||||
|
|
||||||
|
1. **资源限制**:在 `docker-compose.yml` 中添加资源限制:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
cloud-mcp:
|
||||||
|
# ...
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 256M
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **日志轮转**:配置 Docker 日志驱动限制日志大小
|
||||||
|
|
||||||
|
3. **健康检查**:已包含在 `docker-compose.yml` 中
|
||||||
|
|
||||||
|
## 更新流程
|
||||||
|
|
||||||
|
### 开发流程
|
||||||
|
|
||||||
|
1. 在本地开发并测试
|
||||||
|
2. 提交代码到 Git
|
||||||
|
3. 推送到 Gitea 仓库
|
||||||
|
4. Webhook 自动触发部署(如果配置)
|
||||||
|
5. 或手动运行 `./deploy-gitea.sh`
|
||||||
|
|
||||||
|
### 回滚
|
||||||
|
|
||||||
|
如果需要回滚到之前的版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看提交历史
|
||||||
|
git log
|
||||||
|
|
||||||
|
# 回滚到指定提交
|
||||||
|
git checkout <commit-hash>
|
||||||
|
|
||||||
|
# 重新部署
|
||||||
|
./deploy-gitea.sh --rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
## 支持
|
||||||
|
|
||||||
|
如有问题,请查看:
|
||||||
|
- 项目 README.md
|
||||||
|
- 测试文档:tests/README.md
|
||||||
|
- 日志文件:deploy.log
|
||||||
|
|
||||||
42
Dockerfile
Normal file
42
Dockerfile
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Dockerfile for Cloud MCP Server
|
||||||
|
FROM oven/bun:1 AS base
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package.json bun.lockb* ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN bun install --frozen-lockfile
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
RUN bun run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM oven/bun:1-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files and install production dependencies
|
||||||
|
COPY package.json bun.lockb* ./
|
||||||
|
RUN bun install --frozen-lockfile --production
|
||||||
|
|
||||||
|
# Copy built files from base stage
|
||||||
|
COPY --from=base /app/dist ./dist
|
||||||
|
COPY --from=base /app/src ./src
|
||||||
|
|
||||||
|
# Create data directory for persistent storage
|
||||||
|
RUN mkdir -p /app/data
|
||||||
|
|
||||||
|
# Expose port (if needed for health checks)
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
# Run the MCP server
|
||||||
|
CMD ["bun", "run", "src/index.ts"]
|
||||||
|
|
||||||
42
Makefile
Normal file
42
Makefile
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Makefile for Cloud MCP Deployment
|
||||||
|
|
||||||
|
.PHONY: help build up down restart logs status deploy clean
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
help:
|
||||||
|
@echo "Cloud MCP Deployment Commands:"
|
||||||
|
@echo " make build - Build Docker image"
|
||||||
|
@echo " make up - Start container"
|
||||||
|
@echo " make down - Stop container"
|
||||||
|
@echo " make restart - Restart container"
|
||||||
|
@echo " make logs - Show container logs"
|
||||||
|
@echo " make status - Show container status"
|
||||||
|
@echo " make deploy - Full deployment (pull, build, restart)"
|
||||||
|
@echo " make clean - Clean up unused Docker resources"
|
||||||
|
|
||||||
|
build:
|
||||||
|
docker-compose build
|
||||||
|
|
||||||
|
up:
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
down:
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
restart:
|
||||||
|
docker-compose restart
|
||||||
|
|
||||||
|
logs:
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
status:
|
||||||
|
docker-compose ps
|
||||||
|
@echo ""
|
||||||
|
@docker logs --tail 20 cloud-mcp 2>/dev/null || echo "Container not running"
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
@./deploy.sh --pull --rebuild
|
||||||
|
|
||||||
|
clean:
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
113
QUICK_START.md
Normal file
113
QUICK_START.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# 快速部署指南
|
||||||
|
|
||||||
|
## 服务器端设置(一次性)
|
||||||
|
|
||||||
|
### 1. 克隆项目
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <your-gitea-repo-url> /opt/cloud-mcp
|
||||||
|
cd /opt/cloud-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 配置环境变量
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp env.template .env
|
||||||
|
nano .env # 编辑配置
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 设置脚本权限
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x deploy.sh deploy-gitea.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 首次部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy.sh --rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
## Gitea Webhook 自动部署设置
|
||||||
|
|
||||||
|
### 方法一:使用 Git Hook(推荐)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在服务器上设置 post-receive hook
|
||||||
|
cd /opt/cloud-mcp
|
||||||
|
git config receive.denyCurrentBranch ignore
|
||||||
|
|
||||||
|
# 创建 hook 脚本
|
||||||
|
cat > .git/hooks/post-receive << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
cd /opt/cloud-mcp
|
||||||
|
git checkout -f
|
||||||
|
./deploy-gitea.sh
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x .git/hooks/post-receive
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方法二:使用 Gitea Webhook
|
||||||
|
|
||||||
|
1. 在 Gitea 仓库设置中添加 Webhook
|
||||||
|
2. URL: `http://your-server:port/hooks/deploy` (需要 webhook 服务器)
|
||||||
|
3. 或使用 SSH 方式触发部署脚本
|
||||||
|
|
||||||
|
## 日常使用
|
||||||
|
|
||||||
|
### 手动部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在服务器上
|
||||||
|
cd /opt/cloud-mcp
|
||||||
|
./deploy-gitea.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看状态
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy-gitea.sh --status
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看日志
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy-gitea.sh --logs
|
||||||
|
# 或
|
||||||
|
docker logs -f cloud-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用 Makefile(可选)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make deploy # 完整部署
|
||||||
|
make status # 查看状态
|
||||||
|
make logs # 查看日志
|
||||||
|
make restart # 重启
|
||||||
|
make down # 停止
|
||||||
|
make up # 启动
|
||||||
|
```
|
||||||
|
|
||||||
|
## 更新流程
|
||||||
|
|
||||||
|
1. **本地开发** → 提交代码 → 推送到 Gitea
|
||||||
|
2. **自动触发** → Webhook/Hook 自动运行 `deploy-gitea.sh`
|
||||||
|
3. **完成** → 容器自动更新并重启
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查容器状态
|
||||||
|
docker ps -a | grep cloud-mcp
|
||||||
|
|
||||||
|
# 查看详细日志
|
||||||
|
docker logs cloud-mcp
|
||||||
|
|
||||||
|
# 检查部署日志
|
||||||
|
tail -f deploy.log
|
||||||
|
|
||||||
|
# 手动重启
|
||||||
|
./deploy-gitea.sh --restart
|
||||||
|
```
|
||||||
|
|
||||||
238
deploy-gitea.sh
Executable file
238
deploy-gitea.sh
Executable file
@@ -0,0 +1,238 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Gitea Webhook Deployment Script
|
||||||
|
# This script is triggered by Gitea webhook on push events
|
||||||
|
# Configure in Gitea: Repository -> Settings -> Webhooks -> Add Webhook
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
PROJECT_DIR="/path/to/cloud-mcp" # Update this to your project path
|
||||||
|
CONTAINER_NAME="cloud-mcp"
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
BRANCH="main" # or "master"
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
LOG_FILE="${PROJECT_DIR}/deploy.log"
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
log() {
|
||||||
|
local level=$1
|
||||||
|
shift
|
||||||
|
local message="$@"
|
||||||
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
echo -e "${timestamp} [${level}] ${message}" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
log "INFO" "${GREEN}$@${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn() {
|
||||||
|
log "WARN" "${YELLOW}$@${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
log "ERROR" "${RED}$@${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running in correct directory
|
||||||
|
check_directory() {
|
||||||
|
if [ ! -f "$PROJECT_DIR/docker-compose.yml" ]; then
|
||||||
|
log_error "Project directory not found: $PROJECT_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
log_info "Working directory: $(pwd)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if Docker is running
|
||||||
|
check_docker() {
|
||||||
|
if ! docker info > /dev/null 2>&1; then
|
||||||
|
log_error "Docker is not running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log_info "Docker is running"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pull latest code
|
||||||
|
pull_latest() {
|
||||||
|
log_info "Pulling latest code from repository..."
|
||||||
|
|
||||||
|
# Fetch latest changes
|
||||||
|
git fetch origin "$BRANCH" || {
|
||||||
|
log_error "Failed to fetch from repository"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if there are updates
|
||||||
|
LOCAL=$(git rev-parse @)
|
||||||
|
REMOTE=$(git rev-parse "origin/${BRANCH}")
|
||||||
|
BASE=$(git merge-base @ "origin/${BRANCH}")
|
||||||
|
|
||||||
|
if [ "$LOCAL" = "$REMOTE" ]; then
|
||||||
|
log_info "Already up to date"
|
||||||
|
return 1
|
||||||
|
elif [ "$LOCAL" = "$BASE" ]; then
|
||||||
|
log_info "New commits found, pulling..."
|
||||||
|
git pull origin "$BRANCH" || {
|
||||||
|
log_error "Failed to pull from repository"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_warn "Local branch is ahead or diverged. Resetting to remote..."
|
||||||
|
git reset --hard "origin/${BRANCH}" || {
|
||||||
|
log_error "Failed to reset branch"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build Docker image
|
||||||
|
build_image() {
|
||||||
|
log_info "Building Docker image..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" build --no-cache || {
|
||||||
|
log_error "Failed to build Docker image"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
log_info "Docker image built successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stop existing container
|
||||||
|
stop_container() {
|
||||||
|
log_info "Stopping existing container..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" down || {
|
||||||
|
log_warn "Failed to stop container (might not exist)"
|
||||||
|
}
|
||||||
|
log_info "Container stopped"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start container
|
||||||
|
start_container() {
|
||||||
|
log_info "Starting container..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" up -d || {
|
||||||
|
log_error "Failed to start container"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
log_info "Container started"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify deployment
|
||||||
|
verify_deployment() {
|
||||||
|
log_info "Verifying deployment..."
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||||
|
log_info "Container is running"
|
||||||
|
|
||||||
|
# Check container health
|
||||||
|
local status=$(docker inspect --format='{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null)
|
||||||
|
if [ "$status" = "running" ]; then
|
||||||
|
log_info "Deployment successful!"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_error "Container is not running (status: $status)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_error "Container not found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show container logs
|
||||||
|
show_logs() {
|
||||||
|
log_info "Recent container logs:"
|
||||||
|
docker logs --tail 30 "$CONTAINER_NAME" 2>&1 || log_warn "Could not fetch logs"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cleanup old images (optional)
|
||||||
|
cleanup_images() {
|
||||||
|
log_info "Cleaning up unused Docker images..."
|
||||||
|
docker image prune -f || log_warn "Failed to cleanup images"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main deployment flow
|
||||||
|
main() {
|
||||||
|
log_info "========================================="
|
||||||
|
log_info "Starting deployment process"
|
||||||
|
log_info "========================================="
|
||||||
|
|
||||||
|
check_directory
|
||||||
|
check_docker
|
||||||
|
|
||||||
|
# Pull latest code
|
||||||
|
if ! pull_latest; then
|
||||||
|
log_info "No updates to deploy"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build and deploy
|
||||||
|
build_image
|
||||||
|
stop_container
|
||||||
|
start_container
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
if verify_deployment; then
|
||||||
|
show_logs
|
||||||
|
cleanup_images
|
||||||
|
log_info "========================================="
|
||||||
|
log_info "Deployment completed successfully!"
|
||||||
|
log_info "========================================="
|
||||||
|
else
|
||||||
|
log_error "Deployment verification failed"
|
||||||
|
show_logs
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle script arguments
|
||||||
|
case "${1:-}" in
|
||||||
|
--pull-only)
|
||||||
|
check_directory
|
||||||
|
pull_latest
|
||||||
|
;;
|
||||||
|
--rebuild)
|
||||||
|
check_directory
|
||||||
|
check_docker
|
||||||
|
build_image
|
||||||
|
stop_container
|
||||||
|
start_container
|
||||||
|
verify_deployment
|
||||||
|
;;
|
||||||
|
--status)
|
||||||
|
check_directory
|
||||||
|
docker ps --filter "name=${CONTAINER_NAME}" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||||
|
show_logs
|
||||||
|
;;
|
||||||
|
--logs)
|
||||||
|
check_directory
|
||||||
|
docker logs -f "$CONTAINER_NAME"
|
||||||
|
;;
|
||||||
|
--stop)
|
||||||
|
check_directory
|
||||||
|
stop_container
|
||||||
|
;;
|
||||||
|
--start)
|
||||||
|
check_directory
|
||||||
|
start_container
|
||||||
|
;;
|
||||||
|
--restart)
|
||||||
|
check_directory
|
||||||
|
stop_container
|
||||||
|
start_container
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
main
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
118
deploy.sh
Executable file
118
deploy.sh
Executable file
@@ -0,0 +1,118 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Cloud MCP Deployment Script
|
||||||
|
# This script builds and deploys the MCP server using Docker
|
||||||
|
# Usage: ./deploy.sh [--pull] [--rebuild]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CONTAINER_NAME="cloud-mcp"
|
||||||
|
IMAGE_NAME="cloud-mcp"
|
||||||
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
log_info() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if Docker is running
|
||||||
|
check_docker() {
|
||||||
|
if ! docker info > /dev/null 2>&1; then
|
||||||
|
log_error "Docker is not running. Please start Docker and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log_info "Docker is running"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pull latest code from git (if --pull flag is set)
|
||||||
|
pull_latest() {
|
||||||
|
if [[ "$1" == "--pull" ]] || [[ "$*" == *"--pull"* ]]; then
|
||||||
|
log_info "Pulling latest code from git..."
|
||||||
|
git pull origin main || git pull origin master || log_warn "Failed to pull from git, continuing with local code"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build Docker image
|
||||||
|
build_image() {
|
||||||
|
local rebuild=false
|
||||||
|
if [[ "$*" == *"--rebuild"* ]]; then
|
||||||
|
rebuild=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Building Docker image..."
|
||||||
|
|
||||||
|
if [ "$rebuild" = true ]; then
|
||||||
|
log_info "Force rebuilding image (no cache)..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" build --no-cache
|
||||||
|
else
|
||||||
|
docker-compose -f "$COMPOSE_FILE" build
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Docker image built successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stop existing container
|
||||||
|
stop_container() {
|
||||||
|
if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||||
|
log_info "Stopping existing container..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" down
|
||||||
|
log_info "Container stopped"
|
||||||
|
else
|
||||||
|
log_info "No existing container found"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start container
|
||||||
|
start_container() {
|
||||||
|
log_info "Starting container..."
|
||||||
|
docker-compose -f "$COMPOSE_FILE" up -d
|
||||||
|
log_info "Container started"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show container status
|
||||||
|
show_status() {
|
||||||
|
log_info "Container status:"
|
||||||
|
docker ps --filter "name=${CONTAINER_NAME}" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||||
|
|
||||||
|
log_info "Container logs (last 20 lines):"
|
||||||
|
docker logs --tail 20 "${CONTAINER_NAME}" 2>&1 || log_warn "Could not fetch logs"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main deployment flow
|
||||||
|
main() {
|
||||||
|
log_info "Starting deployment..."
|
||||||
|
|
||||||
|
check_docker
|
||||||
|
pull_latest "$@"
|
||||||
|
build_image "$@"
|
||||||
|
stop_container
|
||||||
|
start_container
|
||||||
|
|
||||||
|
# Wait a moment for container to start
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
show_status
|
||||||
|
|
||||||
|
log_info "Deployment completed!"
|
||||||
|
log_info "To view logs: docker logs -f ${CONTAINER_NAME}"
|
||||||
|
log_info "To stop: docker-compose -f ${COMPOSE_FILE} down"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run main function
|
||||||
|
main "$@"
|
||||||
|
|
||||||
29
docker-compose.yml
Normal file
29
docker-compose.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
cloud-mcp:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: cloud-mcp
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
# Mount data directory for persistent storage
|
||||||
|
- ./data:/app/data
|
||||||
|
# Mount .env file if exists (optional, can use environment variables instead)
|
||||||
|
- ./.env:/app/.env:ro
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
# Add your environment variables here or use .env file
|
||||||
|
# - NAS_HOST=${NAS_HOST}
|
||||||
|
# - SERVER_HOST=${SERVER_HOST}
|
||||||
|
# etc.
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
# Health check (optional)
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "bun", "--version"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
Reference in New Issue
Block a user