当前位置:首页>python>Python教程 - Docker 容器化部署

Python教程 - Docker 容器化部署

  • 2026-08-18 23:10:35
Python教程 - Docker 容器化部署

欢迎来到第十一期!

在第一阶段的收官之作 Episode 10 中,你从零搭建了一个名为 **FinanceFlow** 的个人财务 Dashboard 项目——有后端(FastAPI + SQLite),有前端(React + Chart.js),还有 AI 智能分析(LangChain)。

**但有一个问题:** 你的代码跑在你自己的电脑上,换一台机器就可能会报错——"Python 版本不对"、"依赖没装全"、"环境变量缺失"……这种 **「在我机器上是好的」** 的痛点,几乎是每个程序员成长路上必经的一课。

**本期解决方案:Docker。**

学了这一期,你将能够:把任何 Python 项目打包成一个**可以在任何地方一键运行**的容器镜像。

>**前置知识**:需要熟悉本系列前面 10 期的内容,特别是 Episode 10 的 FinanceFlow 项目。

---

## 11.1 为什么需要 Docker?

### 11.1.1 现实困境

在 Docker 出现之前,部署一个 Python 应用通常需要经历这些痛苦:

```

开发环境(你的电脑):

  Python 3.12

  pip install fastapi uvicorn pandas matplotlib

  一切正常运行 ✅

生产服务器(别人的电脑):

  Python 3.8 ← 版本不匹配 ❌

  库没装全 ❌

  系统缺少依赖库(比如 libpq-dev)❌

  环境变量不对 ❌

  运行失败 💥

```

这就是著名的 **"它在我机器上是好的"** 问题。

### 11.1.2 Docker 的思路

Docker 的做法是:**不只打包代码,还打包一切——操作系统、解释器、依赖库、环境变量、甚至运行时配置。**

```

Docker 镜像 = 你的代码 + Python 解释器 + 所有依赖 + 系统库 + 配置文件

                          ↓

                   在任何地方 "运行" 这个镜像

                          ↓

                   保证行为完全一致 ✅

```

### 11.1.3 核心概念

| 概念 | 说明 | 类比 |

|------|------|------|

**镜像(Image)** | 只读的模板,包含了运行应用所需的一切 | 安装光盘 |

**容器(Container)** | 镜像的运行实例,是可读写的 | 从光盘里运行的程序 |

**Dockerfile** | 定义如何构建镜像的文件 | 食谱 |

**Docker Compose** | 定义多容器应用的配置文件 | 餐厅菜单(多个菜的组合) |

**Registry(仓库)** | 存储和分发镜像的地方(如 Docker Hub) | 应用商店 |

---

## 11.2 第一个 Docker 镜像

### 11.2.1 Hello World 示例

先从一个最简单的例子入手。创建一个 `hello.py`

```python

# hello.py

print("你好,Docker!")

print(f"Python 版本: {__import__('sys').version}")

```

接下来写 Dockerfile:

```dockerfile

# Dockerfile(第一版:最简单)

FROM python:3.12-slim

COPY hello.py /app/hello.py

CMD ["python""/app/hello.py"]

```

逐行解释:

-`FROM python:3.12-slim`:基础镜像。python:3.12 表示使用 Python 3.12,`slim` 是精简版(体积小)。

-`COPY hello.py /app/hello.py`:将本地的 hello.py 复制到镜像中的 /app/ 目录。

-`CMD`:容器启动时默认执行的命令。

构建和运行:

```bash

# 1. 构建镜像(-t 给镜像起个名字)

dockerbuild-tmy-hello.

# 2. 运行容器

dockerrunmy-hello

# 输出:

# 你好,Docker!

# Python 版本: 3.12.x (main, ...)

```

### 11.2.2 交互式容器

试试进入容器的 Shell:

```bash

# 启动容器并进入交互模式

dockerrun-it--rmpython:3.12-slim/bin/bash

# 在容器内部

root@abc123:/#python--version

Python3.12.x

root@abc123:/#ls

binbootdevetchomelibmediaoptprocrootrunsbinsrvsystmpusrvar

root@abc123:/#exit

```

