2ND
This commit is contained in:
690
DEPLOYMENT.md
Normal file
690
DEPLOYMENT.md
Normal file
@@ -0,0 +1,690 @@
|
||||
# 部署指南 - 暫時規範管理系統 V3
|
||||
|
||||
本文件提供詳細的部署指導,涵蓋不同平台和環境的部署方式。
|
||||
|
||||
## 📋 目錄
|
||||
|
||||
1. [快速開始](#1-快速開始)
|
||||
2. [平台特定部署](#2-平台特定部署)
|
||||
3. [Docker 部署](#3-docker-部署)
|
||||
4. [生產環境部署](#4-生產環境部署)
|
||||
5. [疑難排解](#5-疑難排解)
|
||||
|
||||
## 1. 快速開始
|
||||
|
||||
### 前置需求檢查清單
|
||||
|
||||
- [ ] Python 3.8+ 已安裝
|
||||
- [ ] Docker 已安裝且運行中 (如使用 Docker 部署)
|
||||
- [ ] MySQL 8.0+ 或相容的資料庫
|
||||
- [ ] ONLYOFFICE Document Server
|
||||
- [ ] LDAP/Active Directory 伺服器 (企業環境)
|
||||
- [ ] SMTP 郵件伺服器
|
||||
|
||||
### 一鍵啟動
|
||||
|
||||
#### Windows 環境
|
||||
```cmd
|
||||
# 使用自動化腳本啟動
|
||||
start-windows.bat
|
||||
|
||||
# 或手動執行
|
||||
docker-compose up -d
|
||||
docker-compose exec app python init_db.py
|
||||
```
|
||||
|
||||
#### Linux 環境
|
||||
```bash
|
||||
# 使用自動化腳本啟動
|
||||
chmod +x start-linux.sh
|
||||
./start-linux.sh
|
||||
|
||||
# 或手動執行
|
||||
docker-compose up -d
|
||||
docker-compose exec app python init_db.py
|
||||
```
|
||||
|
||||
## 2. 平台特定部署
|
||||
|
||||
### 2.1 Windows 部署
|
||||
|
||||
#### 開發環境
|
||||
|
||||
1. **準備環境**
|
||||
```cmd
|
||||
# 建立虛擬環境
|
||||
python -m venv venv
|
||||
venv\Scripts\activate
|
||||
|
||||
# 安裝依賴
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **設定環境變數**
|
||||
```cmd
|
||||
copy .env.example .env
|
||||
# 編輯 .env 檔案設定參數
|
||||
```
|
||||
|
||||
3. **啟動外部服務**
|
||||
```cmd
|
||||
# 啟動 MySQL (使用 Docker)
|
||||
docker run -d --name tempspec-mysql ^
|
||||
-e MYSQL_ROOT_PASSWORD=tempspec123 ^
|
||||
-e MYSQL_DATABASE=tempspec_db ^
|
||||
-e MYSQL_USER=tempspec_user ^
|
||||
-e MYSQL_PASSWORD=tempspec_pass ^
|
||||
-p 3306:3306 mysql:8.0
|
||||
|
||||
# 啟動 ONLYOFFICE
|
||||
docker run -d --name tempspec-onlyoffice ^
|
||||
-e JWT_ENABLED=true ^
|
||||
-e JWT_SECRET=your_jwt_secret ^
|
||||
-p 8080:80 onlyoffice/documentserver
|
||||
```
|
||||
|
||||
4. **初始化並啟動應用**
|
||||
```cmd
|
||||
python init_db.py
|
||||
python app.py
|
||||
```
|
||||
|
||||
#### 生產環境 (Windows Server + IIS)
|
||||
|
||||
1. **安裝 IIS 和 HttpPlatformHandler**
|
||||
- 啟用 IIS 功能
|
||||
- 安裝 HttpPlatformHandler 模組
|
||||
|
||||
2. **建立應用程式目錄**
|
||||
```cmd
|
||||
mkdir C:\inetpub\wwwroot\tempspec
|
||||
xcopy /E /I . C:\inetpub\wwwroot\tempspec
|
||||
```
|
||||
|
||||
3. **建立 Web.config**
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="PythonHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
|
||||
</handlers>
|
||||
<httpPlatform processPath="C:\Python310\python.exe"
|
||||
arguments="app.py"
|
||||
startupTimeLimit="60"
|
||||
startupRetryCount="3"
|
||||
stdoutLogEnabled="true"
|
||||
stdoutLogFile="logs\python.log"
|
||||
environmentVariables="PYTHONPATH=C:\inetpub\wwwroot\tempspec">
|
||||
<environmentVariables>
|
||||
<environmentVariable name="PYTHONPATH" value="C:\inetpub\wwwroot\tempspec" />
|
||||
</environmentVariables>
|
||||
</httpPlatform>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
4. **使用 Waitress (建議方式)**
|
||||
```cmd
|
||||
pip install waitress
|
||||
waitress-serve --host=0.0.0.0 --port=5000 app:app
|
||||
```
|
||||
|
||||
#### Windows 服務安裝
|
||||
|
||||
使用 NSSM (Non-Sucking Service Manager):
|
||||
|
||||
```cmd
|
||||
# 下載 NSSM
|
||||
# https://nssm.cc/download
|
||||
|
||||
# 安裝服務
|
||||
nssm install TempSpecSystem
|
||||
|
||||
# 設定參數
|
||||
nssm set TempSpecSystem Application "C:\path\to\python.exe"
|
||||
nssm set TempSpecSystem AppParameters "app.py"
|
||||
nssm set TempSpecSystem AppDirectory "C:\path\to\your\app"
|
||||
nssm set TempSpecSystem DisplayName "Temp Spec System V3"
|
||||
nssm set TempSpecSystem Description "企業暫時規範管理系統"
|
||||
|
||||
# 啟動服務
|
||||
nssm start TempSpecSystem
|
||||
```
|
||||
|
||||
### 2.2 Linux 部署
|
||||
|
||||
#### 開發環境
|
||||
|
||||
1. **準備環境 (Ubuntu/Debian)**
|
||||
```bash
|
||||
# 更新系統
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# 安裝必要套件
|
||||
sudo apt install python3 python3-pip python3-venv git curl -y
|
||||
|
||||
# 建立虛擬環境
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安裝依賴
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **CentOS/RHEL 環境**
|
||||
```bash
|
||||
# 安裝 EPEL repository
|
||||
sudo yum install epel-release -y
|
||||
|
||||
# 安裝必要套件
|
||||
sudo yum install python3 python3-pip git curl -y
|
||||
|
||||
# 建立虛擬環境
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安裝依賴
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
#### 生產環境 (Nginx + Gunicorn)
|
||||
|
||||
1. **安裝 Gunicorn**
|
||||
```bash
|
||||
pip install gunicorn gevent
|
||||
```
|
||||
|
||||
2. **建立 Gunicorn 設定檔**
|
||||
```python
|
||||
# gunicorn.conf.py
|
||||
bind = "127.0.0.1:5000"
|
||||
workers = 4
|
||||
worker_class = "gevent"
|
||||
worker_connections = 1000
|
||||
max_requests = 1000
|
||||
max_requests_jitter = 50
|
||||
timeout = 30
|
||||
keepalive = 2
|
||||
preload_app = True
|
||||
```
|
||||
|
||||
3. **建立 systemd 服務檔案**
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/tempspec.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Temp Spec System V3
|
||||
After=network.target mysql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/path/to/your/app
|
||||
Environment="PATH=/path/to/your/app/venv/bin"
|
||||
ExecStart=/path/to/your/app/venv/bin/gunicorn -c gunicorn.conf.py app:app
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
4. **啟動服務**
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable tempspec
|
||||
sudo systemctl start tempspec
|
||||
sudo systemctl status tempspec
|
||||
```
|
||||
|
||||
5. **設定 Nginx**
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/tempspec
|
||||
```
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
# SSL 重定向 (生產環境建議)
|
||||
# return 301 https://$server_name$request_uri;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket 支援
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# 靜態檔案
|
||||
location /static/ {
|
||||
alias /path/to/your/app/static/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# 大檔案上傳支援
|
||||
client_max_body_size 100M;
|
||||
}
|
||||
```
|
||||
|
||||
6. **啟用站點**
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/tempspec /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## 3. Docker 部署
|
||||
|
||||
### 3.1 基本 Docker 部署
|
||||
|
||||
```bash
|
||||
# 1. 複製環境設定檔
|
||||
cp .env.example .env
|
||||
# 編輯 .env 設定參數
|
||||
|
||||
# 2. 啟動所有服務
|
||||
docker-compose up -d
|
||||
|
||||
# 3. 初始化資料庫
|
||||
docker-compose exec app python init_db.py
|
||||
|
||||
# 4. 檢查服務狀態
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### 3.2 開發環境部署
|
||||
|
||||
```bash
|
||||
# 使用 override 檔案啟動開發環境
|
||||
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
|
||||
|
||||
# 查看即時日誌
|
||||
docker-compose logs -f app
|
||||
```
|
||||
|
||||
### 3.3 生產環境部署
|
||||
|
||||
```bash
|
||||
# 啟動包含 Nginx 的完整生產環境
|
||||
docker-compose --profile production up -d
|
||||
|
||||
# 檢查所有服務
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### 3.4 Docker Swarm 部署 (高可用性)
|
||||
|
||||
1. **初始化 Swarm**
|
||||
```bash
|
||||
docker swarm init
|
||||
```
|
||||
|
||||
2. **建立 Docker Stack 檔案**
|
||||
```yaml
|
||||
# docker-stack.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
image: tempspec:latest
|
||||
deploy:
|
||||
replicas: 3
|
||||
update_config:
|
||||
parallelism: 1
|
||||
delay: 10s
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
networks:
|
||||
- tempspec-network
|
||||
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == manager
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
networks:
|
||||
- tempspec-network
|
||||
|
||||
networks:
|
||||
tempspec-network:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
```
|
||||
|
||||
3. **部署 Stack**
|
||||
```bash
|
||||
docker stack deploy -c docker-stack.yml tempspec
|
||||
```
|
||||
|
||||
### 3.5 Docker 管理指令
|
||||
|
||||
```bash
|
||||
# 查看服務狀態
|
||||
docker-compose ps
|
||||
|
||||
# 查看日誌
|
||||
docker-compose logs -f [service_name]
|
||||
|
||||
# 重啟服務
|
||||
docker-compose restart [service_name]
|
||||
|
||||
# 進入容器
|
||||
docker-compose exec app bash
|
||||
|
||||
# 備份資料庫
|
||||
docker-compose exec mysql mysqldump -u root -p tempspec_db > backup.sql
|
||||
|
||||
# 清理未使用的資源
|
||||
docker system prune -f
|
||||
docker volume prune -f
|
||||
```
|
||||
|
||||
## 4. 生產環境部署
|
||||
|
||||
### 4.1 負載均衡部署
|
||||
|
||||
使用多個應用程式實例提高可用性:
|
||||
|
||||
```yaml
|
||||
# docker-compose.prod.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app1:
|
||||
build: .
|
||||
environment:
|
||||
- INSTANCE_ID=1
|
||||
# 其他設定...
|
||||
|
||||
app2:
|
||||
build: .
|
||||
environment:
|
||||
- INSTANCE_ID=2
|
||||
# 其他設定...
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./nginx/nginx-lb.conf:/etc/nginx/nginx.conf
|
||||
ports:
|
||||
- "80:80"
|
||||
depends_on:
|
||||
- app1
|
||||
- app2
|
||||
```
|
||||
|
||||
### 4.2 SSL/HTTPS 設定
|
||||
|
||||
1. **獲取 SSL 證書 (Let's Encrypt)**
|
||||
```bash
|
||||
# 安裝 Certbot
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
|
||||
# 獲取證書
|
||||
sudo certbot --nginx -d your-domain.com
|
||||
```
|
||||
|
||||
2. **Docker 環境 SSL 設定**
|
||||
```yaml
|
||||
# docker-compose.ssl.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
nginx:
|
||||
volumes:
|
||||
- /etc/letsencrypt:/etc/letsencrypt:ro
|
||||
- ./nginx/ssl.conf:/etc/nginx/conf.d/default.conf
|
||||
ports:
|
||||
- "443:443"
|
||||
- "80:80"
|
||||
```
|
||||
|
||||
### 4.3 監控和日誌
|
||||
|
||||
1. **集成監控 (可選)**
|
||||
```yaml
|
||||
# 添加到 docker-compose.yml
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
ports:
|
||||
- "9090:9090"
|
||||
volumes:
|
||||
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
```
|
||||
|
||||
2. **集中化日誌收集**
|
||||
```yaml
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:7.14.0
|
||||
ports:
|
||||
- "5601:5601"
|
||||
```
|
||||
|
||||
### 4.4 備份策略
|
||||
|
||||
1. **資料庫備份腳本**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# backup-db.sh
|
||||
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR="/backup/mysql"
|
||||
CONTAINER_NAME="tempspec-mysql"
|
||||
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 備份資料庫
|
||||
docker exec $CONTAINER_NAME mysqldump \
|
||||
-u root -p$MYSQL_ROOT_PASSWORD \
|
||||
tempspec_db > $BACKUP_DIR/tempspec_$DATE.sql
|
||||
|
||||
# 壓縮備份檔案
|
||||
gzip $BACKUP_DIR/tempspec_$DATE.sql
|
||||
|
||||
# 刪除 30 天前的備份
|
||||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||||
|
||||
echo "Database backup completed: tempspec_$DATE.sql.gz"
|
||||
```
|
||||
|
||||
2. **設定 cron 自動備份**
|
||||
```bash
|
||||
# 編輯 crontab
|
||||
crontab -e
|
||||
|
||||
# 每天凌晨 2:30 執行備份
|
||||
30 2 * * * /path/to/backup-db.sh >> /var/log/tempspec-backup.log 2>&1
|
||||
```
|
||||
|
||||
## 5. 疑難排解
|
||||
|
||||
### 5.1 常見問題
|
||||
|
||||
#### 問題:Docker 容器無法啟動
|
||||
|
||||
**可能原因**:
|
||||
- 端口被占用
|
||||
- 環境變數設定錯誤
|
||||
- 磁碟空間不足
|
||||
|
||||
**解決方案**:
|
||||
```bash
|
||||
# 檢查端口占用
|
||||
netstat -tulpn | grep :5000
|
||||
|
||||
# 檢查容器日誌
|
||||
docker-compose logs app
|
||||
|
||||
# 檢查磁碟空間
|
||||
df -h
|
||||
|
||||
# 清理 Docker 資源
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
#### 問題:LDAP 連線失敗
|
||||
|
||||
**檢查清單**:
|
||||
- [ ] LDAP 伺服器地址正確
|
||||
- [ ] 防火牆開放 389/636 端口
|
||||
- [ ] 服務帳號權限足夠
|
||||
- [ ] 搜尋基底設定正確
|
||||
|
||||
**測試 LDAP 連線**:
|
||||
```bash
|
||||
# 使用 ldapsearch 測試
|
||||
ldapsearch -H ldap://your-dc.company.com -D "CN=service,DC=company,DC=com" -W -b "DC=company,DC=com"
|
||||
|
||||
# 或在 Python 中測試
|
||||
python3 -c "
|
||||
from ldap_utils import authenticate_ldap_user
|
||||
result = authenticate_ldap_user('testuser', 'testpass')
|
||||
print('LDAP Test Result:', result)
|
||||
"
|
||||
```
|
||||
|
||||
#### 問題:ONLYOFFICE 編輯器載入失敗
|
||||
|
||||
**檢查項目**:
|
||||
- [ ] Document Server 容器運行正常
|
||||
- [ ] JWT Secret 設定一致
|
||||
- [ ] 網路連線可達
|
||||
- [ ] 瀏覽器支援 WebSocket
|
||||
|
||||
**測試方法**:
|
||||
```bash
|
||||
# 檢查 ONLYOFFICE 健康狀態
|
||||
curl http://localhost:8080/healthcheck
|
||||
|
||||
# 檢查容器狀態
|
||||
docker logs tempspec-onlyoffice
|
||||
|
||||
# 測試 JWT 設定
|
||||
docker exec tempspec-onlyoffice cat /etc/onlyoffice/documentserver/default.json | grep -i jwt
|
||||
```
|
||||
|
||||
#### 問題:排程任務未執行
|
||||
|
||||
**檢查步驟**:
|
||||
1. 確認 APScheduler 已初始化
|
||||
2. 檢查應用程式日誌
|
||||
3. 驗證任務註冊
|
||||
|
||||
```python
|
||||
# 在 Flask shell 中檢查任務
|
||||
from app import scheduler
|
||||
print(scheduler.get_jobs())
|
||||
```
|
||||
|
||||
### 5.2 效能調校
|
||||
|
||||
#### 資料庫最佳化
|
||||
|
||||
```sql
|
||||
-- 檢查慢查詢
|
||||
SHOW VARIABLES LIKE 'slow_query_log';
|
||||
SHOW VARIABLES LIKE 'long_query_time';
|
||||
|
||||
-- 分析資料表
|
||||
ANALYZE TABLE ts_temp_spec;
|
||||
ANALYZE TABLE ts_user;
|
||||
ANALYZE TABLE ts_upload;
|
||||
|
||||
-- 建立必要索引
|
||||
CREATE INDEX idx_spec_status ON ts_temp_spec(status);
|
||||
CREATE INDEX idx_spec_end_date ON ts_temp_spec(end_date);
|
||||
CREATE INDEX idx_history_spec_id ON ts_spec_history(spec_id);
|
||||
```
|
||||
|
||||
#### 應用程式最佳化
|
||||
|
||||
```python
|
||||
# config.py 調整
|
||||
class ProductionConfig(Config):
|
||||
# 資料庫連線池設定
|
||||
SQLALCHEMY_ENGINE_OPTIONS = {
|
||||
'pool_size': 20,
|
||||
'pool_recycle': 300,
|
||||
'pool_pre_ping': True
|
||||
}
|
||||
|
||||
# Redis 快取 (可選)
|
||||
CACHE_TYPE = 'redis'
|
||||
CACHE_REDIS_URL = 'redis://redis:6379/0'
|
||||
```
|
||||
|
||||
### 5.3 監控指標
|
||||
|
||||
重要的監控指標:
|
||||
|
||||
- **應用程式指標**
|
||||
- 回應時間
|
||||
- 錯誤率
|
||||
- 記憶體使用率
|
||||
- CPU 使用率
|
||||
|
||||
- **資料庫指標**
|
||||
- 連線數
|
||||
- 查詢執行時間
|
||||
- 緩衝池命中率
|
||||
|
||||
- **系統指標**
|
||||
- 磁碟使用率
|
||||
- 網路流量
|
||||
- 檔案描述符使用率
|
||||
|
||||
```bash
|
||||
# 系統監控腳本範例
|
||||
#!/bin/bash
|
||||
# monitor.sh
|
||||
|
||||
echo "=== System Status ==="
|
||||
echo "CPU Usage: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)"
|
||||
echo "Memory Usage: $(free | grep Mem | awk '{printf("%.1f%%", $3/$2 * 100.0)}')"
|
||||
echo "Disk Usage: $(df -h | grep '/$' | awk '{print $5}')"
|
||||
|
||||
echo "=== Docker Status ==="
|
||||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
|
||||
|
||||
echo "=== Application Status ==="
|
||||
curl -s http://localhost:5000/health | jq .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
本部署指南涵蓋了大部分常見的部署場景。如果遇到特殊情況或需要客製化部署,請參考系統文檔或聯繫技術支援團隊。
|
Reference in New Issue
Block a user