最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask常見應(yīng)用部署方案詳解

 更新時(shí)間:2026年02月15日 15:04:05   作者:花酒鋤作田  
這篇文章主要介紹了Flask常見應(yīng)用部署方案詳解的相關(guān)資料,需要的朋友可以參考下

前言

開發(fā)調(diào)試階段,運(yùn)行 Flask 的方式多直接使用 app.run(),但 Flask 內(nèi)置的 WSGI Server 的性能并不高。對(duì)于生產(chǎn)環(huán)境,一般使用 gunicorn。如果老項(xiàng)目并不需要多高的性能,而且用了很多單進(jìn)程內(nèi)的共享變量,使用 gunicorn 會(huì)影響不同會(huì)話間的通信,那么也可以試試直接用 gevent。

在 Docker 流行之前,生產(chǎn)環(huán)境部署 Flask 項(xiàng)目多使用 virtualenv + gunicorn + supervisor。Docker 流行之后,部署方式就換成了 gunicorn + Docker。如果沒有容器編排服務(wù),后端服務(wù)前面一般還會(huì)有個(gè) nginx 做代理。如果使用 Kubernetes,一般會(huì)使用 service + ingress(或 istio 等)。

運(yùn)行方式

Flask 內(nèi)置 WSGI Server

開發(fā)階段一般使用這種運(yùn)行方式。

# main.py
from flask import Flask
from time import sleep

app = Flask(__name__)

@app.get("/test")
def get_test():
    sleep(0.1)
    return "ok"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=10000)

運(yùn)行:

python main.py

gevent

使用 gevent 運(yùn)行 Flask,需要先安裝 gevent

python -m pip install -U gevent

代碼需要稍作修改。

需要注意 monkey.patch_all() 一定要寫在入口代碼文件的最開頭部分,這樣 monkey patch 才能生效。

# main.py
from gevent import monkey
monkey.patch_all()
import time

from flask import Flask
from gevent.pywsgi import WSGIServer


app = Flask(__name__)


@app.get("/test")
def get_test():
    time.sleep(0.1)
    return "ok"


if __name__ == "__main__":
    server = WSGIServer(("0.0.0.0", 10000), app)
    server.serve_forever()

運(yùn)行

python main.py

gunicorn + gevent

如果現(xiàn)有項(xiàng)目大量使用單進(jìn)程內(nèi)的內(nèi)存級(jí)共享變量,貿(mào)然使用 gunicorn 多 worker 模式可能會(huì)導(dǎo)致數(shù)據(jù)訪問不一致的問題。

同樣需要先安裝依賴。

python -m pip install -U gunicorn gevent

不同于單獨(dú)使用 gevent,這種方式不需要修改代碼,gunicorn 會(huì)自動(dòng)注入 gevent 的 monkey patch。

gunicorn 可以在命令行配置啟動(dòng)參數(shù),但個(gè)人一般習(xí)慣在 gunicorn 的配置文件內(nèi)配置啟動(dòng)參數(shù),這樣可以動(dòng)態(tài)設(shè)置一些配置,而且可以修改日志格式。

gunicorn.conf.py 的配置示例如下:

# Gunicorn 配置文件
from pathlib import Path
from multiprocessing import cpu_count
import gunicorn.glogging
from datetime import datetime

class CustomLogger(gunicorn.glogging.Logger):
    def atoms(self, resp, req, environ, request_time):
        """
        重寫 atoms 方法來自定義日志占位符
        """
        # 獲取默認(rèn)的所有占位符數(shù)據(jù)
        atoms = super().atoms(resp, req, environ, request_time)
        
        # 自定義 't' (時(shí)間戳) 的格式
        now = datetime.now().astimezone()
        atoms['t'] = now.isoformat(timespec="seconds")
        
        return atoms
    

# 預(yù)加載應(yīng)用代碼
preload_app = True

# 工作進(jìn)程數(shù)量:通常是 CPU 核心數(shù)的 2 倍加 1
# workers = int(cpu_count() * 2 + 1)
workers = 4

# 使用 gevent 異步 worker 類型,適合 I/O 密集型應(yīng)用
# 注意:gevent worker 不使用 threads 參數(shù),而是使用協(xié)程進(jìn)行并發(fā)處理
worker_class = "gevent"