`-it` 表示交互式终端,`--rm` 表示容器停止后自动删除。

---

## 11.3 为 FinanceFlow 项目编写 Dockerfile

现在回到 Episode 10 的 FinanceFlow 项目,这是我们要容器化的目标。

### 11.3.1 项目结构回顾

```

financeflow/

├── backend/

│   ├── main.py              # FastAPI 入口

│   ├── models.py            # Pydantic 模型

│   ├── database.py          # 数据库连接

│   ├── crud.py              # CRUD 操作

│   ├── ai.py                # AI 分析

│   └── requirements.txt     # Python 依赖

├── frontend/

│   └── financeflow-dashboard/  # React 项目

│       ├── package.json

│       └── src/

└── docker-compose.yml       # 多容器编排文件

```

### 11.3.2 后端 Dockerfile

```dockerfile

# backend/Dockerfile

# ==================== 构建阶段 ====================

FROM python:3.12-slim AS builder

# 设置工作目录

WORKDIR /build

# 安装构建依赖

RUN apt-get update && apt-get install -y --no-install-recommends \

    gcc \

    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件

COPY requirements.txt .

# 创建虚拟环境并安装依赖

RUN python -m venv /opt/venv

ENV PATH="/opt/venv/bin:$PATH"

RUN pip install --no-cache-dir -r requirements.txt

# ==================== 运行阶段 ====================

FROM python:3.12-slim AS runner

# 创建非 root 用户(安全最佳实践)

RUN groupadd -r appuser && useradd -r -g appuser appuser

# 从 builder 阶段复制虚拟环境

COPY --from=builder /opt/venv /opt/venv

ENV PATH="/opt/venv/bin:$PATH"

# 设置工作目录

WORKDIR /app

# 复制应用代码

COPY --chown=appuser:appuser main.py models.py database.py crud.py ai.py ./

# 创建数据目录

RUN mkdir -p /app/data && chown appuser:appuser /app/data

# 切换到非 root 用户

USER appuser

# 暴露端口

EXPOSE 8000

# 健康检查(让 Docker Compose 知道服务是否就绪)

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \

CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')" || exit 1

# 启动命令

CMD ["uvicorn""main:app""--host""0.0.0.0""--port""8000"]

```

关键点解析:

1.**多阶段构建**`AS builder` 和 `AS runner` 是两个阶段。构建阶段安装编译工具,运行阶段只保留必要的东西。这样可以做出**极小体积**的镜像。

2.**非 root 用户**:生产环境中不应该以 root 身份运行应用,这是基本的安全要求。

3.**健康检查**`HEALTHCHECK` 让 Docker 自动监控服务状态。

4.**`--no-cache-dir`**:pip 安装时不缓存下载的包,减少镜像体积。

### 11.3.3 前端 Dockerfile

```dockerfile

# frontend/Dockerfile

# ==================== 构建阶段 ====================

FROM node:20-alpine AS builder

WORKDIR /build

# 复制依赖文件(先复制再复制源码,利用 Docker 缓存层)

COPY package.json package-lock.json* ./

RUN npm ci --only=production

# 复制源码

COPY . .

# 构建生产版本

RUN npm run build

# ==================== 运行阶段 ====================

FROM nginx:alpine AS runner

# 复制构建产物到 Nginx

COPY --from=builder /build/dist /usr/share/nginx/html

# 自定义 Nginx 配置(CORS + API 代理)

COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx""-g""daemon off;"]

```

对应的 `nginx.conf`

```nginx

# frontend/nginx.conf

server {

    listen 80;

    server_name localhost;

    # 前端静态文件

    location / {

        root /usr/share/nginx/html;

        index index.html;

        try_files $uri $uri/ /index.html;  # SPA 路由支持

    }

    # API 代理到后端

    location /api/ {

        proxy_pass http://backend:8000/api/;

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

    }

    # 优化静态资源缓存

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {

        expires 1y;

        add_header Cache-Control "public, immutable";

    }

}

```

