部署文檔
概述
Cortex Investment Agent 使用 Docker Compose 進行本地開發和部署。
系統需求: - Docker 20.10+ - Docker Compose 2.0+ - 8GB RAM (建議 16GB) - 20GB 儲存空間
Docker Compose 架構
cortex/
├── docker-compose.yml
├── .env
├── backend/
│ └── Dockerfile
└── streamlit_ui/
└── Dockerfile
docker-compose.yml
version: '3.8'
services:
# PostgreSQL 資料庫
postgres:
image: postgres:15
container_name: cortex-postgres
environment:
POSTGRES_DB: ${DB_NAME:-cortex_investment}
POSTGRES_USER: ${DB_USER:-cortex}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backend/database/init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U cortex"]
interval: 10s
timeout: 5s
retries: 5
networks:
- cortex-network
# Agent API 服務
agent-api:
build:
context: ./backend
dockerfile: Dockerfile
container_name: cortex-api
command: uvicorn api.main:app --host 0.0.0.0 --port 8000 --reload --no-access-log
environment:
- DATABASE_URL=postgresql+asyncpg://${DB_USER:-cortex}:${DB_PASSWORD}@postgres:5432/${DB_NAME:-cortex_investment}
- GOOGLE_API_KEY=${GOOGLE_API_KEY}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
volumes:
- ./backend:/app
- ./core:/app/core
- ./logs:/app/logs
ports:
- "8000:8000"
depends_on:
postgres:
condition: service_healthy
networks:
- cortex-network
restart: unless-stopped
# Stock Data Scheduler 服務
scheduler:
build:
context: ./backend
dockerfile: Dockerfile
container_name: cortex-scheduler
command: python scripts/scheduler.py
environment:
- DATABASE_URL=postgresql+asyncpg://${DB_USER:-cortex}:${DB_PASSWORD}@postgres:5432/${DB_NAME:-cortex_investment}
- TZ=Asia/Taipei
- LOG_LEVEL=${LOG_LEVEL:-INFO}
volumes:
- ./backend:/app
- ./core:/app/core
- ./logs:/app/logs
depends_on:
postgres:
condition: service_healthy
networks:
- cortex-network
restart: unless-stopped
# Streamlit UI
streamlit:
build:
context: ./streamlit_ui
dockerfile: Dockerfile
container_name: cortex-streamlit
command: streamlit run app.py --server.port=8501 --server.address=0.0.0.0
environment:
- API_URL=http://agent-api:8000
volumes:
- ./streamlit_ui:/app
ports:
- "8501:8501"
depends_on:
- agent-api
networks:
- cortex-network
restart: unless-stopped
volumes:
postgres_data:
driver: local
networks:
cortex-network:
driver: bridge
Dockerfile
Backend Dockerfile
檔案: backend/Dockerfile
FROM python:3.11-slim
# 設定工作目錄
WORKDIR /app
# 安裝系統依賴
RUN apt-get update && apt-get install -y \
build-essential \
curl \
&& rm -rf /var/lib/apt/lists/*
# 複製 requirements
COPY requirements.txt .
# 安裝 Python 依賴
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式碼
COPY . .
# 安裝 core (editable mode)
COPY ../core /app/core
RUN pip install -e /app/core
# 建立日誌目錄
RUN mkdir -p /app/logs
# 預設啟動 API
CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000", "--no-access-log"]
Streamlit Dockerfile
檔案: streamlit_ui/Dockerfile
FROM python:3.11-slim
WORKDIR /app
# 安裝依賴
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用
COPY . .
# 暴露端口
EXPOSE 8501
# 啟動 Streamlit
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
環境變數
.env 檔案
# 資料庫設定
DB_NAME=cortex_investment
DB_USER=cortex
DB_PASSWORD=your_secure_password_here
# Google API (Gemini)
GOOGLE_API_KEY=your_google_api_key_here
# 日誌設定
LOG_LEVEL=INFO
# 其他設定
TZ=Asia/Taipei
.env.example (範本)
# 資料庫設定
DB_NAME=cortex_investment
DB_USER=cortex
DB_PASSWORD=CHANGE_ME
# Google API (Gemini)
GOOGLE_API_KEY=CHANGE_ME
# 日誌設定
LOG_LEVEL=INFO
# 時區
TZ=Asia/Taipei
部署步驟
1. 初次部署
# 1. Clone 專案
git clone https://github.com/your-username/cortex.git
cd cortex
# 2. 複製環境變數範本
cp .env.example .env
# 3. 編輯 .env,填入正確的 API key 和密碼
nano .env
# 4. 建立並啟動所有服務
docker-compose up -d
# 5. 查看日誌確認啟動成功
docker-compose logs -f
# 6. 初始化資料庫(第一次)
docker-compose exec agent-api python -m alembic upgrade head
# 7. 觸發初始資料爬取(可選)
docker-compose exec scheduler python scripts/scheduler.py --setup
2. 啟動服務
# 啟動所有服務
docker-compose up -d
# 只啟動特定服務
docker-compose up -d agent-api streamlit
# 查看日誌
docker-compose logs -f agent-api
docker-compose logs -f scheduler
# 查看所有服務狀態
docker-compose ps
3. 停止服務
# 停止所有服務
docker-compose down
# 停止並刪除資料(慎用!)
docker-compose down -v
4. 更新部署
# 1. 拉取最新代碼
git pull origin main
# 2. 重新建立映像
docker-compose build
# 3. 重啟服務
docker-compose up -d
# 4. 執行資料庫遷移(如有)
docker-compose exec agent-api python -m alembic upgrade head
資料庫管理
備份
# 備份資料庫
docker-compose exec postgres pg_dump -U cortex cortex_investment > backup_$(date +%Y%m%d).sql
# 備份到容器內
docker-compose exec postgres pg_dump -U cortex cortex_investment -f /var/lib/postgresql/data/backup.sql
還原
# 從備份還原
docker-compose exec -T postgres psql -U cortex cortex_investment < backup_20250201.sql
資料庫遷移
# 建立新遷移
docker-compose exec agent-api alembic revision --autogenerate -m "Add new table"
# 執行遷移
docker-compose exec agent-api alembic upgrade head
# 回滾遷移
docker-compose exec agent-api alembic downgrade -1
監控與除錯
查看日誌
# 即時日誌
docker-compose logs -f agent-api
# 最後 100 行
docker-compose logs --tail=100 scheduler
# 所有服務
docker-compose logs -f
進入容器
# 進入 API 容器
docker-compose exec agent-api bash
# 進入 PostgreSQL
docker-compose exec postgres psql -U cortex cortex_investment
健康檢查
# API 健康檢查
curl http://localhost:8000/health
# 資料庫連接測試
docker-compose exec postgres pg_isready -U cortex
效能優化
資源配置
docker-compose.yml (添加資源限制):
services:
agent-api:
# ...
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
PostgreSQL 調優
環境變數:
postgres:
environment:
- POSTGRES_SHARED_BUFFERS=256MB
- POSTGRES_EFFECTIVE_CACHE_SIZE=1GB
- POSTGRES_WORK_MEM=16MB
安全性
1. 環境變數保護
# 使用 secrets (Docker Swarm)
# 或 加密 .env 檔案
ansible-vault encrypt .env
2. 網路隔離
# 只暴露必要端口
services:
postgres:
ports:
- "127.0.0.1:5432:5432" # 只允許本地連接
3. 定期更新
# 更新基礎映像
docker-compose pull
docker-compose up -d --build
故障排除
常見問題
1. 資料庫連接失敗
# 檢查 PostgreSQL 是否啟動
docker-compose ps postgres
# 檢查網路
docker-compose exec agent-api ping postgres
# 檢查環境變數
docker-compose exec agent-api env | grep DATABASE_URL
2. API 無法啟動
# 查看詳細日誌
docker-compose logs agent-api
# 檢查端口占用
lsof -i :8000
3. Scheduler 資料更新失敗
# 查看日誌
docker-compose logs scheduler
# 手動執行測試
docker-compose exec scheduler python -c "import yfinance as yf; print(yf.Ticker('AAPL').info)"
生產環境建議
1. 使用反向代理
nginx.conf:
server {
listen 80;
server_name cortex.yourdomain.com;
location / {
proxy_pass http://localhost:8501; # Streamlit
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api {
proxy_pass http://localhost:8000; # FastAPI
}
}
2. HTTPS 設定
# 使用 Let's Encrypt
certbot --nginx -d cortex.yourdomain.com
3. 自動重啟
services:
agent-api:
restart: always
4. 日誌管理
services:
agent-api:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
維護計劃
每日
- 檢查服務狀態
- 查看錯誤日誌
每週
- 備份資料庫
- 檢查磁碟空間
每月
- 更新依賴套件
- 清理舊日誌
文檔版本: 1.0
最後更新: 2025-02-01