# 每個(gè) gevent worker 可處理的最大并發(fā)連接數(shù)
worker_connections = 2000

# 綁定地址和端口
bind = "127.0.0.1:10001"

# 進(jìn)程名稱
proc_name = "flask-dev"

# PID 文件路徑
pidfile = str(Path(__file__).parent / "tmp" / "gunicorn.pid")

logger_class = CustomLogger
access_log_format = (
    '{"@timestamp": "%(t)s", '
    '"remote_addr": "%(h)s", '
    '"protocol": "%(H)s", '
    '"host": "%({host}i)s", '
    '"request_method": "%(m)s", '
    '"request_path": "%(U)s", '
    '"status_code": %(s)s, '
    '"response_length": %(b)s, '
    '"referer": "%(f)s", '
    '"user_agent": "%(a)s", '
    '"x_tracking_id": "%({x-tracking-id}i)s", '
    '"request_time": %(L)s}'
)

# 訪問日志路徑
accesslog = str(Path(__file__).parent / "logs" / "access.log")

# 錯(cuò)誤日志路徑
errorlog = str(Path(__file__).parent / "logs" / "error.log")

# 日志級(jí)別
loglevel = "debug"

運(yùn)行。gunicorn 的默認(rèn)配置文件名就是 gunicorn.conf.py,如果文件名不同,可以使用 -c 參數(shù)來指定。

gunicorn main:app

傳統(tǒng)進(jìn)程管理:實(shí)現(xiàn)自動(dòng)啟動(dòng)

在傳統(tǒng)服務(wù)器部署時(shí),常見的進(jìn)程守護(hù)方式有:

  • 配置 crontab + shell 腳本。定時(shí)檢查進(jìn)程在不在,不在就啟動(dòng)。
  • 配置 supervisor。
  • 配置 systemd。

由于 supervisor 需要單獨(dú)安裝,而本著能用自帶工具就用自帶工具、能少裝就少裝的原則,個(gè)人一般不會(huì)使用 supervisor,因此本文不會(huì)涉及如何使用 supervisor。

在服務(wù)器部署時(shí),一般也會(huì)為項(xiàng)目單獨(dú)創(chuàng)建 Python 虛擬環(huán)境。

# 使用 Python 內(nèi)置的 venv,在當(dāng)前目錄創(chuàng)建 Python 虛擬環(huán)境目錄 .venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r ./requirements.txt

# 如果使用uv, 直接uv sync 即可

crontab + shell 腳本 (不推薦生產(chǎn)環(huán)境)

剛?cè)胄械臅r(shí)候?qū)?systemd 不熟悉,經(jīng)常用 crontab + shell 腳本來守護(hù)進(jìn)程,現(xiàn)在想想這種方式并不合適,比較考驗(yàn) shell 腳本的編寫水平,需要考慮方方面面

  • 首先要確保用戶級(jí) crontab 啟用,有些生產(chǎn)環(huán)境會(huì)禁用用戶級(jí)的 crontab,而且也不允許隨便配置系統(tǒng)級(jí)的 crontab。
  • crontab 是分鐘級(jí)的,服務(wù)停止時(shí)間可能要一分鐘。
  • 如果有控制臺(tái)日志,需要手動(dòng)處理日志重定向,還有日志文件輪轉(zhuǎn)問題。
  • 如果 ulimit 不高,還得控制 ulimit。
  • 經(jīng)常出現(xiàn)僵尸進(jìn)程,shell 腳本來要寫一堆狀態(tài)檢查的邏輯。

如果只需要簡(jiǎn)單用用,也可以提供個(gè)示例

#!/bin/bash

# 環(huán)境配置
export FLASK_ENV="production"
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
export REDIS_URL="redis://localhost:6379/0"

script_dir=$(cd $(dirname $0) && pwd)
app_name="gunicorn"  # 實(shí)際進(jìn)程名是 gunicorn,不是 Flask app
wsgi_module="wsgi:app"  # 替換 WSGI 入口
socket_path="${script_dir}/myapp.sock"  # Unix Socket 路徑(避免 /run 重啟丟失)
log_file="${script_dir}/app.log"
pid_file="${script_dir}/gunicorn.pid"   # 用 PID 文件控制

