Python 應用程式部署指南:Flask 與 Django 實戰【2025】

Python 應用程式部署指南:Flask 與 Django 實戰

Python 是 Web 開發的熱門選擇,無論是輕量的 Flask API 還是全功能的 Django 專案,部署到生產環境都有其特殊的注意事項。跟 Node.js 不同,Python Web 應用需要透過 WSGI Server(如 Gunicorn)來處理 HTTP 請求。

這篇教學將帶你了解 Flask 與 Django 的部署差異,從本機開發到雲端上線的完整流程,讓你的 Python 專案順利進入生產環境。

如果你想了解更完整的部署策略,可以先閱讀 程式部署完整指南


Flask vs Django:部署差異

flask-vs-django

插圖:Flask 與 Django 框架比較圖

場景描述:
Technical illustration showing Flask 與 Django 框架比較圖. Clean, professional diagram style.

視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements

必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure

需要顯示的中文字:

風格:
Clean flat design, technical illustration, modern infographic style

顏色調性:
Professional blues and grays, with accent colors for emphasis

避免元素:
Cluttered design, realistic photos, complex 3D rendering

在開始部署之前,先了解這兩個框架的差異,有助於選擇正確的部署策略。

框架特性比較

特性 Flask Django
定位 微框架 全功能框架
學習曲線 中高
內建功能 極少,自由搭配 ORM、Admin、Auth、Forms
適合專案 API、微服務、小型應用 中大型專案、CMS、電商
部署複雜度 較低 較高(需處理靜態檔案、migrations)

部署時的差異

Flask 部署重點
- 結構簡單,通常只需要 app.py + requirements.txt
- 不需要處理靜態檔案收集(除非用 Flask 服務靜態檔)
- 適合 Serverless 環境(Cloud Run、Lambda)

Django 部署重點
- 需要執行 collectstatic 收集靜態檔案
- 需要設定 ALLOWED_HOSTSCSRF_TRUSTED_ORIGINS
- 需要執行資料庫 migrations
- 需要妥善管理 SECRET_KEY
- Admin 後台需要靜態檔案才能正常顯示


WSGI Server:為什麼需要 Gunicorn

wsgi-architecture

插圖:WSGI 架構示意圖

場景描述:
Technical illustration showing WSGI 架構示意圖. Clean, professional diagram style.

視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements

必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure

需要顯示的中文字:

風格:
Clean flat design, technical illustration, modern infographic style

顏色調性:
Professional blues and grays, with accent colors for emphasis

避免元素:
Cluttered design, realistic photos, complex 3D rendering