注意 `proxy_pass http://backend:8000/api/;` 中的 `backend` 是 Docker Compose 中后端服务的名字,Docker 内置 DNS 会自动解析。

### 11.3.4 依赖文件

```text

# backend/requirements.txt

fastapi==0.115.0

uvicorn[standard]==0.30.6

pydantic==2.9.2

sqlite3  # 内置,不需要

langchain==0.3.0

langchain-openai==0.2.0

openai==1.45.0

python-multipart==0.0.9

```

---

## 11.4 Docker Compose:多容器编排

一个完整的 FinanceFlow 项目至少需要两个服务:**后端 API** 和 **前端 Web 服务器**。Docker Compose 让你用一个命令管理它们。

### 11.4.1 docker-compose.yml

```yaml

# docker-compose.yml

version"3.9"

services:

# ========== 后端服务 ==========

backend:

build:

context./backend

dockerfileDockerfile

container_namefinanceflow-backend

ports:

      - "8000:8000"

volumes:

# 挂载数据目录(SQLite 数据库持久化)

      - db-data:/app/data

# 开发时用 volume 挂载代码,实现热重载

      - ./backend:/app

environment:

      - PYTHONUNBUFFERED=1

      - OPENAI_API_KEY=${OPENAI_API_KEY:-}

healthcheck:

test: ["CMD""python""-c""import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')"]

interval30s

timeout5s

retries3

start_period10s

restartunless-stopped

# ========== 前端服务 ==========

frontend:

build:

context./frontend

dockerfileDockerfile

container_namefinanceflow-frontend

ports:

      - "3000:80"

depends_on:

backend:

conditionservice_healthy# 等后端健康后再启动

restartunless-stopped

# ========== 持久化卷 ==========

volumes:

db-data:

driverlocal

```

关键概念:

-**`build`**:指定 Dockerfile 的位置和构建上下文

-**`ports`**:端口映射,`宿主机端口:容器端口`

-**`volumes`**:数据持久化和代码热重载

-**`environment`**:环境变量,`${VAR:-default}` 语法表示有值就用,没值就用默认

-**`depends_on` + `condition`**:依赖管理和启动顺序

-**`restart: unless-stopped`**:除非手动停止,否则 Docker 重启时自动恢复

### 11.4.2 .env 环境变量文件

```bash

# .env

OPENAI_API_KEY=sk-your-actual-api-key-here

```

在 docker-compose.yml 中引用:`${OPENAI_API_KEY}` 会从 `.env` 文件中读取。这样**不会把密钥提交到 Git**

记得在 `.gitignore` 中加入:

```

.env

__pycache__/

*.pyc

*.db

node_modules/

dist/

```

---

## 11.5 构建与运行

### 11.5.1 常用命令

```bash

# 1. 构建并启动所有服务

dockercomposeup--build

# 2. 后台运行(推荐)

dockercomposeup-d--build

# 3. 查看运行中的容器

dockerps

# 输出:

# CONTAINER ID   NAME                   STATUS                    PORTS                    NAMES

# abc123         financeflow-backend    Up 2 min (healthy)       0.0.0.0:8000->8000/tcp   financeflow-backend

# def456         financeflow-frontend   Up 1 min                 0.0.0.0:3000->80/tcp     financeflow-frontend

# 4. 查看日志

dockercomposelogs-fbackend# 实时查看后端日志

dockercomposelogs-ffrontend# 实时查看前端日志

# 5. 查看前端

# 浏览器打开 http://localhost:3000

# 6. 查看后端 API 文档

# 浏览器打开 http://localhost:8000/docs

# 7. 进入容器 Shell

dockerexec-itfinanceflow-backend/bin/bash

# 8. 停止服务(保留容器)

dockercomposestop

# 9. 删除所有容器(保留镜像和数据卷)

dockercomposedown

# 10. 彻底清理(删除容器、网络)

dockercomposedown--remove-orphans

# 11. 删除所有数据(包括数据库)

dockercomposedown-v

```

