Docker笔记

前言

本文主要参考教程 Runoob的Docker教程,感谢您抽出宝贵的时间阅读!欢迎批评指正!

Docker


Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。

Docker 架构的工作流程

  • 构建镜像:使用 Dockerfile 创建镜像。
  • 推送镜像到注册表:将镜像上传到 Docker Hub 或私有注册表中。
  • 拉取镜像:通过 docker pull 从注册表中拉取镜像。
  • 运行容器:使用镜像创建并启动容器。
  • 管理容器:使用 Docker 客户端命令管理正在运行的容器(例如查看日志、停止容器、查看资源使用情况等)。
  • 网络与存储:容器之间通过 Docker 网络连接,数据通过 Docker 卷或绑定挂载进行持久化。

Docker命令

Dockers帮助命令:

  • docker 具体命令 --help

Docker容器命令:

  • docker run [-d(后台启动),-i 交互模式启动 ,-t 启动终端 ,--name 指定容器名字 可以组合比如 -it -itd] 镜像名和标签 [启动命令,一般镜像默认输入的启动命令是 /bin/bash,你在这里可以改成别的比如/bin/sh]

    一些知识补充:

    当你使用 docker run -t myimage 启动容器时,并不一定需要在命令的末尾指定 /bin/bash 或其他 shell 的路径。是否需要指定取决于你希望容器启动后执行的具体命令或应用。

    • 镜像自带的默认命令:

      • 许多 Docker 镜像(如 ubuntu, alpine, nginx 等)在 Dockerfile 中定义了默认的 CMD 或 ENTRYPOINT。如果你不指定额外的命令,容器将运行这些默认命令。
        例如,ubuntu 镜像的默认 CMD 可能是 /bin/bash,但如果没有交互式终端(即没有 -i 或 -t),它可能不会启动交互式 shell。
        nginx 镜像的默认 CMD 可能是启动 nginx 服务。
    • 交互式 shell:

      • 如果你希望启动一个交互式的 shell(例如 /bin/bash 或 /bin/sh),你需要明确指定它,特别是当你需要与容器进行交互时。

    另一些知识补充:
    POSIX 标准:

    • 短选项:单个字母选项前缀为单个连字符 -,例如 -a、-b。
    • 长选项:多字符选项前缀为双连字符 --,例如 --verbose、--help。
    • POSIX(Portable Operating System Interface)标准定义了操作系统接口和环境,旨在提高不同操作系统之间的兼容性。虽然 POSIX 主要针对操作系统层面的标准,但其对命令行工具的设计也产生了深远影响。
  • docker ps(process status) 查看运行中的容器

  • docker ps -a/ docker ps -all 查看所有容器(包括已停止的那些)

  • docker stop <容器id(任意长度) | 容器名称> 停止容器

  • docker start <容器id(任意长度) | 容器名称> 启动容器

  • docker restart <容器id(任意长度) | 容器名称> 重启容器等价于 stop+start

  • docker logs <容器id(任意长度) | 容器名称> 查看容器内的日志

  • docker rm -f <容器id(任意长度) | 容器名称> 强制删除容器(包括正在运行的容器)

  • docker rm <容器id(任意长度) | 容器名称> 删除容器(运行中的不行)

  • docker container prune 删除全部停止的容器

  • docker export <容器id(任意长度) | 容器名称> > 容器快照名 重要,将容器导出成快照

  • docker import < URL | 本地容器快照目录> 新镜像名:标签 重要, 从容器快照创建镜像

Docker镜像命令

  • docker images 查看所有镜像

  • docker pull 镜像名称:标签 拉取镜像

  • dockers rmi <镜像id(任意长度) | 镜像名称:标签> 删除指定镜像

  • docker commit [-m 提交的描述信息 -a指定镜像作者] <容器id(任意长度) | 容器名称> 新镜像名:标签 重要,从容器直接创建镜像

  • docker build [-t :指定要创建的目标镜像名] <Dockerfile 所在目录的路径|远程 Dockerfile 的 URL |从标准输入读取 Dockerfile> 非常重要,运行这个之前要先写好Dockerfile

    创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。

    runoob@runoob:~$ cat Dockerfile 
    FROM    centos:6.7
    MAINTAINER      Fisher "fisher@sudops.com"
    
    RUN     /bin/echo 'root:123456' |chpasswd
    RUN     useradd runoob
    RUN     /bin/echo 'runoob:123456' |chpasswd
    RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
    EXPOSE  22
    EXPOSE  80
    CMD     /usr/sbin/sshd -D
    

    每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。

    第一条FROM,指定使用哪个镜像源

    RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。

    然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。

  • docker tag <镜像id(任意长度) | 镜像名称:标签> 新镜像名称:新标签 给镜像加一个新标签(其实也可以改新镜像名称)