Python Web 框架(Flask、Django)都實作了 WSGI(Web Server Gateway Interface)介面,但開發用的內建伺服器(如 flask runpython manage.py runserver不適合生產環境

開發伺服器 vs 生產伺服器

項目 開發伺服器 Gunicorn
效能 單執行緒,無法處理並發 多 Worker 並發處理
穩定性 可能 crash 不重啟 Worker crash 自動重啟
安全性 未經加固 生產環境加固
用途 本地開發 生產部署

Gunicorn 基礎使用

安裝 Gunicorn

pip install gunicorn

Flask 應用啟動

# 假設 app.py 中有 app = Flask(__name__)
gunicorn app:app --bind 0.0.0.0:8000

Django 應用啟動

# 假設專案名稱為 myproject
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000

Gunicorn 設定檔

建立 gunicorn.conf.py

# gunicorn.conf.py
import multiprocessing

# 綁定位址
bind = "0.0.0.0:8000"

# Worker 數量(建議:CPU 核心數 * 2 + 1)
workers = multiprocessing.cpu_count() * 2 + 1

# Worker 類型
worker_class = "sync"  # 或 "gevent"、"uvicorn.workers.UvicornWorker"

# 超時設定(秒)
timeout = 30

# 保持連線
keepalive = 2

# 日誌
accesslog = "-"  # stdout
errorlog = "-"   # stderr
loglevel = "info"

# 程序名稱
proc_name = "myapp"

# 優雅重啟
graceful_timeout = 30

# 最大請求數後重啟 Worker(防止記憶體洩漏)
max_requests = 1000
max_requests_jitter = 50

使用設定檔啟動:

gunicorn app:app -c gunicorn.conf.py

Gunicorn Worker 類型

gunicorn-workers

插圖:Gunicorn Worker 模型圖

場景描述:
Technical illustration showing Gunicorn Worker 模型圖. Clean, professional diagram style.

視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements

必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure

需要顯示的中文字:

風格:
Clean flat design, technical illustration, modern infographic style

顏色調性:
Professional blues and grays, with accent colors for emphasis

避免元素:
Cluttered design, realistic photos, complex 3D rendering

Worker 類型 適用場景 安裝方式
sync 一般 CPU 密集型應用 內建
gevent I/O 密集型(大量 DB 查詢) pip install gevent
uvicorn ASGI 應用(FastAPI) pip install uvicorn
# 使用 gevent Worker
gunicorn app:app --worker-class gevent --workers 4

# 使用 uvicorn Worker(FastAPI)
gunicorn main:app --worker-class uvicorn.workers.UvicornWorker --workers 4

Flask 部署實戰

Flask 的部署相對簡單,以下是完整的部署流程。

專案結構

my-flask-app/
├── app.py              # 主應用程式
├── requirements.txt    # 相依套件
├── gunicorn.conf.py    # Gunicorn 設定
├── Procfile            # Heroku/Railway 用
├── Dockerfile          # Docker 部署用
└── .env                # 環境變數(不上傳)

Flask 應用程式範例

# app.py
import os
from flask import Flask, jsonify

app = Flask(__name__)

# 從環境變數讀取設定
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-secret-key')
app.config['DEBUG'] = os.environ.get('FLASK_DEBUG', 'False').lower() == 'true'

@app.route('/')
def home():
    return jsonify({'message': 'Hello from Flask!'})

@app.route('/health')
def health():
    return 'OK', 200

@app.route('/api/users')
def get_users():
    # 實際應用會從資料庫讀取
    return jsonify([
        {'id': 1, 'name': 'Alice'},
        {'id': 2, 'name': 'Bob'}
    ])

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))

requirements.txt

flask==3.0.0
gunicorn==21.2.0
python-dotenv==1.0.0

部署到 Railway

1. 建立 Procfile

web: gunicorn app:app --bind 0.0.0.0:$PORT

2. 連接 GitHub 部署

  1. 前往 railway.app
  2. 新增專案 → Deploy from GitHub
  3. 選擇你的 Repository
  4. Railway 會自動偵測 Python 並部署

3. 設定環境變數

在 Railway Dashboard 的 Variables 區塊新增:

SECRET_KEY=your-production-secret-key
FLASK_DEBUG=False

💡 Flask 部署遇到問題?

從 WSGI 設定到環境變數管理,Flask 生產部署有許多細節需要注意。

預約免費諮詢,讓我們幫你處理 Flask 部署。


Django 部署實戰

django-deployment-checklist

插圖:Django 部署檢查清單

場景描述:
Technical illustration showing Django 部署檢查清單. Clean, professional diagram style.

視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements

必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure

需要顯示的中文字:

風格:
Clean flat design, technical illustration, modern infographic style

顏色調性:
Professional blues and grays, with accent colors for emphasis

避免元素:
Cluttered design, realistic photos, complex 3D rendering

Django 部署比 Flask 複雜,需要處理靜態檔案、資料庫遷移、安全設定等。

Django 部署前檢查清單

在部署 Django 之前,務必完成以下設定:

# settings.py - 生產環境設定

import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# 安全設定
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
SECRET_KEY = os.environ.get('SECRET_KEY')  # 必須從環境變數讀取
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')

# CSRF 設定(Django 4.0+)
CSRF_TRUSTED_ORIGINS = [
    'https://your-domain.com',
    'https://*.railway.app',  # Railway 部署
]

# HTTPS 設定
SECURE_SSL_REDIRECT = not DEBUG
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = not DEBUG
CSRF_COOKIE_SECURE = not DEBUG

# 靜態檔案設定
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

# WhiteNoise 設定(簡化靜態檔案服務)
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # 加在這裡
    # ... 其他 middleware
]

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

