From 9ea9eb4b61971eb2ee825deca10142347803ea0e Mon Sep 17 00:00:00 2001 From: Timmy Date: Tue, 17 Mar 2026 17:41:10 +0800 Subject: [PATCH] feat: add comprehensive management scripts for CodiMD Add 9 management scripts to simplify CodiMD operations: - start.sh: Start services with automatic .env setup - stop.sh: Stop all services gracefully - restart.sh: Restart all services - logs.sh: View real-time logs for any service - status.sh: Check service status and resource usage - backup.sh: Backup database, uploads, and environment - restore.sh: Restore from backups with interactive selection - update.sh: Update Docker images with automatic backup - cleanup.sh: Clean unused Docker resources Add SCRIPTS.md with comprehensive usage documentation and examples. Co-Authored-By: Claude Sonnet 4 --- SCRIPTS.md | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++ backup.sh | 78 ++++++++++++++++++++++ cleanup.sh | 31 +++++++++ logs.sh | 9 +++ restart.sh | 21 ++++++ restore.sh | 80 ++++++++++++++++++++++ start.sh | 46 +++++++++++++ status.sh | 33 +++++++++ stop.sh | 14 ++++ update.sh | 43 ++++++++++++ 10 files changed, 548 insertions(+) create mode 100644 SCRIPTS.md create mode 100755 backup.sh create mode 100755 cleanup.sh create mode 100755 logs.sh create mode 100755 restart.sh create mode 100755 restore.sh create mode 100755 start.sh create mode 100755 status.sh create mode 100755 stop.sh create mode 100755 update.sh diff --git a/SCRIPTS.md b/SCRIPTS.md new file mode 100644 index 0000000..80805ed --- /dev/null +++ b/SCRIPTS.md @@ -0,0 +1,193 @@ +# CodiMD 管理腳本使用說明 + +這個目錄包含一系列腳本來簡化 CodiMD 的管理。 + +## 🚀 快速開始 + +給所有腳本執行權限: + +```bash +chmod +x *.sh +``` + +## 📜 可用腳本 + +| 腳本 | 功能 | 說明 | +|------|------|------| +| `start.sh` | 啟動服務 | 啟動 CodiMD 和資料庫 | +| `stop.sh` | 停止服務 | 停止所有服務 | +| `restart.sh` | 重啟服務 | 重啟所有服務 | +| `logs.sh` | 查看日誌 | 顯示即時日誌 | +| `status.sh` | 檢查狀態 | 顯示服務狀態和資源使用 | +| `backup.sh` | 備份資料 | 備份資料庫和上傳檔案 | +| `restore.sh` | 還原備份 | 從備份還原資料 | +| `update.sh` | 更新服務 | 更新 Docker 映像 | +| `cleanup.sh` | 清理資源 | 清理未使用的 Docker 資源 | + +## 📖 詳細說明 + +### start.sh - 啟動服務 + +```bash +./start.sh +``` + +功能: +- 檢查 `.env` 是否存在(不存在則複製 `.env.example`) +- 啟動所有 Docker 服務 +- 顯示服務狀態和訪問地址 + +### stop.sh - 停止服務 + +```bash +./stop.sh +``` + +功能: +- 優雅地停止所有服務 +- 保留資料和容器 + +### restart.sh - 重啟服務 + +```bash +./restart.sh +``` + +功能: +- 重啟所有服務 +- 等待服務完全啟動 +- 顯示服務狀態 + +### logs.sh - 查看日誌 + +```bash +# 查看 CodiMD 日誌(預設) +./logs.sh + +# 查看資料庫日誌 +./logs.sh database +``` + +功能: +- 即時顯示服務日誌 +- 按 `Ctrl+C` 離開 + +### status.sh - 檢查狀態 + +```bash +./status.sh +``` + +功能: +- 顯示容器運行狀態 +- 顯示最近 20 行日誌 +- 顯示磁碟空間 +- 顯示 Docker 資源使用 + +### backup.sh - 備份資料 + +```bash +./backup.sh +``` + +功能: +- 備份 PostgreSQL 資料庫 +- 備份上傳檔案 +- 備份環境設定(`.env`) +- 自動清理超過 30 天的舊備份 + +備份位置:`./backups/` + +### restore.sh - 還原備份 + +```bash +./restore.sh +``` + +功能: +- 列出可用的備份 +- 選擇要還原的備份 +- 可選擇還原資料庫、上傳檔案、環境設定 + +### update.sh - 更新服務 + +```bash +./update.sh +``` + +功能: +- 執行備份 +- 拉取最新的 Docker 映像 +- 可選擇立即重啟服務 + +### cleanup.sh - 清理資源 + +```bash +./cleanup.sh +``` + +功能: +- 清理未使用的 Docker 映像 +- 清理停止的容器 +- 清理未使用的網路 +- 清理建置快取 + +## 🔧 設置 Crontab 自動備份 + +編輯 crontab: + +```bash +crontab -e +``` + +添加以下內容(每天凌晨 2 點備份): + +```cron +0 2 * * * cd /path/to/codimd && ./backup.sh >> backups/cron.log 2>&1 +``` + +## 📊 備份範例 + +備份檔案命名格式: + +``` +backups/ +├── database_20260317_020000.sql # 資料庫備份 +├── uploads_20260317_020000.tar.gz # 上傳檔案備份 +├── env_20260317_020000.env # 環境設定備份 +└── backup_20260317_020000.txt # 備份資訊 +``` + +## 🛠️ 故障排除 + +### 腳本無法執行 + +```bash +chmod +x *.sh +``` + +### Docker 未運行 + +```bash +sudo systemctl start docker +``` + +### 權限問題 + +```bash +sudo usermod -aG docker $USER +# 然後重新登入 +``` + +## 📝 注意事事項 + +1. **備份前先測試**:第一次使用建議先手動測試備份和還原 +2. **定期檢查備份**:確認備份檔案完整且可還原 +3. **監控磁碟空間**:定期清理舊備份以節省空間 +4. **保持腳本更新**:更新 CodiMD 時也要檢查腳本是否需要更新 + +## 🔗 相關文件 + +- [README.md](README.md) - 完整部署指南 +- [SSL-SETUP.md](SSL-SETUP.md) - SSL 設置指南 +- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - 故障排除指南 diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..2f54740 --- /dev/null +++ b/backup.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# CodiMD 備份腳本 + +set -e + +# 備份目錄 +BACKUP_DIR="./backups" +TIMESTAMP=$(date +"%Y%m%d_%H%M%S") + +# 建立備份目錄 +mkdir -p "$BACKUP_DIR" + +echo "💾 開始備份 CodiMD..." +echo "📅 備份時間: $(date)" +echo "" + +# 1. 備份資料庫 +echo "📦 備份 PostgreSQL 資料庫..." +docker-compose exec -T database pg_dump -U codimd codimd > "$BACKUP_DIR/database_$TIMESTAMP.sql" + +if [ $? -eq 0 ]; then + DB_SIZE=$(du -h "$BACKUP_DIR/database_$TIMESTAMP.sql" | cut -f1) + echo "✅ 資料庫備份完成 ($DB_SIZE)" +else + echo "❌ 資料庫備份失敗" + exit 1 +fi + +# 2. 備份上傳檔案 +echo "📁 備份上傳檔案..." +UPLOAD_BACKUP="$BACKUP_DIR/uploads_$TIMESTAMP.tar.gz" + +if [ -d "upload-data" ] && [ "$(ls -A upload-data)" ]; then + tar -czf "$UPLOAD_BACKUP" upload-data/ + UPLOAD_SIZE=$(du -h "$UPLOAD_BACKUP" | cut -f1) + echo "✅ 上傳檔案備份完成 ($UPLOAD_SIZE)" +else + echo "⚠️ 沒有上傳檔案需要備份" +fi + +# 3. 備份環境設定 +echo "📝 備份環境設定..." +cp .env "$BACKUP_DIR/env_$TIMESTAMP.env" +echo "✅ 環境設定備份完成" + +# 4. 建立備份資訊文件 +cat > "$BACKUP_DIR/backup_$TIMESTAMP.txt" << EOF +CodiMD 備份資訊 +================ +備份時間: $(date) +備份類型: 完整備份 + +檔案清單: +- 資料庫: database_$TIMESTAMP.sql +- 上傳檔案: uploads_$TIMESTAMP.tar.gz +- 環境設定: env_$TIMESTAMP.env + +還原方式: +1. 資料庫: cat database_$TIMESTAMP.sql | docker-compose exec -T database psql -U codimd codimd +2. 上傳檔案: tar -xzf uploads_$TIMESTAMP.tar.gz +3. 環境設定: cp env_$TIMESTAMP.env .env +EOF + +echo "" +echo "✅ 備份完成!" +echo "" +echo "📂 備份位置: $BACKUP_DIR/" +ls -lh "$BACKUP_DIR" | grep "$TIMESTAMP" +echo "" +echo "💡 還原備份請查看: $BACKUP_DIR/backup_$TIMESTAMP.txt" + +# 清理超過 30 天的舊備份 +echo "" +echo "🧹 清理舊備份(超過 30 天)..." +find "$BACKUP_DIR" -name "database_*.sql" -mtime +30 -delete 2>/dev/null || true +find "$BACKUP_DIR" -name "uploads_*.tar.gz" -mtime +30 -delete 2>/dev/null || true +find "$BACKUP_DIR" -name "env_*.env" -mtime +30 -delete 2>/dev/null || true +echo "✅ 清理完成" diff --git a/cleanup.sh b/cleanup.sh new file mode 100755 index 0000000..8733cfc --- /dev/null +++ b/cleanup.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# CodiMD 清理腳本 + +set -e + +echo "🧹 清理 Docker 資源..." +echo "" + +# 1. 清理未使用的映像 +echo "🗑️ 清理未使用的 Docker 映像..." +docker image prune -f + +# 2. 清理未使用的容器 +echo "🗑️ 清理停止的容器..." +docker container prune -f + +# 3. 清理未使用的網路 +echo "🗑️ 清理未使用的網路..." +docker network prune -f + +# 4. 清理建置快取 +echo "🗑️ 清理建置快取..." +docker builder prune -f + +echo "" +echo "✅ 清理完成!" +echo "" + +# 顯示釋放的空間 +echo "💾 目前 Docker 磁碟使用:" +docker system df diff --git a/logs.sh b/logs.sh new file mode 100755 index 0000000..942be9f --- /dev/null +++ b/logs.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# CodiMD 日誌查看腳本 + +SERVICE=${1:-codimd} + +echo "📋 顯示 $SERVICE 服務日誌(按 Ctrl+C 離開)..." +echo "" + +docker-compose logs -f "$SERVICE" diff --git a/restart.sh b/restart.sh new file mode 100755 index 0000000..1c24e94 --- /dev/null +++ b/restart.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# CodiMD 重啟腳本 + +set -e + +echo "🔄 重啟 CodiMD 服務..." + +# 重啟服務 +docker-compose restart + +echo "" +echo "⏳ 等待服務完全啟動..." +sleep 5 + +# 顯示服務狀態 +echo "" +echo "📊 服務狀態:" +docker-compose ps + +echo "" +echo "✅ CodiMD 已重啟" diff --git a/restore.sh b/restore.sh new file mode 100755 index 0000000..faefca7 --- /dev/null +++ b/restore.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# CodiMD 還原腳本 + +set -e + +BACKUP_DIR="./backups" + +echo "🔄 CodiMD 還原腳本" +echo "" + +# 列出可用的備份 +if [ ! -d "$BACKUP_DIR" ] || [ -z "$(ls -A $BACKUP_DIR/*.sql 2>/dev/null)" ]; then + echo "❌ 找不到備份檔案" + exit 1 +fi + +echo "📂 可用的備份:" +ls -lht "$BACKUP_DIR"/*.sql 2>/dev/null | head -10 +echo "" + +# 詢問要還原的備份 +read -p "請輸入要還原的備份檔案名稱 (例如: database_20260317_120000.sql): " BACKUP_FILE + +if [ ! -f "$BACKUP_DIR/$BACKUP_FILE" ]; then + echo "❌ 找不到檔案: $BACKUP_DIR/$BACKUP_FILE" + exit 1 +fi + +# 提取時間戳記 +TIMESTAMP=$(echo "$BACKUP_FILE" | sed 's/database_\(.*\).sql/\1/') + +echo "" +echo "⚠️ 警告:還原資料庫會覆蓋現有資料!" +read -p "確定要還原嗎?(yes/no): " CONFIRM + +if [ "$CONFIRM" != "yes" ]; then + echo "❌ 取消還原" + exit 0 +fi + +echo "" +echo "🔄 開始還原..." + +# 1. 還原資料庫 +echo "📦 還原資料庫..." +docker-compose exec -T database psql -U codimd codimd < "$BACKUP_DIR/$BACKUP_FILE" + +if [ $? -eq 0 ]; then + echo "✅ 資料庫還原完成" +else + echo "❌ 資料庫還原失敗" + exit 1 +fi + +# 2. 詢問是否還原上傳檔案 +UPLOAD_FILE="$BACKUP_DIR/uploads_$TIMESTAMP.tar.gz" +if [ -f "$UPLOAD_FILE" ]; then + read -p "是否還原上傳檔案?(yes/no): " RESTORE_UPLOAD + if [ "$RESTORE_UPLOAD" = "yes" ]; then + echo "📁 還原上傳檔案..." + rm -rf upload-data/* + tar -xzf "$UPLOAD_FILE" + echo "✅ 上傳檔案還原完成" + fi +fi + +# 3. 詢問是否還原環境設定 +ENV_FILE="$BACKUP_DIR/env_$TIMESTAMP.env" +if [ -f "$ENV_FILE" ]; then + read -p "是否還原環境設定?(yes/no): " RESTORE_ENV + if [ "$RESTORE_ENV" = "yes" ]; then + echo "📝 還原環境設定..." + cp "$ENV_FILE" .env + echo "✅ 環境設定還原完成" + echo "⚠️ 請執行 ./restart.sh 以套用新設定" + fi +fi + +echo "" +echo "✅ 還原完成!" diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..5848581 --- /dev/null +++ b/start.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# CodiMD 啟動腳本 + +set -e + +echo "🚀 啟動 CodiMD 服務..." + +# 檢查 .env 是否存在 +if [ ! -f .env ]; then + echo "⚠️ .env 檔案不存在,從 .env.example 複製..." + cp .env.example .env + echo "✅ 已建立 .env 檔案" + echo "⚠️ 請編輯 .env 檔案,設定強密碼和域名" + echo " nano .env" + echo "" + read -p "按 Enter 繼續或 Ctrl+C 取消..." +fi + +# 檢查 Docker 是否運行 +if ! docker info > /dev/null 2>&1; then + echo "❌ Docker 未運行,請先啟動 Docker" + exit 1 +fi + +# 啟動服務 +docker-compose up -d + +echo "" +echo "⏳ 等待服務啟動..." +sleep 5 + +# 顯示服務狀態 +echo "" +echo "📊 服務狀態:" +docker-compose ps + +echo "" +echo "✅ CodiMD 已啟動!" +echo "" +echo "🌐 訪問地址:" +echo " 本地: http://localhost:3000" +echo " 外部: http://$(hostname -I | awk '{print $1}'):3000" +echo "" +echo "📝 查看日誌: ./logs.sh" +echo "🛑 停止服務: ./stop.sh" +echo "🔄 重啟服務: ./restart.sh" diff --git a/status.sh b/status.sh new file mode 100755 index 0000000..c86e818 --- /dev/null +++ b/status.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# CodiMD 狀態檢查腳本 + +echo "🔍 檢查 CodiMD 服務狀態..." +echo "" + +# 顯示容器狀態 +echo "📊 Docker 容器狀態:" +docker-compose ps +echo "" + +# 檢查服務是否正常 +if docker-compose ps | grep -q "Up (healthy)"; then + echo "✅ 所有服務運行正常" +else + echo "⚠️ 部分服務可能未正常運行" +fi + +echo "" + +# 顯示最近日誌 +echo "📋 最近日誌(最後 20 行):" +docker-compose logs --tail=20 +echo "" + +# 檢查磁碟空間 +echo "💾 磁碟空間:" +df -h | grep -E "Filesystem|/$" +echo "" + +# 檢查 Docker 資源使用 +echo "📊 Docker 資源使用:" +docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" 2>/dev/null || echo "無法取得資源使用資訊" diff --git a/stop.sh b/stop.sh new file mode 100755 index 0000000..7e193d3 --- /dev/null +++ b/stop.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# CodiMD 停止腳本 + +set -e + +echo "🛑 停止 CodiMD 服務..." + +# 停止服務 +docker-compose down + +echo "" +echo "✅ CodiMD 已停止" +echo "" +echo "💡 重新啟動: ./start.sh" diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..d955100 --- /dev/null +++ b/update.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# CodiMD 更新腳本 + +set -e + +echo "🔄 更新 CodiMD..." +echo "" + +# 1. 備份現有資料 +echo "💾 更新前備份..." +./backup.sh +echo "" + +# 2. 拉取最新映像 +echo "📥 拉取最新 Docker 映像..." +docker-compose pull +echo "" + +# 3. 詢問是否重啟 +read -p "是否現在重啟服務以套用更新?(yes/no): " RESTART + +if [ "$RESTART" = "yes" ]; then + echo "🔄 重啟服務..." + docker-compose down + docker-compose up -d + + echo "" + echo "⏳ 等待服務啟動..." + sleep 10 + + echo "" + echo "📊 服務狀態:" + docker-compose ps + + echo "" + echo "✅ 更新完成!" + echo "" + echo "📝 查看日誌: ./logs.sh" +else + echo "" + echo "⚠️ 映像已下載,但服務尚未重啟" + echo "💡 稍後可執行 ./restart.sh 來套用更新" +fi