# 進(jìn)程檢測(cè)
is_running() {
    if [ -f "$pid_file" ]; then
        pid=$(cat "$pid_file")
        if ps -p "$pid" > /dev/null 2>&1 && grep -q "gunicorn.*${wsgi_module}" /proc/"$pid"/cmdline 2>/dev/null; then
            echo "Gunicorn (PID: $pid) is running"
            return 0
        else
            rm -f "$pid_file"  # 清理失效 PID
            echo "Stale PID file found, cleaned up"
            return 1
        fi
    else
        # 備用檢測(cè):通過 socket 文件 + 進(jìn)程名
        if [ -S "$socket_path" ] && pgrep -f "gunicorn.*${wsgi_module}" > /dev/null 2>&1; then
            echo "Gunicorn is running (detected by socket)"
            return 0
        fi
        echo "Gunicorn is not running"
        return 1
    fi
}

# 啟動(dòng)應(yīng)用
start_app() {
    is_running
    if [ $? -eq 0 ]; then
        echo "Already running, skip start"
        return 0
    fi

    echo "Starting Gunicorn at $(date)"
    echo "Socket: $socket_path"
    echo "Log: $log_file"

    # 確保 socket 目錄存在
    mkdir -p "$(dirname "$socket_path")"

    # 啟動(dòng)命令(關(guān)鍵:不加 --daemon,用 nohup 托管)
    cd "$script_dir" || exit 1
    # 生成 PID 文件
    nohup "$script_dir/venv/bin/gunicorn" \
        --workers 3 \
        --bind "unix:$socket_path" \
        --pid "$pid_file" \
        --access-logfile "$log_file" \
        --error-logfile "$log_file" \
        --log-level info \
        "$wsgi_module" > /dev/null 2>&1 &

    # 等待啟動(dòng)完成
    sleep 2
    if is_running; then
        echo "? Start success (PID: $(cat "$pid_file" 2>/dev/null))"
        return 0
    else
        echo "? Start failed, check $log_file"
        return 1
    fi
}

# 停止應(yīng)用
stop_app() {
    is_running
    if [ $? -eq 1 ]; then
        echo "Not running, skip stop"
        return 0
    fi

    pid=$(cat "$pid_file" 2>/dev/null)
    echo "Stopping Gunicorn (PID: $pid) gracefully..."

    # 先發(fā) SIGTERM(優(yōu)雅停止)
    kill -15 "$pid" 2>/dev/null || true
    sleep 5

    # 檢查是否還在運(yùn)行
    if ps -p "$pid" > /dev/null 2>&1; then
        echo "Still running after 5s, force killing..."
        kill -9 "$pid" 2>/dev/null || true
        sleep 2
    fi

    # 清理殘留
    rm -f "$pid_file" "$socket_path"
    echo "? Stopped"
}

# 重啟應(yīng)用
restart_app() {
    echo "Restarting Gunicorn..."
    stop_app
    sleep 1
    start_app
}

# 入口函數(shù)
main() {
    # 檢查 Gunicorn 是否存在
    if [ ! -f "$script_dir/venv/bin/gunicorn" ]; then
        echo "ERROR: Gunicorn not found at $script_dir/venv/bin/gunicorn"
        echo "Hint: Did you activate virtualenv? (source venv/bin/activate)"
        exit 1
    fi

    local action=${1:-start}  # 默認(rèn)動(dòng)作:start

    case "$action" in
        start)
            start_app
            ;;
        stop)
            stop_app
            ;;
        restart)
            restart_app
            ;;
        status)
            is_running
            ;;
        cron-check)
            # 專為 crontab 設(shè)計(jì):只檢查+重啟,不輸出干擾日志
            if ! is_running > /dev/null 2>&1; then
                echo "[$(date '+%F %T')] CRON: Gunicorn down, auto-restarting..." >> "$log_file"
                start_app >> "$log_file" 2>&1
            fi
            ;;
        *)
            echo "Usage: $0 {start|stop|restart|status|cron-check}"
            echo "  cron-check: Silent mode for crontab (logs to app.log only)"
            exit 1
            ;;
    esac
}