### 11.5.2 开发模式 vs 生产模式

```yaml

# docker-compose.dev.yml — 开发模式:代码热重载

version"3.9"

services:

backend:

build:

context./backend

dockerfileDockerfile.dev# 开发版 Dockerfile

volumes:

      - ./backend:/app# 挂载源码,改代码即刻生效

ports:

      - "8000:8000"

environment:

      - PYTHONUNBUFFERED=1

      - DEBUG=true

commanduvicorn main:app --host 0.0.0.0 --port 8000 --reload

frontend:

build:

context./frontend

dockerfileDockerfile.dev# 开发版 Dockerfile

ports:

      - "3000:5173"

volumes:

      - ./frontend:/app# 挂载源码

commandnpm run dev -- --host 0.0.0.0

```

开发版 Dockerfile(`backend/Dockerfile.dev`):

```dockerfile

# backend/Dockerfile.dev — 开发专用

FROM python:3.12-slim

WORKDIR /app

# 开发时需要完整依赖(包括 gcc 等编译工具)

RUN apt-get update && apt-get install -y --no-install-recommends \

    gcc libpq-dev \

    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

# 开发时以 root 运行(方便),用 --reload 实现热重载

EXPOSE 8000

CMD ["uvicorn""main:app""--host""0.0.0.0""--port""8000""--reload"]

```

```yaml

# docker-compose.prod.yml — 生产模式:精简、安全

# 使用前面 11.3 节写的生产 Dockerfile

version"3.9"

services:

backend:

build:

context./backend

dockerfileDockerfile# 生产 Dockerfile

container_namefinanceflow-backend

ports:

      - "8000:8000"

volumes:

      - db-data:/app/data

environment:

      - PYTHONUNBUFFERED=1

      - DEBUG=false

restartunless-stopped

frontend:

build:

context./frontend

dockerfileDockerfile# 生产 Dockerfile

container_namefinanceflow-frontend

ports:

      - "3000:80"

depends_on:

backend:

conditionservice_healthy

restartunless-stopped

volumes:

db-data:

driverlocal

```

启动生产环境:

```bash

dockercompose-fdocker-compose.prod.ymlup-d--build

```

---

## 11.6 镜像优化技巧

### 11.6.1 减小镜像体积

**未优化的镜像:**

```bash

dockerbuild-tmy-app:bad./backend

dockerimagesmy-app:bad

# 输出:my-app:bad    1.2GB

```

1.2 GB?太大了!让我们看看怎么优化。

**优化策略一:使用 slim/alpine 基础镜像**

```dockerfile

FROM python:3.12-slim    # 而不是 python:3.12(完整版约 900MB,slim 约 150MB)

```

**优化策略二:多阶段构建**(见 11.3.2,我们已经用了 ✅)

**优化策略三:合并 RUN 指令,利用缓存**

```dockerfile

# ❌ 差的写法:每行 RUN 都产生一层新镜像

RUN apt-get update

RUN apt-get install -y gcc

RUN apt-get install -y libpq-dev

RUN rm -rf /var/lib/apt/lists/*

# ✅ 好的写法:合并为一条 RUN,apt 的缓存只在第一条产生

RUN apt-get update && apt-get install -y --no-install-recommends \

    gcc libpq-dev \

    && rm -rf /var/lib/apt/lists/*

```

**优化策略四:利用 Docker 缓存层**

```dockerfile

# ❌ 差的写法:代码变动会导致重新安装依赖

COPY . .

RUN pip install -r requirements.txt

# ✅ 好的写法:先复制依赖文件,pip install 利用缓存

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .    # 代码变动不会影响上面那层的缓存

```

**优化策略五:使用 .dockerignore**

```text

# .dockerignore

__pycache__/

*.pyc

*.db

.git/

node_modules/

.env

*.md

dist/

build/

.venv/

```

**优化结果:**