# 資料庫設定(以 PostgreSQL 為例)
import dj_database_url

DATABASES = {
    'default': dj_database_url.config(
        default=os.environ.get('DATABASE_URL'),
        conn_max_age=600,
        conn_health_checks=True,
    )
}

requirements.txt

django==5.0
gunicorn==21.2.0
whitenoise==6.6.0
dj-database-url==2.1.0
psycopg2-binary==2.9.9
python-dotenv==1.0.0

專案結構

my-django-app/
├── myproject/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── myapp/
│   ├── models.py
│   ├── views.py
│   └── ...
├── manage.py
├── requirements.txt
├── Procfile
├── Dockerfile
└── staticfiles/        # collectstatic 產生

部署步驟

1. 收集靜態檔案

python manage.py collectstatic --noinput

2. 執行資料庫遷移

python manage.py migrate --noinput

3. 建立 Procfile

web: gunicorn myproject.wsgi:application --bind 0.0.0.0:$PORT
release: python manage.py migrate --noinput

release 命令會在每次部署時自動執行資料庫遷移。

部署到 Railway

1. 連接 GitHub 部署

與 Flask 相同,Railway 會自動偵測 Django 專案。

2. 新增 PostgreSQL 資料庫

在 Railway Dashboard 點擊「+ New」→「Database」→「PostgreSQL」

Railway 會自動注入 DATABASE_URL 環境變數。

3. 設定環境變數

SECRET_KEY=your-very-long-random-secret-key
DEBUG=False
ALLOWED_HOSTS=your-app.railway.app,your-domain.com

4. 手動執行 collectstatic(首次部署)

如果靜態檔案有問題,可以在 Railway 的 shell 執行:

python manage.py collectstatic --noinput

💡 Django 靜態檔案設定卡關?

WhiteNoise、collectstatic、Nginx 設定讓人頭痛?

預約免費諮詢,讓專家幫你解決 Django 部署問題。


Docker 容器化部署

使用 Docker 可以確保開發與生產環境一致,並方便部署到各種雲端平台。

Flask Dockerfile

FROM python:3.12-slim

# 設定環境變數
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /app

# 安裝相依套件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 複製應用程式
COPY . .

# 建立非 root 使用者
RUN adduser --disabled-password --gecos '' appuser
USER appuser

# 開放 port
EXPOSE 8000

# 啟動命令
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000", "--workers", "4"]

Django Dockerfile

FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /app

# 安裝系統相依(PostgreSQL 需要)
RUN apt-get update && apt-get install -y \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

# 安裝 Python 相依套件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 複製應用程式
COPY . .

# 收集靜態檔案
RUN python manage.py collectstatic --noinput

# 建立非 root 使用者
RUN adduser --disabled-password --gecos '' appuser
RUN chown -R appuser:appuser /app
USER appuser

EXPOSE 8000

CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]

docker-compose.yml(本地開發)

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DEBUG=True
      - SECRET_KEY=dev-secret-key
      - DATABASE_URL=postgres://postgres:postgres@db:5432/myapp
    depends_on:
      - db
    volumes:
      - .:/app  # 開發時同步程式碼

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

部署到 Cloud Run

# 建置並推送到 Google Container Registry
gcloud builds submit --tag gcr.io/PROJECT_ID/my-python-app

# 部署到 Cloud Run
gcloud run deploy my-python-app \
  --image gcr.io/PROJECT_ID/my-python-app \
  --platform managed \
  --region asia-east1 \
  --allow-unauthenticated \
  --set-env-vars "SECRET_KEY=xxx,DEBUG=False"

想了解更多 Docker 部署細節,請參考 Docker Deploy 教學


雲端平台比較

python-cloud-platforms

插圖:Python 雲端部署平台比較

場景描述:
Technical illustration showing Python 雲端部署平台比較. Clean, professional diagram style.

視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements

必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure

需要顯示的中文字:

風格:
Clean flat design, technical illustration, modern infographic style

顏色調性:
Professional blues and grays, with accent colors for emphasis

避免元素:
Cluttered design, realistic photos, complex 3D rendering

根據專案需求選擇合適的雲端平台:

平台 適合框架 難度 費用 特點
Railway Flask/Django $5/月起 最簡單,自動偵測
Render Flask/Django 免費起 Heroku 替代品
Cloud Run Flask ⭐⭐ 按用量 Serverless,自動擴展
Elastic Beanstalk Django ⭐⭐⭐ 依 EC2 AWS 整合,適合企業
DigitalOcean App Platform Flask/Django ⭐⭐ $5/月起 簡單且價格透明

推薦選擇

  • Flask API / 微服務 → Railway 或 Cloud Run
  • Django 全功能專案 → Railway 或 Render
  • 企業級 / AWS 生態系 → Elastic Beanstalk
  • 預算有限 → Render(有免費方案)

生產環境最佳實踐

1. 環境變數管理

永遠不要在程式碼中寫死敏感資訊:

# 錯誤
SECRET_KEY = 'my-secret-key'

# 正確
SECRET_KEY = os.environ.get('SECRET_KEY')
if not SECRET_KEY:
    raise ValueError("SECRET_KEY environment variable is required")

2. 日誌設定

# settings.py (Django) 或 app.py (Flask)
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Django 日誌設定
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO',
    },
}

3. 健康檢查端點

# Flask
@app.route('/health')
def health():
    # 可以加入資料庫連線檢查
    return {'status': 'healthy'}, 200

# Django (urls.py)
from django.http import JsonResponse

def health_check(request):
    return JsonResponse({'status': 'healthy'})

urlpatterns = [
    path('health/', health_check),
    # ...
]

4. 資料庫連線池

# Django with dj-database-url
DATABASES = {
    'default': dj_database_url.config(
        conn_max_age=600,        # 連線保持 10 分鐘
        conn_health_checks=True, # 使用前檢查連線有效性
    )
}

FAQ 常見問題

Q1: 為什麼不能用 flask run 上線?

flask run 是開發伺服器,單執行緒且未經安全加固。生產環境必須使用 Gunicorn、uWSGI 等 WSGI Server。

Q2: Django 的 SECRET_KEY 怎麼產生?

# 執行這段程式碼產生隨機 key
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())

或使用命令列:

python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

Q3: collectstatic 是什麼?為什麼需要?

Django 的靜態檔案(CSS、JS、圖片)分散在各個 app 中。collectstatic 會將所有靜態檔案收集到 STATIC_ROOT 目錄,方便 Nginx 或 WhiteNoise 統一服務。

Q4: Gunicorn Worker 數量怎麼設?

經驗法則:(2 × CPU 核心數) + 1

例如 2 核心 CPU → 5 個 Workers

但這只是起點,實際要根據應用特性(CPU 密集 or I/O 密集)調整。

Q5: 如何處理資料庫 migrations?

建議在部署流程中自動執行:

# Procfile
release: python manage.py migrate --noinput

或在 CI/CD Pipeline 中執行。


Python 部署重點整理與框架選擇建議

這篇教學涵蓋了 Python Web 應用的完整部署流程:

  • 框架差異:Flask(輕量簡單)vs Django(全功能但需更多設定)
  • WSGI Server:為什麼需要 Gunicorn,以及如何設定
  • Flask 部署:簡單的 Procfile + Railway 即可上線
  • Django 部署:collectstatic、ALLOWED_HOSTS、資料庫遷移
  • Docker 容器化:確保環境一致,可部署到任何平台
  • 平台選擇:Railway、Cloud Run、Elastic Beanstalk 各有優劣

無論你選擇哪種方式,記得做好環境變數管理、日誌設定、健康檢查,這些是生產環境的基本功。

如果你想了解其他語言的部署方式,可以接著閱讀 Node.js 部署教學Java 部署教學


🐍 Python 部署需要協助?

從 Gunicorn 調校到 Django 安全設定,Python 生產部署有許多眉角。

預約免費諮詢,讓 VibeFix 的工程師幫你把 Python 專案順利上線!

分享文章:
V

VibeFix

專門解決 AI Vibe Coding 後的疑難雜症,讓你的專案順利上線。

這篇文章有幫到你嗎?

如果還有問題,讓我們直接幫你解決!

聯繫我們