main "$@"

手動(dòng)運(yùn)行測(cè)試

bash app_ctl.sh start

配置 crontab

# 編輯當(dāng)前用戶 crontab
crontab -e

# 添加以下行(每分鐘檢查一次)
* * * * * /opt/myflaskapp/app_ctl.sh cron-check >/dev/null 2>&1

配置logrotate

# /etc/logrotate.d/myflaskapp
/opt/myflaskapp/app.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    copytruncate  # 避免 Gunicorn 丟失文件句柄
}

systemd (推薦生產(chǎn)環(huán)境使用)

  • 創(chuàng)建 systemd 服務(wù)文件
sudo vim /etc/systemd/system/myflaskapp.service
  • 示例如下
[Unit]
Description=Gunicorn instance for Flask App
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/your/app
Environment="PATH=/path/to/venv/bin"
ExecStart=/path/to/venv/bin/gunicorn \
          --workers 4 \
          --bind unix:/run/myapp.sock \
          --access-logfile - \
          --error-logfile - \
          wsgi:app

# 禁止添加 --daemon!systemd 需直接監(jiān)控主進(jìn)程
Restart=on-failure        # 僅異常退出時(shí)重啟(非0狀態(tài)碼、被信號(hào)殺死等)
RestartSec=5s             # 重啟前等待5秒
StartLimitInterval=60s    # 60秒內(nèi)
StartLimitBurst=5         # 最多重啟5次,防雪崩
TimeoutStopSec=30         # 停止時(shí)等待30秒(優(yōu)雅關(guān)閉)

# 安全加固
PrivateTmp=true
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/run /var/log/myapp

[Install]
WantedBy=multi-user.target
  • 設(shè)置開機(jī)自啟并啟動(dòng)服務(wù)
sudo systemctl daemon-reload
sudo systemctl enable myflaskapp    # 開機(jī)自啟
sudo systemctl start myflaskapp

可以試試用kill -9停止后端服務(wù)進(jìn)程,觀察能否被重新拉起。

注意,kill -15算是正常停止,不算異常退出。

Docker 部署方案

  • Dockerfile。Python 項(xiàng)目通常不需要多階段構(gòu)建,單階段即可。
FROM python:3.11-slim-bookworm