```bash

# 优化前:1.2GB

dockerimagesmy-app:bad

# my-app:bad    1.2GB

# 优化后:约 200MB

dockerimagesmy-app:good

# my-app:good    198MB

# 体积缩小超过 80%!

```

### 11.6.2 镜像大小对比

| 基础镜像 | 大小(约) | 适用场景 |

|---------|-----------|---------|

`python:3.12` | 900MB | 开发、教学 |

`python:3.12-slim` | 150MB | **生产首选** |

`python:3.12-alpine` | 70MB | 极致精简(可能有兼容性问题) |

`node:20` | 1.1GB | 开发 |

`node:20-alpine` | 170MB | **前端构建首选** |

---

## 11.7 推送到 Docker Hub 并部署

### 11.7.1 推送镜像

```bash

# 1. 登录 Docker Hub

dockerlogin

# 2. 给镜像打标签(Tag)

# 格式:docker tag 本地镜像名 用户名/仓库名:版本号

dockertagfinanceflow-backendyourname/financeflow-backend:v1.0.0

dockertagfinanceflow-frontendyourname/financeflow-frontend:v1.0.0

# 3. 推送

dockerpushyourname/financeflow-backend:v1.0.0

dockerpushyourname/financeflow-frontend:v1.0.0

```

### 11.7.2 在生产服务器上部署

假设你有一台云服务器(Ubuntu / CentOS):

```bash

# 1. SSH 连接到服务器

sshuser@your-server.com

# 2. 安装 Docker(如果还没有)

curl-fsSLhttps://get.docker.com | sh

# 3. 克隆项目

gitclonehttps://github.com/yourname/financeflow.git

cdfinanceflow

# 4. 创建 .env 文件

cat > .env << 'EOF'

OPENAI_API_KEY=sk-your-api-key

EOF

# 5. 启动生产服务

dockercompose-fdocker-compose.prod.ymlup-d--build

# 6. 验证

curlhttp://localhost:8000/api/health

# 输出:{"status":"running","version":"1.0.0"}

# 浏览器访问 http://your-server.com:3000

```

### 11.7.3 使用 CI/CD 自动构建和部署

```yaml

# .github/workflows/deploy.yml

nameBuild and Deploy

on:

push:

branches: [main]

jobs:

build-and-deploy:

runs-onubuntu-latest

steps:

# 检出代码

      - usesactions/checkout@v4

# 登录 Docker Hub

      - nameLogin to Docker Hub

usesdocker/login-action@v3

with:

username${{ secrets.DOCKER_USERNAME }}

password${{ secrets.DOCKER_PASSWORD }}

# 构建并推送后端镜像

      - nameBuild and push backend

usesdocker/build-push-action@v5

with:

context./backend

pushtrue

tagsyourname/financeflow-backend:v${{ github.run_number }}

# 构建并推送前端镜像

      - nameBuild and push frontend

usesdocker/build-push-action@v5

with:

context./frontend

pushtrue

tagsyourname/financeflow-frontend:v${{ github.run_number }}

# 部署到服务器(通过 SSH)

      - nameDeploy to server

usesappleboy/ssh-action@v1

with:

host${{ secrets.SERVER_HOST }}

username${{ secrets.SERVER_USER }}

key${{ secrets.SSH_PRIVATE_KEY }}

script|

            cd ~/financeflow

            docker compose -f docker-compose.prod.yml pull

            docker compose -f docker-compose.prod.yml up -d

```

每次推送到 main 分支,GitHub Actions 会自动构建镜像、推送到 Docker Hub、并部署到你的服务器。

---

## 11.8 Docker 常见问题排查

### 11.8.1 常见问题清单

