本文档按当前项目实际配置编写。根目录 Dockerfile 会构建一个单容器镜像,并在容器内同时运行 FastAPI 后端和 Next.js standalone 前端。
30008000/app/database.db/app/images/app/data/backups/app/start-all.sh 同时拉起后端和前端,并在任一进程退出时结束容器8234 -> 容器 3000前端通过 Next.js rewrites 访问后端接口和图片:
/api/:path* -> http://127.0.0.1:8000/api/:path*
/images/:path* -> http://127.0.0.1:8000/images/:path*
flower-inventory/
├─ Dockerfile # 多阶段构建:Next.js 构建、Python 依赖、最终运行镜像
├─ docker-compose.yml # 当前推荐的本地/服务器 Compose 部署配置
├─ .env.example # Compose 环境变量模板
├─ start-all.sh # 容器启动脚本
├─ backend/ # FastAPI 后端
├─ frontend-next/ # Next.js 前端
└─ data/
├─ database.db # SQLite 数据库文件
├─ images/ # 上传图片,含 materials/products/workflows
└─ backups/ # 系统备份文件
cp .env.example .env
编辑 .env,至少设置 SECRET_KEY:
SECRET_KEY=replace-with-a-long-random-secret
DATABASE_URL=
DIRECT_URL=
说明:
SECRET_KEY 是必填项;docker-compose.yml 使用 ${SECRET_KEY:?...},未设置时会直接启动失败。DATABASE_URL / DIRECT_URL 是旧工作流兼容占位,当前主业务路径使用 SQLite,可留空。.env.example 中的 CORS_ORIGINS 只在直接暴露后端或本地跨域联调时需要;当前 Compose 默认只暴露 Next.js 入口。Linux/macOS:
mkdir -p data/images data/backups
touch data/database.db
PowerShell:
New-Item -ItemType Directory -Force data\images, data\backups
if (!(Test-Path data\database.db)) { New-Item -ItemType File data\database.db }
必须提前创建 data/database.db 文件。否则 Docker 可能把缺失的宿主机路径当作目录创建,导致 SQLite 无法正常打开数据库文件。
docker compose up -d --build
首次构建会安装前端依赖、构建 Next.js standalone、安装 Python 依赖,耗时会比较久。
http://localhost:8234/api/v1/*http://localhost:8234/api/health默认登录:
用户名:admin
密码:admin123
首次登录会要求修改默认密码。同一 IP 在 5 分钟内登录失败 5 次会被临时限流。
docker-compose.yml 是 Compose 配置的唯一来源;本文只说明关键点,避免端口、变量或挂载路径变更后多处漂移。
当前配置使用本地 build: 构建镜像,不是直接拉取远程 image:。默认将宿主机 8234 映射到容器 3000,并挂载 ./data/database.db、./data/images、./data/backups。
如果要改访问端口,只改 docker-compose.yml 的 ports 左侧宿主机端口,例如把 8234:3000 改成 3000:3000。
当前需要持久化三个宿主机路径:
| 宿主机路径 | 容器路径 | 用途 |
|---|---|---|
./data/database.db | /app/database.db | SQLite 数据库 |
./data/images | /app/images | 花材、成品、工作流图片 |
./data/backups | /app/data/backups | 手动备份、自动备份、整包备份 |
图片目录由后端自动确保存在:
/app/images/materials
/app/images/products
/app/images/workflows
请定期备份整个 data/ 目录,尤其是 database.db 和 images/。
| 变量名 | Docker 中的值 | 说明 |
|---|---|---|
SECRET_KEY | 来自 .env,必填 | JWT 签名密钥;生产环境必须自定义 |
DB_PATH | /app/database.db | SQLite 数据库路径 |
IMAGE_DIR | /app/images | 上传图片根目录 |
BACKUP_DIR | /app/data/backups | 备份文件目录 |
BACKEND_PORT | 8000 | Uvicorn 后端端口,容器内使用 |
PORT | 3000 | Next.js standalone server 端口 |
DATABASE_URL | 可留空 | 旧 Prisma/Supabase 兼容占位,当前主业务不依赖 |
DIRECT_URL | 可留空 | 旧 Prisma/Supabase 兼容占位,当前主业务不依赖 |
CORS_ORIGINS | 当前 Compose 未转发 | 直接暴露后端或跨域联调时才需要 |
后端在没有有效 SECRET_KEY 时会生成临时随机密钥,服务重启后所有登录态会失效。Compose 部署下应始终显式设置 SECRET_KEY。
查看容器状态:
docker compose ps
查看日志:
docker compose logs -f app
重启:
docker compose restart app
停止:
docker compose down
重新构建并启动当前代码:
docker compose up -d --build
进入容器:
docker exec -it flower_inventory_app sh
因为当前 docker-compose.yml 使用 build: 从本地源码构建,升级步骤是先更新代码,再重新构建容器:
# 先备份 data/ 目录
# 然后更新代码,例如 git pull
docker compose up -d --build
不要用 docker compose pull 作为当前 Compose 配置的主要升级方式;该命令只适用于 image: 部署方式。
如果你已经有镜像,例如 goordonchen/flower-inventory:latest,可以不用 Compose,直接运行:
mkdir -p data/images data/backups
touch data/database.db
docker run -d \
--name flower_inventory_app \
-p 8234:3000 \
-v "$(pwd)/data/database.db:/app/database.db" \
-v "$(pwd)/data/images:/app/images" \
-v "$(pwd)/data/backups:/app/data/backups" \
-e DB_PATH=/app/database.db \
-e IMAGE_DIR=/app/images \
-e BACKUP_DIR=/app/data/backups \
-e BACKEND_PORT=8000 \
-e PORT=3000 \
-e SECRET_KEY=replace-with-a-long-random-secret \
--restart unless-stopped \
goordonchen/flower-inventory:latest
PowerShell 中建议使用 ${PWD} 或绝对路径,并注意引号:
docker run -d `
--name flower_inventory_app `
-p 8234:3000 `
-v "${PWD}\data\database.db:/app/database.db" `
-v "${PWD}\data\images:/app/images" `
-v "${PWD}\data\backups:/app/data/backups" `
-e DB_PATH=/app/database.db `
-e IMAGE_DIR=/app/images `
-e BACKUP_DIR=/app/data/backups `
-e BACKEND_PORT=8000 `
-e PORT=3000 `
-e SECRET_KEY=replace-with-a-long-random-secret `
--restart unless-stopped `
goordonchen/flower-inventory:latest
构建当前平台镜像:
docker build -t goordonchen/flower-inventory:latest .
如果只想验证 Dockerfile 是否能构建成功,也可以使用临时标签:
docker build -t flower-inventory:local .
Dockerfile 使用 BUILDPLATFORM / TARGETPLATFORM,支持 Buildx 多架构构建。常用目标平台:
linux/amd64:常见 x86_64 服务器linux/arm64:ARM 服务器、Apple Silicon、树莓派等docker buildx create --name multiarch --driver docker-container --use --bootstrap
如果构建器已存在:
docker buildx use multiarch
docker buildx inspect --bootstrap
docker run --privileged --rm tonistiigi/binfmt --install all
docker login
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t goordonchen/flower-inventory:1.0.0 \
-t goordonchen/flower-inventory:latest \
--push \
.
说明:
--platform linux/amd64,linux/arm64 同时构建双架构镜像。--push 会直接推送到镜像仓库。docker build 一次性保存到本地 Docker engine。检查镜像架构:
docker buildx imagetools inspect goordonchen/flower-inventory:latest
输出中应能看到 linux/amd64 和 linux/arm64。
系统设置中支持:
自动备份调度随 FastAPI 后端进程启动,后台 APScheduler 会按规则动态注册下一次备份任务,设置变更后刷新调度。备份文件会保存到宿主机 ./data/backups。升级、迁移或更换服务器前,建议先完整复制:
data/database.db
data/images/
data/backups/
docker compose up 提示必须设置 SECRET_KEY复制 .env.example 为 .env,并填写 SECRET_KEY:
cp .env.example .env
确认宿主机 data/database.db 是文件,不是目录:
ls -l data/database.db
如果它被误创建成目录,需要先停止容器,备份确认后删除该目录,再创建同名文件。
确认容器内两个进程都启动成功:
docker compose logs -f app
正常日志应包含类似:
Starting backend on :8000
Starting frontend on :3000
当前只需要修改 docker-compose.yml 的 ports 左侧宿主机端口。例如 "8234:3000" 表示访问宿主机 8234,容器内 Next.js 仍监听 3000。
DATABASE_URL / DIRECT_URL 要不要填写当前主业务路径是 FastAPI + SQLite,不需要填写。保留空值即可,主要用于兼容旧配置和避免 Compose 变量提示。
docker compose pull 没有更新应用当前 Compose 使用 build:,不是 image:。请更新源码后执行:
docker compose up -d --build
SECRET_KEY。.env、data/database.db、data/images/ 提交到仓库。data/ 目录。data/database.db、data/images/、data/backups/ 后用同一套挂载路径启动。8000 默认不对外暴露;外部访问应走 Next.js 入口。frontend-next/package.json 和可选的 package-lock.json;Dockerfile 会优先执行 npm ci。Content type
Image
Digest
sha256:1e23b3ae7…
Size
104.5 MB
Last updated
about 7 hours ago
docker pull goordonchen/flower-inventory