Docker 容器连接

  • 容器和宿主机之间连接

    • docker run -d -p 127.0.0.1:5001:5000/udp 镜像名:标签 执行的启动命令

      这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。

      默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp

    • docker port <容器id(任意长度) | 容器名称> 5000 docker port 命令可以让我们快捷地查看端口的绑定情况。

  • 容器互联

    • docker network create -d bridge 网络名 新建容器网络

    docker run -itd --name test1 --network 网络名 ubuntu /bin/bash

    docker run -itd --name test2 --network 网络名 ubuntu /bin/bash

    可以进入一个容器去ping另一个来验证是否联通

    • 如果想在指定的容器设置 DNS,则可以使用以下命令:

      $ docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu
      

      参数说明:

      --rm:容器退出时自动清理容器内部的文件系统。

      -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。

      --dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。

      --dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。

Docker仓库管理

  • 登录

登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。

$ docker login

img

  • 退出

退出 docker hub 可以使用以下命令:

$ docker logout
  • 拉取镜像

你可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。

以 ubuntu 为关键词进行搜索:

$ docker search ubuntu

img

使用 docker pull 将官方 ubuntu 镜像下载到本地:

$ docker pull ubuntu 

img

  • 推送镜像

用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。

以下命令中的 username 请替换为你的 Docker 账号用户名。

$ docker tag ubuntu:18.04 username/ubuntu:18.04
$ docker image ls

REPOSITORY      TAG        IMAGE ID            CREATED           ...  
ubuntu          18.04      275d79972a86        6 days ago        ...  
username/ubuntu 18.04      275d79972a86        6 days ago        ...  
$ docker push username/ubuntu:18.04
$ docker search username/ubuntu

NAME             DESCRIPTION       STARS         OFFICIAL    AUTOMATED
username/ubuntu

Docker清理命令

  • 清理悬空的镜像:docker image prune
  • 清理所有未使用的镜像:docker image prune -a
  • 清理停止的容器:docker container prune
  • 清理未使用的网络:docker network prune
  • 清理未使用的卷:docker volume prune
  • 清理所有未使用的资源:docker system prune
  • 清理所有未使用的资源(包括镜像和卷):docker system prune -a --volumes

Dockerfile


什么是 Dockerfile?

Dockerfile 是一个文本文件,包含了构建 Docker 镜像的所有指令。

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

通过定义一系列命令和参数,Dockerfile 指导 Docker 构建一个自定义的镜像。

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum -y install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

使用 Dockerfile 指令

Dockerfile 指令都要大写!

指令详解

