使用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"]
}
相关推荐
迷茫运维路29 分钟前
docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等)
运维·docker·jenkins·cicd
我叫乐多你养我啊33 分钟前
Windows远程连接Docker服务
笔记·docker
mit6.8244 小时前
[Docker#5] 镜像仓库 | 命令 | 实验:搭建Nginx | 创建私有仓库
linux·后端·docker·云原生
牛右刀薛面4 小时前
麒麟V10,arm64,离线安装docker和docker-compose
运维·docker·容器·麒麟·鲲鹏
杨浦老苏4 小时前
简单安全的密码生成器PSWD
docker·群晖·密码
后端常规开发人员4 小时前
在 Mac 上使用 Docker 安装宝塔并部署 LNMP 环境
macos·docker·容器·宝塔
hshpy4 小时前
Allow two Docker containers to communicate with each other
docker·容器·eureka
Violet_Stray4 小时前
docker里rtsp推流+同一个docker接受流进行部署
运维·docker·容器
好记忆不如烂笔头abc4 小时前
docker:docker: Get https://registry-1.docker.io/v2/: net/http: request canceled
http·docker·容器
杨浦老苏4 小时前
单网页图库应用Single File PHP Gallery
docker·相册·群晖·图库