690 lines
14 KiB
Markdown
690 lines
14 KiB
Markdown
# 部署指南 - 暫時規範管理系統 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 .
|
||
```
|
||
|
||
---
|
||
|
||
本部署指南涵蓋了大部分常見的部署場景。如果遇到特殊情況或需要客製化部署,請參考系統相關文檔。 |