```bash

# 问题 1:端口被占用

# 错误:Error response from daemon: Ports are not available: exposing port TCP :8000

解决:更换宿主机端口

dockercomposedown

# 修改 docker-compose.yml: ports: ["8001:8000"]

dockercomposeup-d

# 问题 2:容器启动后立即退出

# 错误:Exit 0 (container stopped)

解决:容器需要有持续运行的进程。检查CMD是否正确

dockercomposelogsbackend# 查看日志

dockercomposeexecbackendpsaux# 查看容器内进程

# 问题 3:无法连接数据库

# 错误:Connection refused

解决:检查volume挂载是否正确,数据是否持久化

dockervolumels# 查看卷

dockercomposedown-v# 删除卷(重置数据)

# 问题 4:权限被拒绝

# 错误:Permission denied

解决:确认USERappuser正确设置了文件所有权

dockercomposeexecbackendls-la/app

# 问题 5:镜像构建慢

解决:使用国内镜像加速器

# /etc/docker/daemon.json(Linux)

# 或通过 Docker Desktop 设置(Windows/Mac)

  {

"registry-mirrors": ["https://docker.m.daocloud.io"]

  }

sudosystemctlrestartdocker

```

### 11.8.2 调试技巧

```bash

# 技巧 1:进入正在运行的容器

dockerexec-itfinanceflow-backend/bin/bash

# 技巧 2:查看容器内部文件系统

dockercpfinanceflow-backend:/app/main.py./main.py.debug

# 技巧 3:临时覆盖启动命令

dockercomposerun--rmbackendbash

# 技巧 4:查看容器资源使用

dockerstats

# 输出:

# CONTAINER           CPU %     MEM USAGE     MEM %     NET I/O

# financeflow-backend 2.5%      120MiB        3.0%      1.2kB/2.4kB

# financeflow-frontend 0.8%      45MiB         1.1%      0.8kB/1.6kB

# 技巧 5:打印环境变量,排查配置问题

dockercomposeexecbackendenv | grepOPENAI

# 技巧 6:重建镜像(不使用缓存)

dockercomposebuild--no-cache

```

---

## 11.9 实操练习

### 练习 1:构建第一个镜像

**题目**:为一个简单的 Python Flask 应用创建 Dockerfile。

```python

# app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')

defhello():

return"Hello from Docker!"

@app.route('/health')

defhealth():

return {"status""ok"}

if__name__ == '__main__':

    app.run(host='0.0.0.0'port=5000)

```

```text

# requirements.txt

flask==3.0.3

gunicorn==22.0.0

```

**任务**

1. 编写一个生产级 Dockerfile(多阶段构建 + 非 root 用户 + 健康检查)

2. 构建镜像并运行容器

3. 验证 `/` 和 `/health` 端点都能正常工作

<details>

<summary>参考答案</summary>

```dockerfile

# Dockerfile(参考答案)

FROM python:3.12-slim AS builder

WORKDIR /build

RUN apt-get update && apt-get install -y --no-install-recommends gcc && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .

RUN python -m venv /opt/venv && /opt/venv/bin/pip install --no-cache-dir -r requirements.txt

FROM python:3.12-slim AS runner

RUN groupadd -r appuser && useradd -r -g appuser appuser

COPY --from=builder /opt/venv /opt/venv

ENV PATH="/opt/venv/bin:$PATH"

WORKDIR /app

COPY --chown=appuser:appuser app.py .

EXPOSE 5000

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \

CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')" || exit 1

USER appuser

CMD ["gunicorn""--bind""0.0.0.0:5000""--workers""2""app:app"]

```

构建和测试:

```bash

dockerbuild-tmy-flask.

dockerrun-d-p5000:5000--nameflask-testmy-flask

# 验证

curlhttp://localhost:5000/# → Hello from Docker!

curlhttp://localhost:5000/health# → {"status":"ok"}

dockerrm-fflask-test

```

</details>

---

### 练习 2:Docker Compose 多服务编排

**题目**:创建一个包含三个服务的 docker-compose.yml:

1. 后端 API(使用我们前面写的 Python 镜像)

2. 前端(使用 Nginx 镜像托管静态文件)

3. Redis 缓存服务

**任务**

1. 编写 `docker-compose.yml`,让 Redis 作为一个独立的 service 运行

2. 让后端可以连接 Redis(通过服务名 `redis` 作为主机名)

