8th_fix docker
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(dir)"
|
||||
"Bash(dir)",
|
||||
"Bash(docker:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
113
.env.production
Normal file
113
.env.production
Normal file
@@ -0,0 +1,113 @@
|
||||
# ===========================================
|
||||
# 生產環境配置文件
|
||||
# ===========================================
|
||||
|
||||
# ===========================================
|
||||
# MySQL 資料庫連線
|
||||
# ===========================================
|
||||
DATABASE_URL=mysql+pymysql://A060:WLeSCi0yhtc7@mysql.theaken.com:33306/db_A060
|
||||
MYSQL_HOST=mysql.theaken.com
|
||||
MYSQL_PORT=33306
|
||||
MYSQL_USER=A060
|
||||
MYSQL_PASSWORD=WLeSCi0yhtc7
|
||||
MYSQL_DATABASE=db_A060
|
||||
MYSQL_CHARSET=utf8mb4
|
||||
|
||||
# ===========================================
|
||||
# Flask 應用配置
|
||||
# ===========================================
|
||||
FLASK_ENV=production
|
||||
SECRET_KEY=prod-todo-secret-key-2024-change-me
|
||||
JWT_SECRET_KEY=prod-jwt-secret-key-2024-change-me
|
||||
JWT_ACCESS_TOKEN_EXPIRES=3600
|
||||
|
||||
# ===========================================
|
||||
# AD/LDAP 設定 (生產環境)
|
||||
# ===========================================
|
||||
USE_MOCK_LDAP=false
|
||||
LDAP_SERVER=panjit.com.tw
|
||||
LDAP_PORT=389
|
||||
LDAP_USE_SSL=false
|
||||
LDAP_BIND_USER_DN=CN=LdapBind,CN=Users,DC=PANJIT,DC=COM,DC=TW
|
||||
LDAP_BIND_USER_PASSWORD=panjit2481
|
||||
LDAP_SEARCH_BASE=OU=PANJIT,DC=panjit,DC=com,DC=tw
|
||||
LDAP_USER_LOGIN_ATTR=userPrincipalName
|
||||
|
||||
# ===========================================
|
||||
# SMTP 設定
|
||||
# ===========================================
|
||||
SMTP_SERVER=mail.panjit.com.tw
|
||||
SMTP_PORT=25
|
||||
SMTP_USE_TLS=false
|
||||
SMTP_USE_SSL=false
|
||||
SMTP_AUTH_REQUIRED=false
|
||||
SMTP_SENDER_EMAIL=todo-system@panjit.com.tw
|
||||
SMTP_SENDER_PASSWORD=
|
||||
|
||||
# ===========================================
|
||||
# CORS 設定
|
||||
# ===========================================
|
||||
CORS_ORIGINS=http://localhost:12012
|
||||
|
||||
# ===========================================
|
||||
# 日誌設定
|
||||
# ===========================================
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE_PATH=logs/app.log
|
||||
LOG_MAX_BYTES=10485760
|
||||
LOG_BACKUP_COUNT=5
|
||||
|
||||
# ===========================================
|
||||
# Redis 設定 (如果使用)
|
||||
# ===========================================
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# ===========================================
|
||||
# Celery 設定 (如果使用)
|
||||
# ===========================================
|
||||
CELERY_BROKER_URL=redis://localhost:6379/0
|
||||
CELERY_RESULT_BACKEND=redis://localhost:6379/0
|
||||
|
||||
# ===========================================
|
||||
# 前端配置
|
||||
# ===========================================
|
||||
NEXT_PUBLIC_API_URL=http://localhost:12011
|
||||
|
||||
# ===========================================
|
||||
# 服務端口配置
|
||||
# ===========================================
|
||||
BACKEND_PORT=12011
|
||||
FRONTEND_PORT=12012
|
||||
|
||||
# ===========================================
|
||||
# 安全設定
|
||||
# ===========================================
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
SECURE_SSL_REDIRECT=false
|
||||
SESSION_COOKIE_SECURE=false
|
||||
CSRF_COOKIE_SECURE=false
|
||||
|
||||
# ===========================================
|
||||
# 檔案上傳設定
|
||||
# ===========================================
|
||||
MAX_CONTENT_LENGTH=16777216
|
||||
UPLOAD_FOLDER=uploads
|
||||
ALLOWED_EXTENSIONS=xlsx,xls,csv
|
||||
|
||||
# ===========================================
|
||||
# 郵件配額設定
|
||||
# ===========================================
|
||||
DAILY_EMAIL_LIMIT=100
|
||||
MONTHLY_EMAIL_LIMIT=1000
|
||||
|
||||
# ===========================================
|
||||
# 系統設定
|
||||
# ===========================================
|
||||
SYSTEM_NAME=TODO管理系統
|
||||
SYSTEM_VERSION=1.0.0
|
||||
ADMIN_EMAIL=ymirliu@panjit.com.tw
|
||||
DEFAULT_ADMIN_USER=ymirliu@panjit.com.tw
|
||||
|
279
DEPLOYMENT.md
Normal file
279
DEPLOYMENT.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# TODO管理系統 - 生產環境部署指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本文件提供TODO管理系統的完整生產環境部署指南,包含所有必要的配置和步驟。
|
||||
|
||||
## 🏗️ 系統架構
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ 前端 (Next.js) │ │ 後端 (Flask) │ │ MySQL DB │
|
||||
│ Port: 12012 │◄───┤ Port: 12011 │◄───┤ theaken.com │
|
||||
│ Docker容器 │ │ Docker容器 │ │ Port: 33306 │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ LDAP/AD │
|
||||
│ panjit.com.tw │
|
||||
│ Port: 389 │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## 🚀 快速部署
|
||||
|
||||
### Windows 環境
|
||||
|
||||
```batch
|
||||
# 1. 克隆專案(如果尚未克隆)
|
||||
git clone <repository-url>
|
||||
cd TODOLIST
|
||||
|
||||
# 2. 執行部署腳本
|
||||
deploy.bat
|
||||
```
|
||||
|
||||
### Linux/Mac 環境
|
||||
|
||||
```bash
|
||||
# 1. 克隆專案(如果尚未克隆)
|
||||
git clone <repository-url>
|
||||
cd TODOLIST
|
||||
|
||||
# 2. 設置執行權限並執行部署腳本
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
## 📁 部署文件結構
|
||||
|
||||
```
|
||||
TODOLIST/
|
||||
├── backend/ # 後端代碼
|
||||
│ ├── Dockerfile # 後端Docker構建文件
|
||||
│ ├── requirements.txt # Python依賴
|
||||
│ └── ...
|
||||
├── frontend/ # 前端代碼
|
||||
│ ├── Dockerfile # 前端Docker構建文件
|
||||
│ ├── package.json # Node.js依賴
|
||||
│ └── ...
|
||||
├── docker-compose.prod.yml # 生產環境Docker Compose配置
|
||||
├── .env.production # 生產環境變量配置
|
||||
├── deploy.bat # Windows部署腳本
|
||||
├── deploy.sh # Linux/Mac部署腳本
|
||||
└── DEPLOYMENT.md # 部署說明文件
|
||||
```
|
||||
|
||||
## 🔧 環境配置
|
||||
|
||||
### 生產環境變量 (`.env.production`)
|
||||
|
||||
本系統使用以下生產環境配置:
|
||||
|
||||
#### 🗄️ 資料庫配置
|
||||
- **MySQL主機**: `mysql.theaken.com:33306`
|
||||
- **資料庫**: `db_A060`
|
||||
- **用戶**: `A060`
|
||||
|
||||
#### 🔐 LDAP認證配置
|
||||
- **LDAP服務器**: `panjit.com.tw:389`
|
||||
- **搜索基礎**: `OU=PANJIT,DC=panjit,DC=com,DC=tw`
|
||||
- **認證方式**: Active Directory集成
|
||||
|
||||
#### 📧 郵件服務配置
|
||||
- **SMTP服務器**: `mail.panjit.com.tw:25`
|
||||
- **發送者**: `todo-system@panjit.com.tw`
|
||||
|
||||
#### 🌐 服務端口
|
||||
- **前端**: `12012`
|
||||
- **後端API**: `12011`
|
||||
|
||||
## 🐳 Docker配置
|
||||
|
||||
### 服務組成
|
||||
|
||||
1. **todo-backend-prod**: Flask後端容器
|
||||
- 端口映射: `12011:12011`
|
||||
- 健康檢查: `/api/health`
|
||||
- 自動重啟: `unless-stopped`
|
||||
|
||||
2. **todo-frontend-prod**: Next.js前端容器
|
||||
- 端口映射: `12012:12012`
|
||||
- 健康檢查: 根路徑檢查
|
||||
- 自動重啟: `unless-stopped`
|
||||
|
||||
### 網路配置
|
||||
|
||||
- 使用自定義橋接網路 `todolist-network`
|
||||
- 容器間可通過服務名稱通信
|
||||
- 外部訪問通過端口映射
|
||||
|
||||
## 🔍 手動部署步驟
|
||||
|
||||
如果需要手動部署,請按以下步驟執行:
|
||||
|
||||
### 1. 停止現有服務
|
||||
|
||||
```bash
|
||||
# 停止並移除現有容器
|
||||
docker stop todo-backend-prod todo-frontend-prod
|
||||
docker rm todo-backend-prod todo-frontend-prod
|
||||
```
|
||||
|
||||
### 2. 建置Docker鏡像
|
||||
|
||||
```bash
|
||||
# 建置後端鏡像
|
||||
docker build -t todolist-backend:latest ./backend
|
||||
|
||||
# 建置前端鏡像
|
||||
docker build -t todo-frontend:latest \
|
||||
--build-arg NEXT_PUBLIC_API_URL=http://localhost:12011 \
|
||||
./frontend
|
||||
```
|
||||
|
||||
### 3. 啟動服務
|
||||
|
||||
```bash
|
||||
# 使用Docker Compose啟動
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 4. 驗證部署
|
||||
|
||||
```bash
|
||||
# 檢查容器狀態
|
||||
docker ps
|
||||
|
||||
# 檢查服務健康
|
||||
curl http://localhost:12011/api/health
|
||||
curl http://localhost:12012
|
||||
```
|
||||
|
||||
## 🧪 測試與驗證
|
||||
|
||||
|
||||
### API測試
|
||||
|
||||
```bash
|
||||
# 健康檢查
|
||||
curl http://localhost:12011/api/health
|
||||
|
||||
# CORS測試
|
||||
curl -H "Origin: http://localhost:12012" \
|
||||
-H "Access-Control-Request-Method: POST" \
|
||||
-H "Access-Control-Request-Headers: Content-Type,Authorization" \
|
||||
-X OPTIONS http://localhost:12011/api/auth/login
|
||||
```
|
||||
|
||||
## 🛠️ 維護指令
|
||||
|
||||
### 日誌查看
|
||||
|
||||
```bash
|
||||
# 查看所有服務日誌
|
||||
docker-compose -f docker-compose.prod.yml logs -f
|
||||
|
||||
# 查看特定服務日誌
|
||||
docker logs todo-backend-prod -f
|
||||
docker logs todo-frontend-prod -f
|
||||
```
|
||||
|
||||
### 服務管理
|
||||
|
||||
```bash
|
||||
# 重啟服務
|
||||
docker-compose -f docker-compose.prod.yml restart
|
||||
|
||||
# 停止服務
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
|
||||
# 更新並重啟
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
docker-compose -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
### 資源監控
|
||||
|
||||
```bash
|
||||
# 查看容器狀態
|
||||
docker ps
|
||||
|
||||
# 查看資源使用
|
||||
docker stats
|
||||
|
||||
# 查看容器詳情
|
||||
docker inspect todo-backend-prod
|
||||
docker inspect todo-frontend-prod
|
||||
```
|
||||
|
||||
## 🚨 故障排除
|
||||
|
||||
### 常見問題
|
||||
|
||||
#### 1. 容器無法啟動
|
||||
```bash
|
||||
# 檢查日誌
|
||||
docker logs todo-backend-prod
|
||||
docker logs todo-frontend-prod
|
||||
|
||||
# 檢查端口占用
|
||||
netstat -ano | findstr :12011
|
||||
netstat -ano | findstr :12012
|
||||
```
|
||||
|
||||
#### 2. 資料庫連接失敗
|
||||
- 確認網路連通性到 `mysql.theaken.com:33306`
|
||||
- 驗證資料庫憑證
|
||||
- 檢查防火牆設置
|
||||
|
||||
#### 3. LDAP認證失敗
|
||||
- 確認網路連通性到 `panjit.com.tw:389`
|
||||
- 驗證LDAP服務帳號憑證
|
||||
- 檢查搜索基礎設置
|
||||
|
||||
#### 4. CORS錯誤
|
||||
- 確認前後端URL配置
|
||||
- 檢查 `CORS_ORIGINS` 環境變量
|
||||
- 驗證前端請求標頭
|
||||
|
||||
### 健康檢查端點
|
||||
|
||||
- **後端健康檢查**: `GET http://localhost:12011/api/health`
|
||||
- **前端健康檢查**: `GET http://localhost:12012`
|
||||
|
||||
## 🔒 安全考量
|
||||
|
||||
### 生產環境安全設置
|
||||
|
||||
1. **更改默認密鑰**:
|
||||
- 修改 `SECRET_KEY` 和 `JWT_SECRET_KEY`
|
||||
- 使用強密碼策略
|
||||
|
||||
2. **網路安全**:
|
||||
- 考慮使用反向代理(Nginx)
|
||||
- 配置HTTPS證書
|
||||
- 限制外部訪問
|
||||
|
||||
3. **監控與日誌**:
|
||||
- 設置日誌輪轉
|
||||
- 監控系統資源
|
||||
- 設置告警機制
|
||||
|
||||
## 📞 支援聯繫
|
||||
|
||||
- **系統管理員**: `ymirliu@panjit.com.tw`
|
||||
- **技術支援**: 參考專案文檔或聯繫開發團隊
|
||||
|
||||
## 📝 版本資訊
|
||||
|
||||
- **系統版本**: 1.0.0
|
||||
- **Docker映像**:
|
||||
- Backend: `todolist-backend:latest`
|
||||
- Frontend: `todo-frontend:latest`
|
||||
- **部署日期**: 自動生成
|
||||
|
||||
---
|
||||
|
||||
**注意**: 本文件包含敏感配置資訊,請妥善保管,僅限授權人員查看。
|
99
backend/.dockerignore
Normal file
99
backend/.dockerignore
Normal file
@@ -0,0 +1,99 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Virtual environments
|
||||
venv/
|
||||
env/
|
||||
ENV/
|
||||
.venv/
|
||||
.env/
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.local
|
||||
.env.development
|
||||
.env.production
|
||||
|
||||
# Flask
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Celery
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Uploads
|
||||
uploads/
|
||||
temp/
|
||||
tmp/
|
||||
|
||||
# Database
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
LICENSE
|
||||
docs/
|
||||
|
||||
# Docker files
|
||||
Dockerfile*
|
||||
.dockerignore
|
||||
docker-compose*.yml
|
||||
|
||||
# Testing
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
.tox/
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
103
deploy.bat
Normal file
103
deploy.bat
Normal file
@@ -0,0 +1,103 @@
|
||||
@echo off
|
||||
REM ===========================================
|
||||
REM TODO管理系統 - 生產環境部署腳本
|
||||
REM ===========================================
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo TODO管理系統 - 生產環境部署
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM 檢查Docker是否運行
|
||||
echo [INFO] 檢查Docker狀態...
|
||||
docker info >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo [ERROR] Docker未運行,請啟動Docker Desktop後再執行此腳本
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo [SUCCESS] Docker運行正常
|
||||
|
||||
REM 停止現有容器
|
||||
echo.
|
||||
echo [INFO] 停止現有容器...
|
||||
docker stop todo-backend-prod todo-frontend-prod 2>nul
|
||||
docker rm todo-backend-prod todo-frontend-prod 2>nul
|
||||
|
||||
REM 建置Docker鏡像
|
||||
echo.
|
||||
echo [INFO] 建置Docker鏡像...
|
||||
echo [INFO] 建置後端鏡像...
|
||||
docker build -t todolist-backend:latest ./backend
|
||||
if %errorlevel% neq 0 (
|
||||
echo [ERROR] 後端鏡像建置失敗
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo [SUCCESS] 後端鏡像建置完成
|
||||
|
||||
echo [INFO] 建置前端鏡像...
|
||||
docker build -t todo-frontend:latest --build-arg NEXT_PUBLIC_API_URL=http://localhost:12011 ./frontend
|
||||
if %errorlevel% neq 0 (
|
||||
echo [ERROR] 前端鏡像建置失敗
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo [SUCCESS] 前端鏡像建置完成
|
||||
|
||||
REM 啟動服務
|
||||
echo.
|
||||
echo [INFO] 啟動生產環境服務...
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
if %errorlevel% neq 0 (
|
||||
echo [ERROR] 服務啟動失敗
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 等待服務啟動
|
||||
echo [INFO] 等待服務啟動...
|
||||
timeout /t 10 /nobreak >nul
|
||||
|
||||
REM 檢查服務狀態
|
||||
echo.
|
||||
echo [INFO] 檢查服務狀態...
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | findstr todo-
|
||||
|
||||
REM 健康檢查
|
||||
echo.
|
||||
echo [INFO] 執行健康檢查...
|
||||
|
||||
echo [INFO] 檢查後端API...
|
||||
curl -s -w "%%{http_code}" -o nul http://localhost:12011/api/health >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
echo [SUCCESS] 後端API響應正常
|
||||
) else (
|
||||
echo [WARNING] 後端API可能尚未完全啟動,請稍後手動檢查
|
||||
)
|
||||
|
||||
echo [INFO] 檢查前端...
|
||||
curl -s -w "%%{http_code}" -o nul http://localhost:12012 >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
echo [SUCCESS] 前端響應正常
|
||||
) else (
|
||||
echo [WARNING] 前端可能尚未完全啟動,請稍後手動檢查
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo 部署完成!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo 服務地址:
|
||||
echo 前端: http://localhost:12012
|
||||
echo 後端API: http://localhost:12011
|
||||
echo.
|
||||
echo.
|
||||
echo 管理指令:
|
||||
echo 查看日誌: docker-compose -f docker-compose.prod.yml logs -f
|
||||
echo 停止服務: docker-compose -f docker-compose.prod.yml down
|
||||
echo 重啟服務: docker-compose -f docker-compose.prod.yml restart
|
||||
echo.
|
||||
pause
|
93
deploy.sh
Normal file
93
deploy.sh
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# TODO管理系統 - 生產環境部署腳本 (Linux/Mac)
|
||||
# ===========================================
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo "TODO管理系統 - 生產環境部署"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# 檢查Docker是否運行
|
||||
echo "[INFO] 檢查Docker狀態..."
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
echo "[ERROR] Docker未運行,請啟動Docker後再執行此腳本"
|
||||
exit 1
|
||||
fi
|
||||
echo "[SUCCESS] Docker運行正常"
|
||||
|
||||
# 停止現有容器
|
||||
echo ""
|
||||
echo "[INFO] 停止現有容器..."
|
||||
docker stop todo-backend-prod todo-frontend-prod 2>/dev/null || true
|
||||
docker rm todo-backend-prod todo-frontend-prod 2>/dev/null || true
|
||||
|
||||
# 建置Docker鏡像
|
||||
echo ""
|
||||
echo "[INFO] 建置Docker鏡像..."
|
||||
echo "[INFO] 建置後端鏡像..."
|
||||
if ! docker build -t todolist-backend:latest ./backend; then
|
||||
echo "[ERROR] 後端鏡像建置失敗"
|
||||
exit 1
|
||||
fi
|
||||
echo "[SUCCESS] 後端鏡像建置完成"
|
||||
|
||||
echo "[INFO] 建置前端鏡像..."
|
||||
if ! docker build -t todo-frontend:latest --build-arg NEXT_PUBLIC_API_URL=http://localhost:12011 ./frontend; then
|
||||
echo "[ERROR] 前端鏡像建置失敗"
|
||||
exit 1
|
||||
fi
|
||||
echo "[SUCCESS] 前端鏡像建置完成"
|
||||
|
||||
# 啟動服務
|
||||
echo ""
|
||||
echo "[INFO] 啟動生產環境服務..."
|
||||
if ! docker-compose -f docker-compose.prod.yml up -d; then
|
||||
echo "[ERROR] 服務啟動失敗"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 等待服務啟動
|
||||
echo "[INFO] 等待服務啟動..."
|
||||
sleep 10
|
||||
|
||||
# 檢查服務狀態
|
||||
echo ""
|
||||
echo "[INFO] 檢查服務狀態..."
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep todo-
|
||||
|
||||
# 健康檢查
|
||||
echo ""
|
||||
echo "[INFO] 執行健康檢查..."
|
||||
|
||||
echo "[INFO] 檢查後端API..."
|
||||
if curl -s -f http://localhost:12011/api/health >/dev/null 2>&1; then
|
||||
echo "[SUCCESS] 後端API響應正常"
|
||||
else
|
||||
echo "[WARNING] 後端API可能尚未完全啟動,請稍後手動檢查"
|
||||
fi
|
||||
|
||||
echo "[INFO] 檢查前端..."
|
||||
if curl -s -f http://localhost:12012 >/dev/null 2>&1; then
|
||||
echo "[SUCCESS] 前端響應正常"
|
||||
else
|
||||
echo "[WARNING] 前端可能尚未完全啟動,請稍後手動檢查"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo "部署完成!"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
echo "服務地址:"
|
||||
echo " 前端: http://localhost:12012"
|
||||
echo " 後端API: http://localhost:12011"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "管理指令:"
|
||||
echo " 查看日誌: docker-compose -f docker-compose.prod.yml logs -f"
|
||||
echo " 停止服務: docker-compose -f docker-compose.prod.yml down"
|
||||
echo " 重啟服務: docker-compose -f docker-compose.prod.yml restart"
|
||||
echo ""
|
94
docker-compose.prod.yml
Normal file
94
docker-compose.prod.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
todo-backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
image: todolist-backend:latest
|
||||
container_name: todo-backend-prod
|
||||
ports:
|
||||
- "12011:12011"
|
||||
environment:
|
||||
# MySQL Database Configuration
|
||||
- DATABASE_URL=mysql+pymysql://A060:WLeSCi0yhtc7@mysql.theaken.com:33306/db_A060
|
||||
- MYSQL_HOST=mysql.theaken.com
|
||||
- MYSQL_PORT=33306
|
||||
- MYSQL_USER=A060
|
||||
- MYSQL_PASSWORD=WLeSCi0yhtc7
|
||||
- MYSQL_DATABASE=db_A060
|
||||
- MYSQL_CHARSET=utf8mb4
|
||||
|
||||
# CORS Configuration
|
||||
- CORS_ORIGINS=http://localhost:12012
|
||||
|
||||
# LDAP Configuration (Production)
|
||||
- USE_MOCK_LDAP=false
|
||||
- LDAP_SERVER=panjit.com.tw
|
||||
- LDAP_PORT=389
|
||||
- LDAP_USE_SSL=false
|
||||
- LDAP_BIND_USER_DN=CN=LdapBind,CN=Users,DC=PANJIT,DC=COM,DC=TW
|
||||
- LDAP_BIND_USER_PASSWORD=panjit2481
|
||||
- LDAP_SEARCH_BASE=OU=PANJIT,DC=panjit,DC=com,DC=tw
|
||||
- LDAP_USER_LOGIN_ATTR=userPrincipalName
|
||||
|
||||
# SMTP Configuration
|
||||
- SMTP_SERVER=mail.panjit.com.tw
|
||||
- SMTP_PORT=25
|
||||
- SMTP_USE_TLS=false
|
||||
- SMTP_USE_SSL=false
|
||||
- SMTP_AUTH_REQUIRED=false
|
||||
- SMTP_SENDER_EMAIL=todo-system@panjit.com.tw
|
||||
- SMTP_SENDER_PASSWORD=
|
||||
|
||||
# Flask Configuration
|
||||
- FLASK_ENV=production
|
||||
- SECRET_KEY=your-production-secret-key-change-me
|
||||
- JWT_SECRET_KEY=your-jwt-secret-key-change-me
|
||||
|
||||
# Logging
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:12011/api/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- todolist-network
|
||||
|
||||
todo-frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:12011
|
||||
image: todo-frontend:latest
|
||||
container_name: todo-frontend-prod
|
||||
ports:
|
||||
- "12012:12012"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:12011
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:12012"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- todolist-network
|
||||
depends_on:
|
||||
- todo-backend
|
||||
|
||||
networks:
|
||||
todolist-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
backend-logs:
|
||||
driver: local
|
||||
frontend-logs:
|
||||
driver: local
|
60
frontend/.dockerignore
Normal file
60
frontend/.dockerignore
Normal file
@@ -0,0 +1,60 @@
|
||||
node_modules
|
||||
.git
|
||||
.next
|
||||
out
|
||||
build
|
||||
dist
|
||||
coverage
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
LICENSE
|
||||
docs/
|
||||
|
||||
# Docker files
|
||||
Dockerfile*
|
||||
.dockerignore
|
||||
docker-compose*.yml
|
||||
|
||||
# Git files
|
||||
.gitignore
|
||||
.gitattributes
|
@@ -7,7 +7,7 @@ WORKDIR /app
|
||||
|
||||
# Install dependencies based on the preferred package manager
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm ci --only=production
|
||||
RUN npm ci
|
||||
|
||||
# Rebuild the source code only when needed
|
||||
FROM base AS builder
|
||||
@@ -15,6 +15,10 @@ WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
# Set build-time environment variables
|
||||
ARG NEXT_PUBLIC_API_URL=http://localhost:12011
|
||||
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
|
@@ -52,6 +52,7 @@ interface TodoImportData {
|
||||
due_date: string | null;
|
||||
responsible_users: string[];
|
||||
followers: string[];
|
||||
is_public: boolean;
|
||||
}
|
||||
|
||||
const ExcelImport: React.FC<ExcelImportProps> = ({ open, onClose, onImportComplete }) => {
|
||||
|
@@ -67,6 +67,7 @@ interface LocalTodo {
|
||||
creator?: User;
|
||||
responsible: User[];
|
||||
isPublic: boolean;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
interface TodoDialogProps {
|
||||
|
@@ -24,6 +24,7 @@ export interface Todo {
|
||||
followers: string[];
|
||||
responsible_users_details?: UserDetail[];
|
||||
followers_details?: UserDetail[];
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export interface TodoCreate {
|
||||
@@ -36,6 +37,7 @@ export interface TodoCreate {
|
||||
is_public?: boolean;
|
||||
responsible_users?: string[];
|
||||
followers?: string[];
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export interface TodoUpdate extends Partial<TodoCreate> {
|
||||
|
74
manage.bat
Normal file
74
manage.bat
Normal file
@@ -0,0 +1,74 @@
|
||||
@echo off
|
||||
REM ===========================================
|
||||
REM TODO管理系統 - 管理腳本
|
||||
REM ===========================================
|
||||
|
||||
if "%1"=="" (
|
||||
echo.
|
||||
echo TODO管理系統 - 管理指令
|
||||
echo.
|
||||
echo 用法: manage.bat [指令]
|
||||
echo.
|
||||
echo 可用指令:
|
||||
echo start - 啟動服務
|
||||
echo stop - 停止服務
|
||||
echo restart - 重啟服務
|
||||
echo logs - 查看日誌
|
||||
echo status - 查看服務狀態
|
||||
echo build - 重新建置並啟動
|
||||
echo clean - 清理未使用的Docker資源
|
||||
echo.
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
if "%1"=="start" (
|
||||
echo [INFO] 啟動TODO管理系統...
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1"=="stop" (
|
||||
echo [INFO] 停止TODO管理系統...
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1"=="restart" (
|
||||
echo [INFO] 重啟TODO管理系統...
|
||||
docker-compose -f docker-compose.prod.yml restart
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1"=="logs" (
|
||||
echo [INFO] 查看服務日誌 (Ctrl+C 退出)...
|
||||
docker-compose -f docker-compose.prod.yml logs -f
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1"=="status" (
|
||||
echo [INFO] 服務狀態:
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | findstr todo-
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1"=="build" (
|
||||
echo [INFO] 重新建置並啟動服務...
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
docker build -t todolist-backend:latest ./backend
|
||||
docker build -t todo-frontend:latest --build-arg NEXT_PUBLIC_API_URL=http://localhost:12011 ./frontend
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1"=="clean" (
|
||||
echo [INFO] 清理未使用的Docker資源...
|
||||
docker system prune -f
|
||||
echo [SUCCESS] 清理完成
|
||||
goto end
|
||||
)
|
||||
|
||||
echo [ERROR] 未知指令: %1
|
||||
echo 使用 'manage.bat' 查看可用指令
|
||||
|
||||
:end
|
||||
echo.
|
Reference in New Issue
Block a user