Dockerfile 指令 说明
FROM 指定基础镜像,用于后续的指令构建。
RUN 在构建过程中在镜像中执行命令。
LABEL 添加镜像的元数据,使用键值对的形式。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
EXPOSE 声明容器运行时监听的特定网络端口。
ENV 在容器内部设置环境变量。
ADD 将文件、目录或远程URL复制到镜像中。
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令。
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
  • FROM

    • 指定基础镜像,用于后续的指令构建。
    • 例如 FROM nginx 这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx
  • RUN

    • 用于执行后面跟着的命令行命令。有以下俩种格式:

      shell 格式:

      RUN <命令行命令>
      # <命令行命令> 等同于,在终端操作的 shell 命令。
      

      exec 格式:

      RUN ["可执行文件", "参数1", "参数2"]
      # 例如:
      # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
      

      注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

  • COPY

    复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

    格式:

    COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
    COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]
    

    [--chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

    <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

    COPY hom* /mydir/
    COPY hom?.txt /mydir/
    

    <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

  • ADD

    ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

    • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
    • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
  • CMD

    类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

    • CMD 在docker run 时运行。
    • RUN 是在 docker build。

    作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

    注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

    格式:

    CMD <shell 命令> 
    CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
    CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
    

    推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

  • ENTRYPOINT

    类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

    但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

    优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

    注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

    格式:

    ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
    

    可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。

    示例:

    假设已通过 Dockerfile 构建了 nginx:test 镜像:

    FROM nginx
    
    ENTRYPOINT ["nginx", "-c"] # 定参
    CMD ["/etc/nginx/nginx.conf"] # 变参 
    

    1、不传参运行

    $ docker run  nginx:test
    

    容器内会默认运行以下命令,启动主进程。

    nginx -c /etc/nginx/nginx.conf
    

    2、传参运行

    $ docker run  nginx:test -c /etc/nginx/new.conf
    

    容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

    nginx -c /etc/nginx/new.conf
    
  • ENV

    设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

    格式:

    ENV <key> <value>
    ENV <key1>=<value1> <key2>=<value2>...
    

    以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

    ENV NODE_VERSION 7.2.0
    
    RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
      && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
    
  • ARG

    构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

    构建命令 docker build 中可以用 --build -arg <参数名>=<值> 来覆盖。

    格式:

    ARG <参数名>[=<默认值>]
    
  • VOLUME

    定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

    作用:

    • 避免重要的数据,因容器重启而丢失,这是非常致命的。
    • 避免容器不断变大。

    格式:

    VOLUME ["<路径1>", "<路径2>"...]
    VOLUME <路径>
    

    在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

    那么如何找到匿名卷并进行管理?

    • 查找和管理匿名卷:你可以通过运行 docker volume ls 命令查看所有已创建的数据卷,包括匿名卷。虽然匿名卷的名字不直观,但你仍然可以通过这个命令找到它们,并根据需要备份或迁移数据。
    • 迁移数据:如果之后你想将数据从匿名卷迁移到命名卷或者宿主机上的某个目录,可以先停止相关容器,然后使用 docker cp 或者 docker run --volumes-from 等命令来复制数据。
    • 重新挂载:为了长期维护方便,建议重新启动容器时,通过 -v 参数明确指定宿主机上的目录作为数据卷的挂载点,这样不仅便于管理,也利于数据的持久化存储和备份。

    例如,假设你有一个容器使用了一个匿名数据卷 /data,后来决定将其迁移到宿主机上的 /my/local/data 目录下,可以这样做:

    # 创建一个新的容器,挂载本地目录
    docker run -v /my/local/data:/data my_image
    # 或者,如果你只是想备份数据
    docker run --rm --volumes-from old_container -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /data
    
  • EXPOSE

    仅仅只是声明端口。

    作用:

    • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
    • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

    格式:

    EXPOSE <端口1> [<端口2>...]
    
  • WORKDIR

    ​ WORKDIR 是 Dockerfile 中的一个指令,用于设置工作目录。这个指令定义了后续指令(如 RUN、CMD、ENTRYPOINT、COPY 和 ADD)的默认目录。每次使用 WORKDIR 指令时,都会改变 Docker 构建上下文中的当前工作目录,并且如果指定的目录不存在,Docker 会自动创建它。

    作用

    • 设定默认目录:为后续的所有指令设定一个默认的工作目录。
    • 保持一致性:确保所有后续指令都在同一个目录中执行,从而避免路径相关的问题。
    • 自动创建目录:如果指定的目录在镜像中不存在,Docker 会自动创建它,无需显式地使用 RUN mkdir 命令。

    格式:

    WORKDIR <工作目录路径>
    

    使用示例

    假设我们要构建一个基于 Node.js 的应用程序镜像,并希望将工作目录设置为 /app,以便所有操作都在该目录下进行。以下是一个典型的 Dockerfile 示例:

    # 使用官方 Node.js 镜像作为基础镜像
    FROM node:14
    
    # 设置工作目录为 /app
    WORKDIR /app
    
    # 将 package.json 和 package-lock.json 复制到工作目录
    COPY package*.json ./
    
    # 在工作目录中安装依赖
    RUN npm install
    
    # 将应用代码复制到工作目录
    COPY . .
    
    # 暴露应用运行所需的端口
    EXPOSE 3000
    
    # 启动应用
    CMD ["npm", "start"]
    

    详细说明

    • 设置工作目录:

      WORKDIR /app
      

      这行命令将当前工作目录设置为 /app。如果这个目录不存在,Docker 会自动创建它。

    • 复制文件:

      COPY package*.json ./
      

      这行命令将主机上的 package.json 和 package-lock.json 文件复制到容器的当前工作目录 /app 下。

    • 安装依赖:

      RUN npm install
      

      这行命令会在 /app 目录下执行 npm install,从而安装项目所需的所有依赖包。

    • 复制应用代码:

      COPY . .
      

      这行命令将主机上的所有文件复制到容器的 /app 目录下。

    • 暴露端口和启动应用:

      EXPOSE 3000
      CMD ["npm", "start"]
      

      这些指令分别指定了容器运行时监听的端口(3000),并设置了启动命令为 npm start,这样当容器启动时,Node.js 应用就会开始运行。

    注意事项

    • 多层结构:每个 RUN 指令都会创建一个新的层(layer),但 WORKDIR 只是改变了当前的工作目录,并不会创建新的层。因此,无论你使用多少次 WORKDIR,它都不会增加镜像的层数。

    • 相对路径与绝对路径:WORKDIR 接受绝对路径或相对路径。如果提供的是相对路径,则它是相对于前一个 WORKDIR 指令的路径。例如:

      WORKDIR /app
      WORKDIR src
      WORKDIR static
      

      最终的工作目录将是 /app/src/static

      最佳实践:建议尽早使用 WORKDIR 来设定工作目录,以避免后续指令需要处理复杂的路径问题。同时,尽量减少路径嵌套层级,以简化管理和维护。

  • USER

    用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

    格式:

    USER <用户名>[:<用户组>]
    

    示例

    假设你有一个需要以特定用户运行的服务:

    FROM ubuntu:latest
    
    # 创建一个新用户 'myuser' 并设置密码
    RUN useradd -m myuser
    
    # 切换到 'myuser' 用户
    USER myuser
    
    # 后续的所有命令都将作为 'myuser' 用户执行
    CMD ["echo", "Running as myuser"]
    
  • HEALTHCHECK

    用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

    格式:

    HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
    HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
    
    HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
    
  • ONBUILD

    用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

    格式:

    ONBUILD <其它指令>
    
  • LABEL

    LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:

    LABEL <key>=<value> <key>=<value> <key>=<value> ...
    

    比如我们可以添加镜像的作者:

    LABEL org.opencontainers.image.authors="runoob"
    

Docker Compose


Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

Compose 使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

Compose 安装:

  • linux需要单独装

  • Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序

具体使用例子

1. 准备

创建一个测试目录:

$ mkdir composetest
$ cd composetest

在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)