3. 验证三个容器都能正常启动和通信

<details>

<summary>参考答案</summary>

```yaml

# docker-compose.yml

version"3.9"

services:

backend:

imagepython:3.12-slim

container_nameexercise-backend

working_dir/app

commandbash -c "pip install redis flask > /dev/null && python -c \"import redis; r = redis.Redis(host='redis', port=6379); r.set('test', 'hello from docker!'); print(r.get('test').decode())\""

volumes:

      - ./backend:/app

depends_on:

      - redis

networks:

      - app-network

frontend:

imagenginx:alpine

container_nameexercise-frontend

ports:

      - "3000:80"

volumes:

      - ./frontend:/usr/share/nginx/html

depends_on:

      - backend

networks:

      - app-network

redis:

imageredis:7-alpine

container_nameexercise-redis

ports:

      - "6379:6379"

networks:

      - app-network

networks:

app-network:

driverbridge

```

运行:

```bash

dockercomposeup-d

dockercomposelogsbackend# 应看到 "hello from docker!"

dockercomposedown

```

</details>

---

### 练习 3:镜像体积优化

**题目**:比较不同基础镜像的大小,并尝试优化一个已有的 Dockerfile。

**任务**

1. 分别拉取 `python:3.12``python:3.12-slim``python:3.12-alpine`,记录各自大小

2. 将一个使用 `python:3.12` 的 Dockerfile 改为多阶段构建 + `slim` 基础镜像

3. 计算优化前后的镜像大小对比

<details>

<summary>参考答案</summary>

```bash

# 1. 查看基础镜像大小

dockerimagespython

# 输出示例:

# python              3.12         c43fac3f6a29    3 weeks ago    923MB

# python              3.12-slim    8f4d3f6e8c21    3 weeks ago    148MB

# python              3.12-alpine  2a1b3c4d5e6f    3 weeks ago    68MB

# 优化前后对比:

# 优化前:python:3.12 + 单阶段 → 约 500MB(安装依赖后)

# 优化后:python:3.12-slim + 多阶段 → 约 150MB

# 体积缩小约 70%

```

</details>

---

### 练习 4:健康检查和自动重启

**题目**:为一个生产级 Dockerfile 添加健康检查和自动重启策略。

**任务**

1. 编写一个包含 `HEALTHCHECK` 指令的 Dockerfile

2. 在 `docker-compose.yml` 中使用 `depends_on` 的 `condition: service_healthy`

3. 模拟后端启动慢的场景,验证前端是否能正确等待

<details>

<summary>参考答案</summary>

```dockerfile

# Dockerfile(含健康检查)

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

HEALTHCHECK --interval=15s --timeout=3s --start-period=30s --retries=5 \

CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')" || exit 1

CMD ["uvicorn""main:app""--host""0.0.0.0""--port""8000"]

```

```yaml

# docker-compose.yml 片段

services:

frontend:

depends_on:

backend:

conditionservice_healthy# 关键:只有后端健康后才启动

imagenginx:alpine

ports:

      - "3000:80"

```

</details>

---

### 练习 5:部署到云服务器

**题目**:将你本地开发好的 FinanceFlow 项目部署到一台真实的云服务器上。

**任务**

1. 购买一台便宜的云服务器(阿里云/腾讯云/AWS 都有学生优惠)

2. 在服务器上安装 Docker

3. 将项目代码和 `docker-compose.yml` 上传到服务器

4. 配置防火墙和安全组(开放 80 和 443 端口)

5. 启动服务并访问你的在线 Dashboard!

<details>

<summary>参考步骤</summary>

```bash

# 1. 在本地构建并测试

cdfinanceflow

dockercomposeup-d--build

# 2. 上传到服务器(使用 scp 或 git)

scp-rfinanceflowuser@your-server.com:~/

# 3. 在服务器上操作

sshuser@your-server.com

cd~/financeflow

# 4. 创建 .env 文件(手动输入密钥)

nano.env

# 写入 OPENAI_API_KEY=sk-your-key-here

# 5. 启动生产环境

dockercompose-fdocker-compose.prod.ymlup-d

# 6. 配置 Nginx 做反向代理(可选,让域名直接访问)

sudoaptinstallnginx

sudonano/etc/nginx/sites-available/default

# 配置 server_name 和 proxy_pass

# 7. 验证

curlhttp://localhost:3000

```

