使用Docker快速部署FastAPI Web应用

Docker是基于 Linux 内核的cgroup、namespace以及 AUFS 类的Union FS 等技术,对进程进行封装隔离,一种操作系统层面的虚拟化技术。Docker中每个容器都基于镜像Image运行,镜像是容器的只读模板,容器是模板的一个实例。镜像是分层结构,一个镜像可以基于另一个镜像创建,最底层的镜像是基础镜像。

安装Docker

bash 复制代码
brew install --cask --appdir=/Applications docker

查看docker版本

bash 复制代码
% docker --version
Docker version 20.10.17, build 100c701

查看docker是否安装成功

bash 复制代码
% docker info     
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.9.1)
  compose: Docker Compose (Docker Inc., v2.10.2)
  extension: Manages Docker extensions (Docker Inc., v0.2.9)
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan: Docker Scan (Docker Inc., v0.19.0)
  

创建FastAPI镜像

依赖

python 复制代码
% cat requirements.txt 
fastapi[standard]>=0.113.0,<0.114.0
pydantic>=2.7.0,<3.0.0

Python代码

python 复制代码
# main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def index():
    return "测试容器部署"

目录结构

Bash 复制代码
% tree
.
├── Dockerfile
├── app
│   └── main.py
└── requirements.txt

Dockerfile

python 复制代码
% cat Dockerfile 
FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
EXPOSE 5000
COPY ./app /code/app
CMD ["fastapi", "run", "app/main.py", "--port", "5000"]

Dockerfile常用指令

指令 描述
FROM 指定基础镜像,可以指定多个,指定多个基础镜像时,编译时也会生成对应的多个镜像
MAINTAINER 指定镜像维护人信息,制作人根据自己情况指定
WORKDIR 设置工作目录,后续的RUN、COPY、CMD等命令都将在工作目录下运行
RUN 构建镜像时运行命令,可以用他安装软件等等
CMD 在容器实例中运行的命令,格式与RUN相同。注意,如果在docker run命令行里指定了命令,将不会执行CMD的内容。
ENTRYPOINT 在容器实例中运行的命令,格式与CMD相同。注意,如果在docker run时指定了命令,该命令会以命令行参数的形式传递到ENTRYPOINT中。
COPY 拷贝文件或目录到镜像中
ADD 拷贝文件或目录到镜像中,如果源文件是gizp等压缩文件,会被自动解压到目标目录
ENV 设置环境变量
USER 为RUN、CMD 和 ENTRYPOINT 执行命令指定运行用户
ARG 由外部启动时必须传入的参数,在容器启动时用--build-arg传递参数
EXPOSE 声明容器暴露给宿主机的端口,可以是一个或者多个以空格间隔
HEALTHCHECK 容器中服务健康检查
VOLUME 用于指定持久化目录

Docker镜像中有一个层的概念,每执行一个RUN命令,就会创建一个层,层过多会导致镜像文件体积增大。尽量在RUN命令中使用&&连接多条shell命令,减少RUN命令的个数,可以有效减小镜像文件的体积。在更多情况下,我们希望在docker run命令中为我们的服务传参,而不是覆盖执行命令,那么,我们应该使用ENTRYPOINT而不是CMD。

创建镜像

Bash 复制代码
% docker build -t myimage .         
[+] Building 54.4s (10/10) FINISHED                                             
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 37B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/library/python:3.9              4.4s
 => [internal] load build context                                          0.0s
 => => transferring context: 6.57kB                                        0.0s
 => [1/5] FROM docker.io/library/python:3.9@sha256:ed8b9dd4e9f89c111f4bd  18.5s

# 查看镜像
% docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
myimage      latest    31030096287b   22 minutes ago   1.06GB

Docker build常用参数

参数 说明
-t 指定Repository以及Tag,例如helloworld:1.0
-f 指定Dockerfile路径,Dockerfile不在当前目录时使用
---no-cache 常见镜像的过程中不使用Build Cache构建镜像
---pull 构建镜像时总是拉取Base Image的最新版本

运行

python 复制代码
% docker run -d --name mycontainer -p 80:5000 myimage
f23deab780852268532e6f820da33df67d6b39ba007db01d6eca2660e345a224

# 查看容器
% docker ps    
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
f23deab78085   myimage   "fastapi run app/mai..."   14 minutes ago   Up 14 minutes   0.0.0.0:80->5000/tcp   mycontainer

# 进入容器
% docker exec -it mycontainer bash

这里docker run从镜像myimage实例了一个容器,守护模式,命名为mycontainer,容器内部的端口是5000,宿主机的端口是80。

停止和移除容器

bash 复制代码
# 关闭容器
% docker stop mycontainer
mycontainer

# 启动容器
% docker start mycontainer
mycontainer

# 移除容器
% docker rm mycontainer  
mycontainer

导入镜像到生产环境

我们可以使用docker save命令将镜像保存到指定的文件中,保存的文件是一个.tar格式的压缩文件:

bash 复制代码
# 导出到tar
docker save -o hello.tar hello:1.0

# 导入到生产环境的docker
docker load -i hello.tar

配置镜像加速器

json 复制代码
{
  "registry-mirrors": ["https://docker.wanpeng.top"]
}
相关推荐
晓柏5 分钟前
OpenEuler 系统安装 docker 和 nvidia-docker
docker
FreeBuf_27 分钟前
新型恶意软件采用独特混淆技术劫持Docker镜像
运维·docker·容器
李菠菜3 小时前
CentOS系统指定版本Docker与Docker-Compose在线安装教程
docker·容器·centos
包达叔3 小时前
dockercompose文件仓库
docker
爱吃龙利鱼4 小时前
rocky9.4部署k8s群集v1.28.2版本(containerd)(纯命令)
云原生·容器·kubernetes
李菠菜7 小时前
Kubernetes上通过Helm部署高可用Redis集群
docker·容器·kubernetes
李菠菜7 小时前
修改KubeSphere外网访问端口
docker·容器·kubernetes
福大大架构师每日一题7 小时前
docker v28.1.1 正式发布!修复关键Bug,网络与安全性再升级
网络·docker·bug
一个小坑货8 小时前
Docker 部署 PostgreSQL 数据库
数据库·docker·postgresql
像风一样自由20208 小时前
FastMCP与FastAPI:构建自定义MCP服务器
服务器·microsoft·fastapi