Docker 已经成为现代后端部署的标配工具。本文将带你用 20 分钟,从零开始把一个 Python Web 服务容器化并运行起来。
为什么要用 Docker
在没有 Docker 的时代,部署一个服务需要手动安装运行时、配置依赖、处理环境差异。“在我机器上能跑"成了经典甩锅语录。
Docker 把应用和它的运行环境打包成一个镜像(Image),在任何装了 Docker 的机器上都能以相同方式运行。核心思路很简单:用代码定义环境,而不是手动配置。
几个关键概念:
- 镜像(Image):只读的模板,包含应用代码和运行所需的一切
- 容器(Container):镜像的运行实例,可以启动、停止、删除
- Dockerfile:构建镜像的配方文件
- docker-compose.yml:定义多个容器如何协同工作的配置文件
准备工作
确保机器上已安装 Docker 和 Docker Compose:
| |
如果没装,参考 Docker 官方文档。Linux 用户装完后把当前用户加入 docker 组,免得每次都加 sudo:
| |
重新登录终端生效。
第一步:写一个简单的 Web 服务
创建一个项目目录:
| |
写一个最小的 Flask 应用 app.py:
| |
再写一个 requirements.txt:
flask==3.1.*
第二步:编写 Dockerfile
在项目根目录创建 Dockerfile:
| |
逐行解释:
| 指令 | 作用 |
|---|---|
FROM python:3.12-slim | 基础镜像,slim 版本体积小 |
WORKDIR /app | 设置容器内的工作目录 |
COPY requirements.txt . | 先复制依赖文件,利用 Docker 层缓存 |
RUN pip install ... | 安装依赖 |
COPY . . | 再复制应用代码 |
EXPOSE 5000 | 声明端口(文档作用,不实际映射) |
CMD ["python", "app.py"] | 容器启动时运行的命令 |
为什么分两步 COPY? Docker 会缓存每一层。如果代码改了但 requirements.txt 没变,pip install 那层会直接走缓存,构建速度更快。
第三步:编写 docker-compose.yml
| |
这比直接用 docker run 更清晰,而且一条命令就能管理。
第四步:构建并运行
| |
第一次会下载基础镜像并安装依赖,之后再构建会很快。看到 Flask 的启动日志后,打开另一个终端测试:
| |
按 Ctrl+C 停止。如果想后台运行:
| |
第五步:加入数据库
实际项目通常需要数据库。给 docker-compose.yml 加一个 PostgreSQL:
| |
几个要点:
depends_on+service_healthy确保数据库就绪后才启动应用volumes让数据库数据持久化,容器删了数据还在- 同一个 compose 文件里的服务可以用服务名(
db)作为主机名互相访问
常见问题
容器内访问宿主机服务
用 host.docker.internal(macOS/Windows)或 host.network(Linux)。
镜像太大
用 slim 或 alpine 基础镜像;多阶段构建把构建工具和运行时分开。
修改代码后不生效
挂载本地目录到容器内,开发时热更新:
| |
如何查看运行中的容器
| |
生产环境建议
这篇文章覆盖的是开发环境的基本用法。上生产前还需要考虑:
- 不要硬编码密码:用
.env文件或密钥管理服务 - 网络隔离:数据库端口不要映射到宿主机,只让应用容器访问
- 日志管理:配置日志驱动,避免容器日志撑爆磁盘
- 资源限制:设置 CPU 和内存上限,防止单个容器耗尽资源
小结
整个流程就是四步:写代码 → 写 Dockerfile → 写 docker-compose.yml → docker compose up。Docker 的核心价值不在于技术有多复杂,而在于它把"部署"从一件靠记忆和运气的事,变成了一件可以版本控制、可以复现、可以自动化的事。