@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

在此示例中,redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379。

在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:

flask
redis

2. 创建 Dockerfile 文件

在 composetest 目录中,创建一个名为 Dockerfile 的文件,内容如下:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]

Dockerfile 内容解释:

  • FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。

  • WORKDIR /code: 将工作目录设置为 /code。

  • ENV FLASK_APP app.py
    ENV FLASK_RUN_HOST 0.0.0.0
    

    设置 flask 命令使用的环境变量。

  • RUN apk add --no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。

  • COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    

    复制 requirements.txt 并安装 Python 依赖项。

  • COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。

  • CMD ["flask", "run"]: 容器提供默认的执行命令为:flask run。

3. 创建 docker-compose.yml

在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:

# yaml 配置
version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

该 Compose 文件定义了两个服务:web 和 redis。

  • web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
  • redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。

4. 使用 Compose 命令构建和运行您的应用

在测试目录中,执行以下命令来启动应用程序:

docker-compose up

如果你想在后台执行该服务可以加上 -d 参数:

docker-compose up -d

停止并移除所有资源:使用 docker compose down

docker compose down

仅停止容器:使用 docker compose stop

docker compose stop

停止特定容器:使用 docker stop 并提供容器名称或 ID。

docker stop <container_name_or_id>

移除已停止的容器:使用 docker compose rm

docker compose rm
posted @ 2025-03-06 15:03  玉米面手雷王  阅读(26)  评论(0)    收藏  举报