</details>

---

## 11.10 知识点小结

| 知识点 | 在实际项目中的价值 |

|--------|-------------------|

| Docker 镜像与容器 | 一次构建,到处运行,消除环境差异 |

| 多阶段构建 | 大幅减小镜像体积,提升安全性 |

| Docker Compose | 轻松管理多服务架构(API + DB + 前端) |

| Volume 挂载 | 开发时热重载,生产时数据持久化 |

| 健康检查 | 让服务感知彼此状态,避免启动顺序问题 |

| 镜像推送与部署 | 从本地到云端的完整发布流程 |

---

## 11.11 小结与展望

恭喜!你已经学会了**容器化部署**,这是从"写出能跑的代码"到"让代码在任何地方都能可靠运行"的关键一步。

回顾一下这一期的核心收获:

```

学习阶段          你得到了什么

─────────────────────────────────────────

Episode 01-04     Python 基础语法和能力

Episode 05        抓取外部数据的能力

Episode 06        分析和理解数据的能力

Episode 07        构建后端服务的能力

Episode 08        接入 AI 智能的能力

Episode 09        打造用户界面的能力

Episode 10        整合所有能力的综合能力

Episode 11        ⭐ 将项目部署到世界任何地方的能力

```

**有了这一章,你的代码不再是"只能在本地跑的玩具",而是"可以被任何人随时访问的产品"。**

---

## 11.12 下期预告

第二阶段已经蓄势待发!以下是后续方向的预告:

-**Episode 12:数据库进阶** —— 从 SQLite 到 PostgreSQL,SQLAlchemy ORM,Alembic 迁移工具,让数据层像专业软件一样健壮。

-**Episode 13:Celery 异步任务** —— 定时财务报表、邮件通知、批量数据处理,学会让后台任务替你打工。

-**Episode 14:单元测试与 CI/CD** —— pytest + coverage,GitHub Actions 自动测试和部署,拥抱工程化。

-**Episode 15:WebSocket 实时通信** —— 让 Dashboard 的数据实时更新,告别手动刷新。

-**Episode 16:微服务架构初探** —— 把一个大项目拆成几个独立服务,了解分布式系统的入门概念。

无论你选择哪条路走下去,**容器化**都是现代软件开发的基础设施。哪怕你以后不做 Python 了,Docker 的知识依然会在每一个项目中帮到你。

下一期,我们聊聊如何让数据库也"容器化"—— Episode 12:数据库进阶。敬请期待!🐳🚀✨

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 15:39:41 HTTP/2.0 GET : https://f.mffb.com.cn/a/504875.html
  2. 运行时间 : 0.266056s [ 吞吐率:3.76req/s ] 内存消耗:4,760.77kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=b1909fef24b4fb5fbdbbdac209f2d1e7
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000360s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000731s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.006008s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.019899s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000773s ]
  6. SELECT * FROM `set` [ RunTime:0.000258s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000727s ]
  8. SELECT * FROM `article` WHERE `id` = 504875 LIMIT 1 [ RunTime:0.013820s ]
  9. UPDATE `article` SET `lasttime` = 1787297981 WHERE `id` = 504875 [ RunTime:0.009559s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000316s ]
  11. SELECT * FROM `article` WHERE `id` < 504875 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.006222s ]
  12. SELECT * FROM `article` WHERE `id` > 504875 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000637s ]
  13. SELECT * FROM `article` WHERE `id` < 504875 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.017057s ]
  14. SELECT * FROM `article` WHERE `id` < 504875 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.045284s ]
  15. SELECT * FROM `article` WHERE `id` < 504875 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.076069s ]
0.267631s