在飞牛 NAS(fnOS)上使用 Docker 部署 FastAPI 应用(这个是从错误学习教程 图是可以的)

在飞牛 NAS(fnOS)上使用 Docker 部署 FastAPI 应用

本教程将引导你从零开始,在飞牛 NAS(fnOS)上通过 Docker 部署一个简单的 FastAPI 应用。你将学习如何通过 SSH 连接到 NAS、编写 Dockerfile、构建镜像、运行容器,并处理常见的错误。

1. 前提条件

  • 一台已经安装好飞牛 NAS(fnOS)的设备,并且你知道它的 IP 地址和管理员账号密码。
  • 一台可以访问该 NAS 的电脑(本教程以 Windows 为例)。
  • 飞牛 NAS 上已安装 Docker(通常 fnOS 自带 Docker 或可通过应用中心安装)。

2. 通过 SSH 连接到飞牛 NAS

2.1 在飞牛 NAS 上开启 SSH 服务

  1. 在浏览器中输入飞牛 NAS 的 IP 地址和端口(默认 5666),例如 http://192.168.160.128:5666,登录管理界面。
  2. 进入 【设置】 > 【SSH】
  3. 勾选 【启用 SSH 服务】 ,端口保持默认 22,点击 【保存】

2.2 从 Windows 使用 PowerShell/CMD 连接

  1. 在 Windows 上打开 PowerShell命令提示符 (按 Win+R,输入 powershellcmd)。

  2. 输入以下命令,将 <username> 替换为你的 NAS 用户名,<nas-ip> 替换为 NAS 的 IP 地址:

    bash 复制代码
    ssh <username>@<nas-ip>

    例如:ssh admin@192.168.160.128

  3. 首次连接会提示确认主机指纹,输入 yes 后回车。

  4. 输入你的密码(输入时屏幕无显示,属正常现象),然后回车。

登录成功后,你会看到类似 admin@fnOs:~$ 的提示符。

2.3 切换到 root 用户

为了获得完整权限执行 Docker 命令,建议切换到 root 用户:

bash 复制代码
sudo -i

输入当前用户的密码后,提示符变为 root@fnOs:~#,表示已拥有 root 权限。

3. 检查 Docker 环境

确认 Docker 已正确安装:

bash 复制代码
docker --version

示例输出:Docker version 28.5.2, build ecc6942

检查当前运行的容器(应为空):

bash 复制代码
docker ps

4. 准备 FastAPI 项目文件

4.1 创建项目目录

假设我们将项目放在 /vol1/1000/fastapi(请根据你的 NAS 存储路径调整):

bash 复制代码
mkdir -p /vol1/1000/fastapi
cd /vol1/1000/fastapi

4.2 编写 FastAPI 应用

创建 main.py 文件,内容如下:

python 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

你可以使用 nanovim 编辑文件,例如:

bash 复制代码
nano main.py

粘贴上述代码后,按 Ctrl+O 保存,Ctrl+X 退出。

4.3 编写依赖文件 requirements.txt

创建 requirements.txt,列出所需 Python 包:

txt 复制代码
fastapi
uvicorn

4.4 编写 Dockerfile

创建 Dockerfile,内容如下(使用 python:latest 基础镜像):

dockerfile 复制代码
# 使用最新的 Python 完整镜像
FROM python:latest

# 设置容器内工作目录
WORKDIR /app

# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/

# 复制应用代码
COPY . .

# 暴露应用端口
EXPOSE 8000

# 启动命令(假设 main.py 在项目根目录)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

注意 :如果你的 main.py 位于子目录(如 app/main.py),请将 CMD 改为 ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

4.5 最终项目结构

此时目录下应有三个文件:

复制代码
/vol1/1000/fastapi/
├── Dockerfile
├── requirements.txt
└── main.py

5. 构建 Docker 镜像

在项目目录下执行构建命令:

bash 复制代码
docker build -t my-fastapi-app .
  • -t my-fastapi-app 为镜像指定名称。
  • 最后的 . 表示使用当前目录的 Dockerfile。

5.1 首次构建可能遇到的问题

问题 :拉取基础镜像失败,提示 401 Unauthorized
原因 :Docker 守护进程配置了私有镜像仓库(如 docker.fnnas.com)且未登录,或镜像源不可用。
解决方法:先手动拉取官方镜像:

bash 复制代码
![docker pull python:latest](https://i-blog.csdnimg.cn/direct/754e80b610164fcb809de99513c93273.png)

成功拉取后,再执行 docker build,此时会使用本地缓存的镜像。

5.2 成功构建镜像

构建成功后,查看本地镜像:

bash 复制代码
docker images

应看到 my-fastapi-apppython 两个镜像。

6. 运行 Docker 容器

6.1 第一次运行:端口冲突

尝试运行容器,将主机的 8000 端口映射到容器的 8000 端口:

bash 复制代码
docker run -d -p 8000:8000 --name my-fastapi-container my-fastapi-app

如果遇到错误:

复制代码
docker: Error response from daemon: failed to set up container networking: ... address already in use

说明主机的 8000 端口已被占用(例如被 nginx 占用)。可以使用以下命令检查端口占用:

bash 复制代码
netstat -tulpn | grep 8000

6.2 更换端口再次运行

将主机端口改为其他未占用的端口,例如 8009:

bash 复制代码
docker run -d -p 8009:8000 --name my-fastapi-container my-fastapi-app

6.3 容器名冲突

如果之前运行过同名容器(即使是停止状态),会提示:

复制代码
docker: Error response from daemon: Conflict. The container name "/my-fastapi-container" is already in use...

解决方法:

  • 删除旧容器:docker rm my-fastapi-container
  • 或使用不同的名称,如 my-fastapi-container1

6.4 成功运行容器

最终成功运行的命令示例:

bash 复制代码
docker run -d -p 8009:8000 --name my-fastapi-container1 my-fastapi-app

输出一串容器 ID 表示启动成功。

7. 验证应用

7.1 查看容器日志

bash 复制代码
docker logs my-fastapi-container1

应看到类似 Uvicorn running on http://0.0.0.0:8000 的信息。

7.2 测试 API

在 NAS 本地或同一局域网内的电脑上,使用 curl 或浏览器访问:

复制代码
http://<nas-ip>:8009/

例如 http://192.168.160.128:8009/,应返回 JSON 数据:

json 复制代码
{"Hello":"World"}

如果无法访问,请检查防火墙设置或容器是否正常运行。

8. 常用 Docker 命令

命令 说明
docker ps 列出运行中的容器
docker ps -a 列出所有容器(包括已停止的)
docker images 列出本地镜像
docker stop <容器名> 停止容器
docker rm <容器名> 删除容器
docker rmi <镜像名> 删除镜像
docker logs <容器名> 查看容器日志
docker exec -it <容器名> /bin/bash 进入容器内部
docker build -t <镜像名> . 构建镜像
docker run -d -p <主机端口>:<容器端口> --name <容器名> <镜像名> 运行容器

9. 清理与重建

当你修改了代码或 Dockerfile,需要重新构建并运行新容器。

9.1 停止并删除容器

bash 复制代码
docker stop my-fastapi-container1
docker rm my-fastapi-container1

9.2 删除镜像

如果需要删除旧镜像(注意:如果镜像被其他容器引用,需先删除那些容器):

bash 复制代码
docker rmi my-fastapi-app

如果镜像被停止的容器引用,可以先强制删除容器,或使用 -f 强制删除镜像(谨慎使用)。

9.3 重新构建并运行

bash 复制代码
docker build -t my-fastapi-app .
docker run -d -p 8009:8000 --name my-fastapi-container1 my-fastapi-app

10. 常见问题排查

10.1 拉取基础镜像失败(401 Unauthorized)

现象 :构建时提示 failed to resolve source metadata ... 401 Unauthorized
原因 :Docker 配置了私有镜像仓库,或网络无法访问官方仓库。
解决 :手动拉取官方镜像 docker pull python:latest,或配置国内镜像加速器(如阿里云)。

10.2 端口被占用

现象 :运行容器时提示 address already in use
解决 :更换主机端口,例如将 8000 改为 8009。使用 netstat -tulpn | grep <端口> 查看占用情况。

10.3 容器名已存在

现象 :提示 Conflict. The container name "/xxx" is already in use
解决 :删除旧容器(docker rm <容器名>)或使用不同的容器名。

10.4 模块找不到(ModuleNotFoundError)

现象 :容器启动失败,日志显示 No module named 'main'
原因main.py 不在正确的位置,或 CMD 中指定的模块路径错误。
解决:进入容器检查文件结构:

bash 复制代码
docker run --rm my-fastapi-app ls -la /app

根据实际文件位置调整 CMD 中的导入路径。

11. 总结

通过本教程,你学会了:

  • 通过 SSH 连接到飞牛 NAS 并切换到 root 用户
  • 检查 Docker 环境
  • 编写 FastAPI 应用及其 Dockerfile
  • 构建 Docker 镜像并处理拉取镜像失败的问题
  • 运行容器并解决端口冲突、容器名冲突等常见错误
  • 验证应用是否成功运行
  • 清理和重建容器/镜像

现在,你的 FastAPI 应用已经成功运行在飞牛 NAS 的 Docker 容器中,可以通过浏览器访问了。希望这个教程对你有所帮助!如果有任何问题,欢迎随时提问。

飞牛Nas fnOS 也可yml来完成


docker-compose.yml

└── build: . → 查找当前目录的 Dockerfile

Dockerfile

├── FROM python:latest ← Python 基础镜像

├── pip install -r requirements.txt ← 安装 FastAPI 等依赖

└── CMD ["uvicorn", "memo:app", ...] ← 启动 FastAPI

docker-compose 做的事等价于:

docker build -t memo .

docker run -p 8089:8089 -v ./data:/app/data memo

复制代码
./data/
├── business_logs.db      # 数据库文件
└── uploads/              # 上传文件目录
    └── xxx.jpg           # 具体上传的文件

代码中:

  • DATABASE_FILE = "data/business_logs.db" → 数据库在 data/ 根目录
  • UPLOAD_DIR = Path("data/uploads") → 上传文件在 data/uploads/ 子目录
    这样挂载 ./data:/app/data 就能同时覆盖两者,没问题。
相关推荐
七夜zippoe1 小时前
集成测试实战:构建可靠的测试金字塔体系
python·log4j·e2e·fastapi·持续集成·flask api
yunhuibin1 小时前
VGGNet网络学习
人工智能·python·深度学习·神经网络·学习
圥忈&&丅佽&&扗虖3 小时前
linux 安装docker和docker-compose
linux·运维·docker
TheMemoryIsLost10 小时前
mac系统装docker,不装docker desktop,安装colima
macos·docker·容器
远离UE410 小时前
houdini hda 如何让模拟与虚幻物体进行碰撞
笔记·学习·houdini
浮游本尊11 小时前
React 18.x 学习计划 - 第十四天:实战整合与进阶收尾
前端·学习·react.js
The_Uniform_C@t212 小时前
PWN | 对CTF WIKI的复现+再学习 (第八期)
网络·学习·网络安全·二进制
前路不黑暗@13 小时前
Java项目:Java脚手架项目的登录认证服务(十三)
java·spring boot·笔记·学习·spring·spring cloud·maven