# 安全加固
## 創(chuàng)建非 root 用戶(避免使用 nobody,權(quán)限太受限)
RUN useradd -m -u 1000 appuser && \
    # 安裝運(yùn)行時(shí)必需的系統(tǒng)庫(kù)(非編譯工具)
    apt-get update && apt-get install -y --no-install-recommends \
        libgomp1 \
        libpq5 \
        libsqlite3-0 \
        && rm -rf /var/lib/apt/lists/* \
        && apt-get autoremove -y \
        && apt-get clean

# Python 優(yōu)化
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1

WORKDIR /app

# 利用 Docker 層緩存:先復(fù)制 requirements
COPY requirements.txt .
RUN pip install --no-cache-dir --prefer-binary -r requirements.txt \
    # 清理 pip 緩存(雖然 --no-cache-dir 已禁用,但保險(xiǎn)起見)
    && rm -rf /root/.cache

# 應(yīng)用代碼
COPY --chown=appuser:appuser . .

# 使用非root用戶運(yùn)行
USER appuser

# 啟動(dòng)
EXPOSE 8000
CMD ["gunicorn", "--config", "config/gunicorn.conf.py", "wsgi:app"]
  • 編寫 docker-compose.yaml
services:
  web:
    image: myflaskapp:latest
    container_name: flask_web
    # 端口映射
    ## 如果 nginx 也使用 Docker 部署,而且使用同一個(gè)網(wǎng)絡(luò)配置,則可以不做端口映射
    ports:
      - "8000:8000"
    # 環(huán)境變量
    environment:
      - FLASK_ENV=production
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
      - REDIS_URL=redis://redis:6379/0
    # 健康檢查
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s      # 每 30 秒檢查一次
      timeout: 5s        # 超時(shí) 5 秒
      start_period: 15s  # 啟動(dòng)后 15 秒開始檢查(給應(yīng)用初始化時(shí)間)
      retries: 3         # 失敗重試 3 次后標(biāo)記 unhealthy
    
    # 自動(dòng)重啟策略
    restart: unless-stopped  # always / on-failure / unless-stopped
    
    # 資源限制
    deploy:
      resources:
        limits:
          cpus: '2'        # 最多 2 個(gè) CPU
          memory: 1G       # 最多 1GB 內(nèi)存
        reservations:
          cpus: '0.5'      # 保留 0.5 個(gè) CPU
          memory: 256M     # 保留 256MB 內(nèi)存
    
    # ulimit 限制(防資源濫用)
    ulimits:
      nproc: 65535       # 最大進(jìn)程數(shù)
      nofile:
        soft: 65535      # 打開文件數(shù)軟限制
        hard: 65535      # 打開文件數(shù)硬限制
      core: 0            # 禁止 core dump
    
    # 安全加固
    security_opt:
      - no-new-privileges:true  # 禁止提權(quán)
    
    # 只讀文件系統(tǒng)(除 /tmp 外)
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=100m
    
    # 卷掛載(日志、臨時(shí)文件)
    volumes:
      - ./logs:/app/logs:rw
      # - ./static:/app/static:ro  # 靜態(tài)文件(可選)
    
    # 網(wǎng)絡(luò)
    networks:
      - app-network
        
# 網(wǎng)絡(luò)配置
networks:
  app-network:
    driver: bridge

# 卷配置
volumes:
  db_data:
    driver: local
  redis_data:
    driver: local

Kubernetes 部署方案

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-app
  namespace: default
  labels:
    app: flask-app
    tier: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        app: flask-app
        tier: backend
    spec:
      securityContext:
        runAsNonRoot: true      # 禁止 root 運(yùn)行
        runAsUser: 1000         # 使用非 root 用戶
        runAsGroup: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault  # 啟用 seccomp 安全策略
      containers:
      - name: flask-app
        image: myregistry.com/myflaskapp:1.0.0
        imagePullPolicy: IfNotPresent  # 生產(chǎn)環(huán)境建議用 Always
        ports:
        - name: http
          containerPort: 8000
          protocol: TCP
        env:
        - name: FLASK_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: flask-app-secrets
              key: database-url
        - name: REDIS_URL
          valueFrom:
            secretKeyRef:
              name: flask-app-secrets
              key: redis-url
        - name: SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: flask-app-secrets
              key: secret-key
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"   # 超過會(huì) OOM Kill
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
            scheme: HTTP
          initialDelaySeconds: 30  # 啟動(dòng)后 30 秒開始檢查
          periodSeconds: 10        # 每 10 秒檢查一次
          timeoutSeconds: 3        # 超時(shí) 3 秒
          successThreshold: 1
          failureThreshold: 3      # 失敗 3 次后重啟容器
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
            scheme: HTTP
          initialDelaySeconds: 10  # 啟動(dòng)后 10 秒開始檢查
          periodSeconds: 5         # 每 5 秒檢查一次
          timeoutSeconds: 2
          successThreshold: 1
          failureThreshold: 3      # 失敗 3 次后從 Service 移除
        startupProbe:
          httpGet:
            path: /health
            port: 8000
            scheme: HTTP
          failureThreshold: 30     # 最多重試 30 次
          periodSeconds: 5         # 每 5 秒一次,共 150 秒容忍慢啟動(dòng)
          timeoutSeconds: 3
        securityContext:
          allowPrivilegeEscalation: false  # 禁止提權(quán)
          readOnlyRootFilesystem: true     # 根文件系統(tǒng)只讀
          capabilities:
            drop:
            - ALL                          # 刪除所有 Linux capabilities
          privileged: false
        volumeMounts:
        - name: tmp-volume
          mountPath: /tmp
        - name: config-volume
          mountPath: /app/config
          readOnly: true
      imagePullSecrets:
      - name: registry-secret  # 如果使用私有鏡像倉(cāng)庫(kù)
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - flask-app
              topologyKey: kubernetes.io/hostname  # 避免所有 Pod 調(diào)度到同一節(jié)點(diǎn)
      volumes:
      - name: tmp-volume
        emptyDir:
          medium: Memory  # 使用內(nèi)存卷,更快
          sizeLimit: 100Mi
      - name: config-volume
        configMap:
          name: flask-app-config

Service

apiVersion: v1
kind: Service
metadata:
  name: flask-app-service
  namespace: default
  labels:
    app: flask-app
    tier: backend
spec:
  type: ClusterIP
  selector:
    app: flask-app
  ports:
  - name: http
    port: 80        # Service 端口
    targetPort: 8000  # Pod 端口
    protocol: TCP

ingress-nginx

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: flask-app-ingress
  namespace: default
  annotations:
    # ==================== Nginx 配置 ====================
    kubernetes.io/ingress.class: "nginx"
    
    # 啟用 HTTPS 重定向
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    
    # 限流(每秒 10 個(gè)請(qǐng)求,突發(fā) 20)
    nginx.ingress.kubernetes.io/limit-rps: "10"
    nginx.ingress.kubernetes.io/limit-burst-multiplier: "2"
    
    # 客戶端真實(shí) IP
    nginx.ingress.kubernetes.io/enable-real-ip: "true"
    nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "0.0.0.0/0"
    
    # 連接超時(shí)
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    
    # 緩沖區(qū)大小
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
    nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
    
    # Gzip 壓縮
    nginx.ingress.kubernetes.io/enable-gzip: "true"
    nginx.ingress.kubernetes.io/gzip-level: "6"
    nginx.ingress.kubernetes.io/gzip-min-length: "1024"
    nginx.ingress.kubernetes.io/gzip-types: "text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript"
    
    # 安全頭
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-XSS-Protection "1; mode=block" always;
      add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # 認(rèn)證
    # nginx.ingress.kubernetes.io/auth-type: basic
    # nginx.ingress.kubernetes.io/auth-secret: flask-app-basic-auth
    # nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
    
    # 自定義錯(cuò)誤頁(yè)面
    # nginx.ingress.kubernetes.io/custom-http-errors: "404,500,502,503,504"
    # nginx.ingress.kubernetes.io/default-backend: custom-error-pages
    
    # 重寫目標(biāo)
    # nginx.ingress.kubernetes.io/rewrite-target: /$1
    
    # WAF(如果安裝了 ModSecurity)
    # nginx.ingress.kubernetes.io/enable-modsecurity: "true"
    # nginx.ingress.kubernetes.io/modsecurity-snippet: |
    #   SecRuleEngine On
    #   SecRequestBodyAccess On

spec:
  tls:
  - hosts:
    - flask.example.com
    secretName: flask-app-tls-secret  # TLS 證書 Secret

  rules:
  - host: flask.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: flask-app-service
            port:
              number: 80

到此這篇關(guān)于Flask常見應(yīng)用部署方案詳解的文章就介紹到這了,更多相關(guān)Flask常見應(yīng)用部署方案內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python基礎(chǔ)教程之csv文件的寫入與讀取

    python基礎(chǔ)教程之csv文件的寫入與讀取

    CSV即逗號(hào)分隔值(也稱字符分隔值,因?yàn)榉指舴梢圆皇嵌禾?hào)),是一種常用的文本格式,用以存儲(chǔ)表格數(shù)據(jù),包括數(shù)字或者字符,下面這篇文章主要給大家介紹了關(guān)于python基礎(chǔ)教程之csv文件的寫入與讀取的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • 一篇文章帶你了解python標(biāo)準(zhǔn)庫(kù)--math模塊

    一篇文章帶你了解python標(biāo)準(zhǔn)庫(kù)--math模塊

    這篇文章主要介紹了Python的math模塊中的常用數(shù)學(xué)函數(shù)整理,同時(shí)對(duì)運(yùn)算符的運(yùn)算優(yōu)先級(jí)作了一個(gè)羅列,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • 使用Python提取PDF文件中內(nèi)容的代碼示例和使用技巧

    使用Python提取PDF文件中內(nèi)容的代碼示例和使用技巧

    在文檔自動(dòng)化處理、數(shù)據(jù)提取和信息分析等任務(wù)中,從 PDF 文件中提取文本是一項(xiàng)常見需求,PDF 文件通常分為兩種類型:基于文本的 PDF 和 包含掃描圖像的 PDF,本文將介紹如何使用 Python 分別提取這兩種類型的 PDF 內(nèi)容,需要的朋友可以參考下
    2025-07-07
  • Python PyTorch實(shí)現(xiàn)Timer計(jì)時(shí)器

    Python PyTorch實(shí)現(xiàn)Timer計(jì)時(shí)器

    這篇文章主要為大家詳細(xì)介紹了Python PyTorch如何實(shí)現(xiàn)簡(jiǎn)單的Timer計(jì)時(shí)器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • Python利用selenium建立代理ip池訪問網(wǎng)站的全過程

    Python利用selenium建立代理ip池訪問網(wǎng)站的全過程

    selenium控制瀏覽器也是可以使用代理ip的,下面這篇文章主要給大家介紹了關(guān)于Python利用selenium建立代理ip池訪問網(wǎng)站的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Python使用Seaborn快速生成高顏值業(yè)務(wù)圖表

    Python使用Seaborn快速生成高顏值業(yè)務(wù)圖表

    本文介紹了Python數(shù)據(jù)可視化庫(kù)Seaborn的核心功能與應(yīng)用場(chǎng)景,掌握Seaborn與Matplotlib的關(guān)系,學(xué)習(xí)使用Seaborn美化圖表繪制各類分布圖、分類圖、回歸圖和配對(duì)圖,提升數(shù)據(jù)可視化能力,需要的朋友可以參考下
    2026-06-06
  • 關(guān)于pip的安裝,更新,卸載模塊以及使用方法(詳解)

    關(guān)于pip的安裝,更新,卸載模塊以及使用方法(詳解)

    下面小編就為大家?guī)硪黄P(guān)于pip的安裝,更新,卸載模塊以及使用方法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • Python與MySQL實(shí)現(xiàn)數(shù)據(jù)庫(kù)實(shí)時(shí)同步的詳細(xì)步驟

    Python與MySQL實(shí)現(xiàn)數(shù)據(jù)庫(kù)實(shí)時(shí)同步的詳細(xì)步驟

    在日常開發(fā)中,數(shù)據(jù)同步是一項(xiàng)常見的需求,本篇文章將使用 Python 和 MySQL 來實(shí)現(xiàn)數(shù)據(jù)庫(kù)實(shí)時(shí)同步,我們將圍繞數(shù)據(jù)變更捕獲、數(shù)據(jù)處理 和 數(shù)據(jù)寫入 這三個(gè)核心環(huán)節(jié)展開,提供易于理解的代碼實(shí)現(xiàn)和實(shí)用方案,需要的朋友可以參考下
    2025-08-08
  • Django如何實(shí)現(xiàn)RBAC權(quán)限管理

    Django如何實(shí)現(xiàn)RBAC權(quán)限管理

    這篇文章主要介紹了Django如何實(shí)現(xiàn)RBAC權(quán)限管理問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Python基礎(chǔ)之python循環(huán)控制語句break/continue詳解

    Python基礎(chǔ)之python循環(huán)控制語句break/continue詳解

    Python中提供了兩個(gè)關(guān)鍵字用來控制循環(huán)語句,分別是break和continue,接下來通過兩個(gè)案例來區(qū)分這兩個(gè)控制語句的不同,感興趣的朋友一起看看吧
    2021-09-09

最新評(píng)論

大洼县| 寿宁县| 亚东县| 通海县| 大田县| 比如县| 松潘县| 双辽市| 潍坊市| 黄山市| 永福县| 夏邑县| 宁化县| 新源县| 婺源县| 鲁山县| 望谟县| 华坪县| 屏边| 南漳县| 津市市| 铜陵市| 晋江市| 南漳县| 南澳县| 达日县| 苍溪县| 淄博市| 平邑县| 周口市| 固始县| 定南县| 牡丹江市| 麟游县| 邵东县| 城市| 盐源县| 天长市| 南陵县| 建水县| 长垣县|