
如果你最近在关注 Python 全栈开发圈的动态大概率已经听过Madeira这个名字。它是 FastAPI 作者 Sebastián Ramírez 在 2024 年把原来的 full-stack-fastapi-template 重整后推出的全栈项目模板技术栈一股脑全是最新那一套FastAPI SQLModel Pydantic v2 PostgreSQL前端是React TypeScript Vite Tailwind连管理后台、用户认证、邮件流程、Docker 部署都给你铺好了。我第一次看到时说实话第一反应是“又一个脚手架”但把代码拉下来跑了一遍后我才发现它比我预想的认真得多——它几乎是把一套商业级 Web 应用的基建直接端到了你面前。这篇文章不打算给你重复官方 README我想从一个实际跑完三轮项目的角度聊聊 Madeira 的核心设计逻辑、怎么快速上手、怎么加自己的业务代码、上线部署有哪些坑。无论是独立开发者想做产品原型还是团队想省掉基础工程的时间下面这些内容应该都能帮你少走点弯路。1. Madeira 是什么为什么值得折腾1.1 FastAPI 作者的全栈新作Sebastián Ramírez 是 FastAPI 的作者。FastAPI 这几年的位置大家都清楚写 API 快、类型安全、自动生成文档在 Python 后端里几乎是事实标准之一。但他一直没有停下来full-stack-fastapi-template 就是他在 FastAPI 之外维护的一个“全家桶”模板前几年更新一直比较克制。2024 年他把它正式更名成 Madeira顺手把技术栈全面翻新了一遍项目定位也从“模板”变成了“全栈框架”。Madeira 这个名字很有意思取自葡萄牙马德拉群岛也指当地著名的马德拉葡萄酒。这种酒的特点是经过陈年酿造风味会越变越醇厚。用这个名字来命名一个全栈项目多少透露出作者对这套技术栈的期待它不是一拍脑门的玩具而是会持续迭代、随实践沉淀的东西。项目本身其实是很多子项目组成的 monorepo默认带后端、前端、管理后台、数据库、以及流量入口容器这几大块。后端基于 FastAPI数据层用 SQLModelFastAPI 作者自己的 ORM权限用的是 JWT 机制前端用 React 生态管理后台用 React-Admin。每个组件都被 Docker 容器化开发环境和生产环境可以做到同一套配置。1.2 解决什么问题适合谁我自己的体会是这个项目解决的其实是三个层面的问题。第一个层面是“冷启动慢”。现在做一个 Web 应用单是基础工程就够折腾一星期用户注册、登录、邮箱验证、密码找回、用户管理、管理后台、部署脚本这些跟业务本身完全无关但必须做。Madeira 把这些默认全给你配好业务还没开始地基已经打完了。第二个层面是“技术选型纠结”。前后端用什么框架、数据库用哪个、要不要上管理后台、代码生成还是手写这些选择在项目一开始往往没有标准答案。Madeira 等于直接给出一套经过长期实践验证的组合拳你照单全收也行拆开挑一部分用也行。第三个层面是“最佳实践落地”。我自己见过太多 FastAPI 项目API 写得挺快但一谈到迁移、测试、部署就抓瞎。Madeira 把这些最佳实践变成了默认配置Alembic 管理数据库迁移、pytest 写后端测试、Playwright 跑端到端测试、Traefik 负责生产流量。这些东西在普通项目里需要资深工程师搭好几周在这里是干干净净开箱即用。所以适合的人群很清楚想做产品的独立开发者想快速验证想法的创业团队需要做内部管理系统的企业项目以及想系统学习全栈工程化的同学。如果你是第一次接触 FastAPI也不是不能上手但建议先把 FastAPI 本身玩熟再来接触 Madeira否则你会分不清哪些是框架能力、哪些是模板替你做的。2. 核心概念拆解Madeira 做了哪些关键决策2.1 技术栈的底层逻辑我先列一下 Madeira 默认带的几个关键组件以及它为什么这么选。组件选型替代方案为什么这么选后端框架FastAPIFlask, Django, Express异步性能好类型驱动自动生成 OpenAPI 文档和 Python 类型体系完美契合ORM/模型SQLModelSQLAlchemy, Tortoise ORM把 SQLAlchemy 和 Pydantic 二合一模型即校验模型写代码少一半数据库PostgreSQLMySQL, SQLite功能全面扩展性强社区生态好生产环境默认选择没有之一迁移工具AlembicDjango migrate, prisma migrateSQLAlchemy 官方迁移方案可控性强适合团队协作前端React Vite TSVue, Svelte, Next.js前后端分离场景下生态最成熟React Query 处理服务端状态非常舒服样式Tailwind CSS组件库, styled-components样式和组件解耦改起来快也能无缝接入 shadcn/ui 这类组件管理后台React-Admin自研后台Django Admin成熟的 REST 后台解决方案接上 API 几乎不用写代码这个组合看起来好像是“作者自己喜欢什么用什么”但仔细看会发现里面是有逻辑的。后端这一侧FastAPI SQLModel Pydantic v2 是一套完整的类型闭环。Schema 定义在 Python 里数据库表结构、请求体校验、响应体序列化全部由同一套类型派生出来。你改写一个模型字段API 层、文档、校验规则都会自动跟着变这是 Django 那种“模型归模型、序列化器归序列化器”的方式做不到的。前端这一侧React 不是性能上最优解也不是语法上最简洁的但它是生态最厚的。React Query 解决服务端状态同步Vite 解决开发体验TypeScript 解决前后端类型对接Tailwind 解决样式可维护性。这些东西组合起来开发速度会明显快过自己从零搭一套前端工程。2.2 认证与数据层的默认实现认证是每个从模板起步的项目都必须面对的大坎Madeira 默认给出的方案是 JWT。具体流程大致是用户提交邮箱和密码后端校验之后签发访问令牌令牌在下一次请求时通过 HTTPOnly Cookie 带回来后端再解密校验用户身份。用 Cookie 而不是 localStorage好处是前端代码拿不到令牌XSS 再怎么折腾也偷不走配合 SameSite 策略CSRF 风险也能控制在可接受范围内。数据层方面Madeira 用 SQLModel 定义每个表然后通过 Alembic 生成迁移文件。这里有个非常重要的工程习惯数据库结构不是靠代码自动同步的而是每次改动都生成一份迁移脚本记录“从旧版本到新版本”的可靠转换过程。这样团队多人协作、线上数据备份恢复、回滚操作都有据可查。2.3 前端与管理后台的分工Madeira 把前端拆成了两个独立入口普通用户界面和管理后台界面。普通用户界面是一个标准的 React 单页应用认证逻辑封装在路由层未登录访问受保护页面自动跳转到登录页登录之后根据角色信息控制能访问哪些页面。管理后台则单独跑一个 React-Admin 应用直接向后端 REST API 拿数据自动生成列表、表单、筛选、分页。这种拆法的最直接好处是两套代码互不干扰。用户端追求体验和性能后台端追求开发效率和表单完整性。React-Admin 甚至能根据 API 返回的 schema 自动推断字段类型建一个带增删改查的资源模块几行代码就够不用自己写表格组件。3. 实操从拉取代码到跑通第一个页面3.1 准备环境与初始化体验 Madeira最好先准备这些工具。Docker 是必须的我建议安装 Docker Desktop 或等效引擎确保 Docker Compose 插件可用本地最好也装 Python 3.12 和 Node.js 18虽然项目里容器自带了运行环境但后面开发调试时在本地跑会更方便。拉取项目git clone 项目仓库地址 madeira-demo cd madeira-demo先别急着启动把环境变量文件准备出来。项目根目录一般会提供一个 .env 示例文件复制一份再改cp .env.example .env需要重点关注几个配置项POSTGRES_PASSWORD数据库密码、SECRET_KEYJWT 加密密钥生产环境必须换成长随机字符串、DOMAIN部署域名等。开发环境可以先保持默认但不能不改 SECRET_KEY这算是基本安全意识。3.2 用 Docker 一键拉起整套服务首次启动直接docker compose up -d --build这个过程因为要拉基础镜像、构建前后端会比预想的慢耐心等几分钟就好。启动完成后docker compose ps 可以看到五个左右的容器在运行数据库、后端 API、前端、管理后台、流量入口。按我实际跑下来的经验默认端口分配大概是这样的具体看项目文档服务开发地址说明前端http://localhost:5173Vite 开发服务器后端 APIhttp://localhost:8000FastAPI 接口带 /docs 文档管理后台http://localhost:3000React-Admin 界面数据库localhost:5432PostgreSQL 实例初次启动后项目会通过初始化脚本自动创建超级管理员账号账号密码会在启动日志或 .env 里给出来。用这个账号登录后台能看到默认的用户管理页面到这里整个基础链路就已经跑通了浏览器到前端再到后端 API再到数据库。3.3 自定义业务模型加一张表再加一组 API项目跑起来之后就可以开始加自己的业务了。我拿一个最常见的场景举例做一个订单系统需要先加一张订单表。第一步在后端项目里创建模型文件比如 backend/app/models/order.pyfrom sqlmodel import SQLModel, Field class Order(SQLModel, tableTrue): id: int | None Field(defaultNone, primary_keyTrue) order_no: str Field(indexTrue, max_length32) amount: float Field(default0.0) status: str Field(defaultpending, max_length16)第二步把这个模型挂到数据库初始化和迁移流程里在模型汇总文件中 import 一下让 Alembic 能发现它。第三步生成迁移文件docker compose exec backend alembic revision --autogenerate -m add order table docker compose exec backend alembic upgrade head这里多说一句Alembic 自动生成的迁移文件只是帮你写好了初稿字段变更、索引调整这些复杂的迁移我还是建议手动过一遍生成的脚本确认每一条 op 都是预期的再执行 upgrade。第四步写 CRUD 接口。在 backend/app/api 下新建路由from fastapi import APIRouter, Depends from sqlmodel import Session, select from app.models.order import Order from app.core.db import get_session router APIRouter(prefix/orders, tags[orders]) router.get(/) def list_orders(session: Session Depends(get_session)): return session.exec(select(Order)).all()路由挂到主 app 上之后访问 /docs 就能看到新增的 API数据库里的表也建好了后端的自定义部分就完成了。4. 前后端联调把自己的业务接进界面4.1 前端页面与 API 对接后端接口有了接下来把前端接上。Madeira 的前端已经封装好了 API 客户端你不用在每个页面里手写 fetch 和错误处理直接用现有的请求方法就可以。大致流程是在 API 模块里加一个获取订单列表的函数然后在页面组件里用 React Query 的 useQuery 调用它import { useQuery } from tanstack/react-query; import { api } from ../api/client; export function OrderList() { const { data, isLoading } useQuery({ queryKey: [orders], queryFn: () api.get(/orders).then((res) res.data), }); if (isLoading) return div加载中.../div; return pre{JSON.stringify(data, null, 2)}/pre; }这么写的好处是React Query 会帮你处理缓存、重新请求、失败重试和加载状态页面代码干净很多不需要自己维护一堆 useState 和 useEffect。4.2 后台管理界面的接入后台部分更简单。React-Admin 的核心思想是“资源驱动”你只要注册一个资源告诉它后端接口地址整套列表、详情、编辑、删除页面就自动出来了import { Resource, List, Datagrid, TextField } from react-admin; export const OrderList () ( List Datagrid TextField sourceorder_no / TextField sourceamount / TextField sourcestatus / /Datagrid /List ); // 注册资源 Resource nameorders list{OrderList} /然后把 order 资源挂到 Admin 组件上刷新后台页面就能看到新增的订单管理模块。React-Admin 会默认从 /orders 拉取列表数据也能自动处理分页、筛选和排序参数。对内部管理系统来说这部分的开发成本几乎可以忽略不计。4.3 本地开发模式的选择用 docker compose 起全套服务适合验证和部署但日常开发我推荐另一个方式后端、数据库、前端分别启动在本地开发模式。资源占用会更低热更新也更快。我习惯的做法是数据库和流量入口继续用 Docker 起后端在本地用 uvicorn 跑前端直接 npm run dev。这样改 Python 代码uvicorn 会自动刷新改前端组件Vite 的 HMR 几乎是秒级生效。写业务的时候体感比每次改代码都重建镜像舒服很多。5. 部署与上线从开发机到生产环境5.1 生产构建与容器化部署Madeira 的设计里开发环境和生产环境共用同一份 Docker Compose 配置只是通过环境变量切换。准备上线时主要做这几件事把 .env 里的 DOMAIN 改成正式域名配置好 DNS 解析。把 SECRET_KEY 换成一个足够长的随机值建议 64 字节以上。确认数据库密码、管理员初始密码等敏感值都已修改。执行生产构建docker compose -f docker-compose.yml up -d --build。流量入口容器会自动处理 HTTPS 证书签发和续期不需要手动配置 Nginx 或手动干预路由规则。你只要把域名解析过去首次启动它就会自动申请证书这在大厂项目里通常需要专人维护在这里是默认能力。5.2 上线后的几个关键优化上线之后有几个点值得第一时间处理。数据库的定期备份可以用 Postgres 自带的 pg_dump 写一个定时任务脚本把备份文件打包上传到对象存储或异地磁盘一旦出问题能快速恢复。日志收集容器默认把日志打到 Docker量大的时候建议接入日志系统或者至少按天落盘避免 Docker 日志文件无限膨胀。监控对中小项目而言后端存活检查加上数据库连接池监控就足够撑起第一版不用一上来就上重量级 APM。还有一点容易忽略代码更新。服务跑起来之后每次改代码都要保证迁移脚本先执行、应用再滚动重启。简单做法是在启动脚本里先跑 alembic upgrade head再启动 uvicorn 进程这样发布流程能够做到自动化且不漏迁移。我给一个启动脚本的参考#!/bin/bash set -e alembic upgrade head uvicorn app.main:app --host 0.0.0.0 --port 806. 踩坑记录与问题排查速查6.1 我实操中遇到的几个典型问题我前后跑过三轮 Madeira 项目有些坑值得写出来。第一个坑是首次 docker compose build 太慢。解决方案是把镜像仓库切到国内镜像源或者提前 pull 好公共镜像再执行 --build。别想着等第一次卡个十分钟都很正常。第二个坑是后端改模型之后忘记跑迁移API 一直报错。报错信息往往是“column xxx does not exist”这时候不要怀疑代码先去确认迁移是否执行到位docker compose exec backend alembic current docker compose exec backend alembic upgrade head第三个坑是前端跨域问题。浏览器里登录状态丢、请求失败十有八九是 Cookie 的 SameSite 和 Secure 配置不对。开发环境走 http生产环境走 https这两套配置不能混用否则登录状态就会时好时坏。第四个坑是 React-Admin 的资源名和后端路由对不上。比如后端接口在 /api/orders但 Admin 里注册的 name 是 orders两者需要保持一致或者写好映射不然列表页会请求错误地址。我把这些问题整理成了一个速查表方便对照。现象可能原因排查手段解决方案build 卡在拉镜像网络慢或镜像源默认国外docker compose pull 单独执行换国内镜像源提前拉公共镜像API 返回字段不存在迁移未执行alembic current 对比模型执行 alembic upgrade head登录后刷新即失效Cookie 配置跨环境不匹配查看浏览器 Cookie 属性统一 SameSite / Secure 配置Admin 列表页 404资源名与接口路径不一致看 Network 标签页的请求地址调整资源 name 或路径映射后台修改内容前端不更新React Query 缓存未失效查看 queryKey 是否变化在 mutation 后调用 invalidateQueries6.2 问题排查思路与自查清单排查这类全栈项目的问题我一般遵循一条主线先看流量入口日志再看后端 API 日志再看数据库状态最后看前端控制台。大多数问题都出在这四个环节里沿着这条链路排查很少会走弯路。自查清单我通常会在每次发布前过一遍是否更换了默认 SECRET_KEY数据库密码是否修改是否已经从默认值改掉迁移脚本是否已经生成并执行过 upgrade head环境变量文件里的域名、端口是否和环境匹配前端缓存是否清理避免上线后用户看到旧页面备份脚本是否已经配置并验证跑通过把这份清单固定下来日常发布基本不会出大问题。最后再分享一个我自己的体会这套全栈结构刚接触时会有种“啥都有、不知从哪改”的眩晕感但等你亲手加完一个业务模型、跑完一次迁移、把前后端和后台都串起来你会对整个现代 Web 应用的工程结构形成完整的画面感。这种理解不是看几篇文档就能获得的——这也是我花了几个晚上完整跑完一遍之后收获感最强的地方。