本指南详细介绍如何将 Flask 应用部署到 CloudBase 云托管服务。
📋 前置要求:如果您还没有创建 Flask 项目,请先阅读 Flask 项目创建指南。
云托管适合以下场景:
- 企业级应用:复杂的 Web 应用和管理系统
- 高并发:需要处理大量并发请求
- 自定义环境:需要特定的运行时环境
- 微服务架构:容器化部署和管理
| 特性 | 说明 |
|---|---|
| 计费方式 | 按资源使用量(CPU/内存) |
| 启动方式 | 持续运行 |
| 端口配置 | 可自定义端口(默认 8080) |
| 扩缩容 | 支持自动扩缩容配置 |
| Python 环境 | 完全自定义 Python 环境 |
创建 Dockerfile 文件:
# 使用官方 Python 运行时作为基础镜像
FROM python:3.11-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 设置 pip 镜像源以提高下载速度
RUN pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple/ \
&& pip config set global.trusted-host mirrors.cloud.tencent.com
# 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8080
# 设置环境变量
ENV PORT=8080
ENV FLASK_ENV=production
ENV PYTHONPATH=/app
# 启动命令
CMD ["python", "app.py"]创建 .dockerignore 文件以优化构建性能:
env/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
.git
.gitignore
README.md
.env
.DS_Store
*.log
.pytest_cache/
.coverage
scf_bootstrap
.vscode/
.idea/
*.db
*.sqlite3
docs/
确保 app.py 支持云托管环境:
import os
from flask import Flask, jsonify, request
# 创建 Flask 应用实例
app = Flask(__name__)
# 配置应用
app.config['DEBUG'] = os.environ.get('DEBUG', 'False').lower() == 'true'
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'your-secret-key-here')
# ... 其他代码保持不变 ...
if __name__ == '__main__':
# 默认端口 8080,HTTP 云函数通过环境变量设置为 9000
port = int(os.environ.get('PORT', 8080))
debug = os.environ.get('FLASK_ENV') == 'development'
app.run(host='0.0.0.0', port=port, debug=debug)确保 requirements.txt 包含所有必要依赖:
Flask==2.3.3
gunicorn>=21.0.0
python-dotenv>=1.0.0cloudrun-flask/
├── app.py # Flask 主应用文件
├── requirements.txt # Python 依赖
├── Dockerfile # 🔑 容器配置文件
├── .dockerignore # Docker 忽略文件
└── .gitignore # Git 忽略文件
💡 说明:
- 云托管支持自定义端口,默认使用 8080 端口
- 使用 Flask 内置开发服务器或 Gunicorn 启动应用
- Docker 容器提供了完整的 Python 环境控制
- 登录 CloudBase 控制台
- 选择您的环境,进入「云托管」页面
- 点击「新建服务」
- 填写服务名称(如:
cloudrun-flask-service) - 选择「本地代码」上传方式
- 上传包含
Dockerfile的项目目录 - 配置服务参数:
- 端口:8080(或您在应用中配置的端口)
- CPU:0.25 核
- 内存:0.5 GB
- 实例数量:1-10(根据需求调整)
- 点击「创建」按钮等待部署完成
# 安装 CloudBase CLI
npm install -g @cloudbase/cli
# 登录
tcb login
# 初始化云托管配置
tcb run init
# 部署云托管服务
tcb run deploy --port 8080创建 cloudbaserc.json 配置文件:
{
"envId": "your-env-id",
"framework": {
"name": "flask",
"plugins": {
"run": {
"name": "@cloudbase/framework-plugin-run",
"options": {
"serviceName": "cloudrun-flask-service",
"servicePath": "/",
"localPath": "./",
"dockerfile": "./Dockerfile",
"buildDir": "./",
"cpu": 0.25,
"mem": 0.5,
"minNum": 1,
"maxNum": 10,
"policyType": "cpu",
"policyThreshold": 60,
"containerPort": 8080,
"envVariables": {
"FLASK_ENV": "production",
"DEBUG": "False"
}
}
}
}
}
}然后执行部署:
tcb framework deploy- 登录 腾讯云托管控制台
- 点击「通过模板部署」,选择 Flask 模板
- 输入自定义服务名称,点击部署
- 等待部署完成后,点击左上角箭头,返回到服务详情页
- 点击概述,获取默认域名并访问
云托管部署成功后,系统会自动分配访问地址。您也可以绑定自定义域名。
访问地址格式:https://your-service-url/
- 根路径:
/- Flask 欢迎页面 - 健康检查:
/health- 查看应用状态 - 用户列表:
/api/users- 获取用户列表 - 用户详情:
/api/users/1- 获取特定用户 - 创建用户:
POST /api/users- 创建新用户 - 更新用户:
PUT /api/users/1- 更新用户信息 - 删除用户:
DELETE /api/users/1- 删除用户
# 健康检查
curl https://your-service-url/health
# 获取用户列表
curl https://your-service-url/api/users
# 分页查询
curl "https://your-service-url/api/users?page=1&limit=2"
# 创建新用户
curl -X POST https://your-service-url/api/users \
-H "Content-Type: application/json" \
-d '{"name":"测试用户","email":"test@example.com"}'A: 云托管支持自定义端口,Flask 应用默认使用 8080 端口,也可以根据需要配置其他端口。
A: 通过环境变量控制应用配置:
# config.py
import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key')
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///app.db')
class ProductionConfig(Config):
DEBUG = False
class DevelopmentConfig(Config):
DEBUG = True
config = {
'production': ProductionConfig,
'development': DevelopmentConfig,
'default': ProductionConfig
}A: 可以通过以下方式配置:
- 控制台服务配置页面
cloudbaserc.json配置文件- Dockerfile 中的 ENV 指令
A: 在云托管环境中,可以配置 Flask 处理静态文件:
@app.route('/static/<path:filename>')
def static_files(filename):
return app.send_static_file(filename)A: 在云托管服务详情页面可以查看:
- 实例日志
- 构建日志
- 访问日志
- 错误日志
# 构建阶段
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 运行阶段
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
# 确保 Python 用户包在 PATH 中
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8080
CMD ["python", "app.py"]# Dockerfile 中使用 Gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "2", "app:app"]# gunicorn.conf.py
bind = "0.0.0.0:8080"
workers = 2
worker_class = "sync"
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 100
timeout = 30
keepalive = 2# config.py
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key')
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
PORT = int(os.getenv('PORT', 8080))
# 数据库配置
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///app.db')
class ProductionConfig(Config):
DEBUG = False
class DevelopmentConfig(Config):
DEBUG = True
config = {
'production': ProductionConfig,
'development': DevelopmentConfig,
'default': ProductionConfig
}# app.py
import sys
import os
from flask import Flask, jsonify
from datetime import datetime
@app.route('/health')
def health_check():
"""增强的健康检查接口"""
return jsonify({
"status": "healthy",
"timestamp": datetime.now().isoformat(),
"framework": "Flask",
"deployment": "云托管",
"version": "2.3.0",
"python_version": sys.version,
"environment": os.environ.get("FLASK_ENV", "production")
})# logging_config.py
import logging
import sys
from flask import request, g
import time
def setup_logging(app):
if not app.debug:
# 生产环境日志配置
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO)
@app.before_request
def before_request():
g.start_time = time.time()
@app.after_request
def after_request(response):
if hasattr(g, 'start_time'):
duration = time.time() - g.start_time
app.logger.info(f'{request.method} {request.path} - {response.status_code} - {duration:.3f}s')
return responsefrom flask_cors import CORS
# 基础 CORS 配置
CORS(app)
# 或者更精确的配置
CORS(app, resources={
r"/api/*": {
"origins": ["https://yourdomain.com"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["Content-Type", "Authorization"]
}
})-
Dockerfile文件存在且配置正确 -
.dockerignore文件配置合理 - 端口配置灵活(支持环境变量)
- 容器启动命令正确
- 排除
env目录(云托管使用 Docker 容器内的 Python 环境) - 排除
scf_bootstrap文件(仅用于云函数) - 本地 Docker 构建测试通过
- Flask 应用配置正确
{
"run": {
"name": "@cloudbase/framework-plugin-run",
"options": {
"serviceName": "cloudrun-flask-service",
"cpu": 1,
"mem": 2,
"minNum": 2,
"maxNum": 20,
"policyType": "cpu",
"policyThreshold": 70,
"containerPort": 8080,
"customLogs": "stdout",
"initialDelaySeconds": 2
}
}
}# database.py
from flask_sqlalchemy import SQLAlchemy
import os
db = SQLAlchemy()
def init_db(app):
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'sqlite:///app.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
with app.app_context():
db.create_all()# cache.py
from flask_caching import Cache
import os
cache = Cache()
def init_cache(app):
cache_config = {
'CACHE_TYPE': 'redis',
'CACHE_REDIS_URL': os.getenv('REDIS_URL', 'redis://localhost:6379/0')
}
app.config.update(cache_config)
cache.init_app(app)# monitoring.py
import time
import logging
from flask import request, g
logger = logging.getLogger(__name__)
def init_monitoring(app):
@app.before_request
def before_request():
g.start_time = time.time()
@app.after_request
def after_request(response):
if hasattr(g, 'start_time'):
duration = time.time() - g.start_time
# 记录慢请求
if duration > 1.0:
logger.warning(f"Slow request: {request.method} {request.path} - {duration:.3f}s")
# 记录错误请求
if response.status_code >= 400:
logger.error(f"Error request: {request.method} {request.path} - {response.status_code}")
return response