Docker

核心概念

镜像

类似于虚拟机镜像、或者是面对对象里的”类”。如果一个镜像可以包含一个基本的操作系统环境,里面仅安装Apache,就可以把它称为Apache镜像,镜像是创建 docker 容器的基础。

注意:镜像自身是只读的,容器从镜像启动的时候,会在镜像的最上层创建一个可写层。

容器

类似于一个轻量级的沙箱,或者是面对对象里的 “对象”。 docker 利用容器来运行和隔离应用,容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而且这些容器都是彼此相互隔离的,互不可见的。

可以把容器看作是一个简易版的Linux系统环境,以及运行在其中的应用程序打包而成的盒子。

仓库

类似于代码仓库,它是 docker 集中存放镜像文件的场所,一个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。

例如:存放 ubuntu 镜像的仓库称为 ubuntu 仓库,其中可能包含14.04、12.04等不同版本的镜像。

docker 仓库分为公开仓库和私有仓库,比较出名的公开仓库有: docker Hub、时速云、aliyun 等。

安装及配置

  1. 卸载旧版本 :yum remove docker * ;
  2. 安装 docker :yum -y install docker ,如果提示您接受 GPG 密钥,请选“是” ;
  3. [可选] 配置用户组: docker 安装后自动创建 docker 用户组,我们可以将用户添加到 docker 用户组,可以避免每次都使用 sudo 运行:usermod -aG docker YOUR_NAME ;
  4. [可选] 让 docker 服务可以通过本地 2375 端口接受来自外部的请求:docker _OPTS=”$ docker _OPTS -H tcp://0.0.0.0:2375 -H unix:/// /var/run/ docker .sock” ;
  5. [可选] 然后重启 docker 服务:systemctl restart docker ;
  6. 启动 docker :systemctl start docker ;
  7. 运行 hello-world 镜像来验证是否正确安装 :docker run hello-world ;

基础命令

  • info:显示 docker 系统信息,包括镜像和容器数;

  • version:显示 docker 版本信息;

仓库管理命令

  • login :登陆到一个 docker 镜像仓库,未指定镜像仓库地址,默认为官方仓库 docker Hub ;

    docker login [Options] [SERVER]
    [Options]:
    	-u: 登陆的用户名
        -p: 登陆的密码
  • logout :登出镜像仓库,未指定镜像仓库地址,默认为官方仓库 docker Hub ;

    docker logout [SERVER]
  • pull :从镜像仓库中拉取或者更新指定镜像 ;

    docker pull [Options] NAME[:TAG]
    [Options]:
    	-a: 拉取所有 tagged 镜像
    	--disable-content-trust: 忽略镜像的校验,默认开启
  • push :将本地的镜像上传到镜像仓库 ;

    docker push [Options] NAME[:TAG]
    [Options]:
    	--disable-content-trust: 忽略镜像的校验,默认开启
  • search :从 docker Hub 查找镜像 ;

    docker search [Options] Name
    [Options]:
    	--automated: 只列出 automated build 类型的镜像
    	--no-trunc: 显示完整的镜像描述
    	-s: 列出收藏数不小于指定值的镜像
    	-f:过滤条件?

镜像管理命令

  • images:列出所有本地镜像 ;

    docker images [Options] [REPOSITORY[:TAG]]
    [Options]:
    	-a: 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层)
    	--digests: 显示镜像的摘要信息
    	-f: 显示满足条件的镜像
    	--format: 指定返回值的模板文件
     	--no-trunc: 显示完整的镜像信息
     	-q: 只显示镜像ID
  • rmi : 删除本地一个或多少镜像 ;

    docker rmi [OPTIONS] IMAGE [IMAGE...]
    	-f: 强制删除
    	--no-prune: 不移除该镜像的过程镜像,默认移除
  • tag : 为镜像添加一个标签 ;

    docker tag  IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
  • history:查看指定镜像的创建历史 ;

    docker history [Options] IMAGE
    [Options]:
    	-H: 以可读的格式打印镜像大小和日期,默认为true
    	--no-trunc: 显示完整的提交记录
    	-q: 仅列出提交记录ID
  • save:将指定镜像保存成 tar 归档文件 ;

    docker save [Options] IMAGE [IMAGE...]
    [Options]:
    	-o: 输出到的文件
    # 示例:
    $ docker save centos_test_v3.tar centos:v3
  • load:导入使用 save 命令导出的镜像 ;

    docker load [Options]
    [Options]:
    	--input,-i :指定导入的文件,代替 STDIN
    	--quiet,-q :精简输出信息
    	
    # 示例1:
    $ docker load < busybox.tar.gz
    # Loaded image: busybox:latest
    
    # 示例2:
    $ docker load --input fedora.tar
    # Loaded image: fedora:latest
  • import:导入镜像 ;

    docker  import [Options] file|URL(压缩文件或url) [容器名:标签]
    [Options]:
    	-c: 应用 docker 指令创建镜像
    	-m: 提交时的说明文字
    
    # 示例:
    $ docker import centos_test.tar os/centos_test:v2

容器管理命令

生命周期管理

  • run:根据镜像创建并启动一个容器 ;

    docker run [Options] image-name
    [Options]:
    	-i: 以交互模式运行容器,通常与 -t 同时使用
        -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
        -a: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项
        -d: 后台运行容器,并返回容器ID
        -p: 指定端口映射,格式为:8000:8000
        -m: 设置容器使用内存最大值
        -P: 随机端口映射,容器内部端口随机映射到主机的高端口
        -e username="ritchie": 设置容器的环境变量
        -h "mars": 指定容器的 hostname
        --restart='always': 设置容器自动重启,[no:不重启/on-failure:非0退出时重启]
        --name="nginx-lb":为容器指定一个名称
        --network='bridge':指定容器的网络
        --privileged=True:让容器获取宿主机 root 权限
        --link=[]: 添加链接到另一个容器
        --volume,-v: 绑定一个卷
        --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致
        --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致
        --env-file=[]: 从指定文件读入环境变量
        --cpuset="0,1,2": 绑定容器到指定CPU运行
        --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container
        --expose=[]: 开放一个端口或一组端口
        --rm:退出容器时删除容器
  • create:创建一个新的容器但不启动它 ;

    docker create [Options] IMAGE [COMMAND] [ARG...]
    [Options]: 命令同 run
  • start/stop/restart:启动/停止/重启 一个或多个容器 ;

    docker stop id/name[容器2, ...]
    docker start id/name[容器2, ...]
    docker restart id/name[容器2, ...]
  • pause/unpause :暂停/恢复 一个或多个容器进程 ;

    docker pause id/name[容器2, ...]
    docker unpause id/name[容器2, ...]
  • kill:杀掉一个运行中的容器 ;

    docker kill [Options] id/name
    [Options]:
    	-s :向容器发送一个信号
    	
    # 示例:
    $ docker kill -s KILL mynginx
  • rm:删除容器 ;

    docker rm [Options] id/name[容器2, ...]
    [Options]:
     	-f: 强制删除一个运行中的容器
    	-l: 移除容器间的网络连接,而非容器本身
     	-v: 删除与容器关联的卷
    
    # 示例1:删除所有未运行的容器
    $ docker rm $(docker ps -aq)
    # 示例2:删除所有终止状态的容器
    $ docker container prune

容器操作

  • ps:查看容器 ;

    docker ps [Options]
    [Options]:
    	-a: 显示所有的容器,包括未运行的
    	-q: 只显示容器编号
    	-l: 显示最近创建的容器
    	-n: 列出最近创建的n个容器
    	-s: 显示总的文件大小
    	-f: 根据条件过滤显示的内容
    	--format : 指定返回值的模板文件
    	--no-trunc: 不截断输出
  • exec:进入容器或在运行的容器中执行命令 ;

    docker exec [Options] id/name COMMAND [ARG...]
    [Options]:
    	-d: 后台运行
    	-i: 即使没有附加也保持 STDIN 打开
    	-t: 分配一个伪终端
    
    COMMAND:要在容器中执行的命令
    [ARG...]: 命令的参数
    
    # 示例:
    $ docker exec -it c3c7732da20e /bin/bash
  • top:查看容器中运行的进程信息 ;

    docker top id
  • logs:查看容器日志 ;

    docker logs [Options] id/name
    [Options]:
    	-t: 显示时间戳
    	-f: 跟踪日志输出
    	--tail: 仅列出最新N条容器日志
    	--since: 显示某个开始时间的所有日志
  • inspect: 获取容器/镜像的元数据(配置信息)。

    docker inspect [Options] id/name
    [Options]:
    	-s: 显示总的文件大小
    	-f: 指定返回值的模板文件
    	--type: 指定返回类型 JSON
  • attach:进入容器 ;

    docker attach [Options] id/name
    [Options]:
    	--sig-proxy=false: 退出容器时不停止容器
    	
    注意:使用 attach 进入容器,ctrl + c/d 退出容器时会停止容器,所以需要使用 --sig-proxy=false 参数
  • events: 从服务器获取实时事件 ;

    docker events [Options]
    [Options]:
    	-f:根据条件过滤事件
    	--since:从指定的时间戳后显示所有事件
    	--until:流水时间显示到指定的时间为止
  • wait: 阻塞运行直到容器停止,然后打印出它的退出代码 ;

    docker wait id/name
  • export:导出容器 ;

    docker export [Options] id/name
    [Options]:
    	-o: 将输入内容写到文件
    
    # 示例1:将 id 为 abcdefg 的容器按日期保存为tar文件
    $ docker export -o centos-'date +%Y%m%d'.tar abcdefg 
    # 示例2:将容器 test_centos 导出为 centos_test.tar
    $ docker export test_centos > ./centos_test.tar
  • port:列出指定的容器的端口映射

    docker port id/name
  • rename:重命名一个容器 ;

  • update:更新一个或多个容器的配置 ;

容器rootfs

  • commit:根据容器创建一个新的镜像 ;

    docker commit [Options] id/name 镜像名:标签
    [Options]:
        -a: 提交的镜像作者
        -c: 使用 docker file指令来创建镜像
        -m: 提交时的说明文字
        -p: 在commit时,将容器暂停
  • cp:用于容器与主机之间的数据拷贝 ;

    # 将容器内数据拷贝到外部
    docker cp [Options] id/name:from_path to_host_path
    # 将外部数据拷贝到容器内
    docker cp [Options] from_host_path id/name:to_path
    [Options]:
    	-L: 保持源目标中的链接
  • diff:检查容器里文件结构的更改 ;

    docker diff id/name

网络管理命令

docker network

  • create:创建一个 docker 网络 ;

    docker network create [OPTIONS] net_name
    [OPTIONS]:
    	-d:指定 docker 网络类型,有 bridge、overlay 等类型
  • ls:查看已有的 docker 网络 ;

    docker network ls
    	-q:仅显示网络id
    	-f:过滤条件
    
    # 示例:根据网络类型过滤
    $ docker network ls -f 'driver=bridge'
  • connect:将容器连接到网络 ;

    docker network connect net_name container_id/name
  • disconnect:断开容器与网络的连接 ;

    docker network disconnect [OPTIONS] net_name container_id/name
    [OPTIONS]:
    	-f:强制断开
  • inspect:显示一个或多个网络上的详细信息 ;

    docker network inspect [Options] net_name
    [Options]:
    	-f:用给定的模版格式化输出信息
  • rm:删除1个或多个网络 ;

    docker network rm net_name[net_2, ...]
  • prune:删除所有未使用的网络 ;

    docker network prune [OPTIONS]
    [OPTIONS]:
    	-f:不提示确认

Dockerfile

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

构建命令

  • build:dockerfile 利用 build 命令来构建一个镜像 ;

    docker build [Options] image_name:tag dockerfile_path
    [Options]:
        -c:cpu核心数
        -m:最大内存
        -t:镜像标记
        
    # 注意:存放 dockerfile 的文件夹中不要放无关的文件,因为 docker 会收集 dockerfile工作路径的所有文件用来构建镜像!

语法规则

dockerfile 分为四个部分:基础镜像信息、维护者信息、镜像操作执行、容器启动时执行的指令 ;

  • FROM:指定要引用的基础镜像,先从本地找,找不到再去 docker hub 找 ;

    注意事项:

    • 基础镜像有 tag 一定要带上,否则不识别 ;

    • 任何 dockerfile 的第一条指令必须为 FROM ;

    • 如果在同一个 dockerfile 中创建多个镜像,可以使用多个 FROM 指令;

      FROM centos:7.5.1804
  • RUN:在镜像 build 时执行命令 ;

    注意事项:

    • RUN 指令每执行一次都会在 docker 上新建一层镜像,造成镜像膨胀,所以无必要的话应该用 && 连接多个指令;

      # 使用 RUN 指令有两种方式:
      
      # 1. 默认使用 shell 执行命令,
      RUN <command>
      # 示例1:
      RUN -c  # 等价于 /bin/sh -c
      
      # 2. 推荐用法,采用 exec 的格式执行命令
      RUN ["executable", "param1", "param2"] 
      "executable":可执行文件
      "param1","param2":执行时的参数
      
      # 示例2:
      RUN ["/bin/bash", "-c", "echo hello"]  # RUN /bin/bash -c echo hello
      RUN ["./test.php", "dev", "offline"]  # RUN ./test.php dev offline
      
      # 示例3:使用 && 连接多个命令
      FROM centos
      RUN yum install wget \
          && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
          && tar -xvf redis.tar.gz
  • CMD:类似于 RUN,为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束 ;

    注意事项:

    • 类似于 RUN 指令,但二者运行的时间点不同,CMD 在 docker run 时运行。

    • 每个 dockerfile 只能有 1 个 CMD 指令,如有多个只会执行最后一条,且如用户启动容器时指定了运行的命令,则会覆盖 CMD 的命令;

      # 有三种格式:
      CMD <command>
      CMD ["executable", "param1", "param2"]
      # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
      CMD ["param1", "param2"] 
  • ENTRYPOINT:类似于 CMD 指令,但不会被 docker run 的指定的参数覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序 ;

    注意事项:

    • CMD 指令指定参数将会成为 ENTRYPOINT 指定命令的参数 ;

    • 每个 dockerfile 只能有1个 ENTRYPOINT 指令,当有多个时只有最后一个生效 ;

    • 会被 docker run 时指定的 –entrypoint 参数覆盖 ;

      FROM nginx
      ENTRYPOINT ["nginx", "-c"] # 定参
      CMD ["/etc/nginx/nginx.conf"] # 变参 
      
      # 当不传参启动容器时
      $ docker run nginx:test  
      # 容器内执行
      $ nginx -c /etc/nginx/nginx.conf  
      
      # 当传参启动容器时
      $ docker run nginx:test -c /etc/nginx/new.conf
      # 容器内执行
      $ nginx -c /etc/nginx/new.conf
  • ENV:指定环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量,在此镜像启动的容器中也会存在。

    注意事项:

    • 可以有多个 ENV

    • 该指令指定的环境变量会被启动容器时的 –env 参数覆盖

      ENV <key> <value>
      ENV <key>=<value> <key2>=<value2> ...
  • ARG:构建参数,与 ENV 作用一至,不过作用域不一样,ARG 设置的环境变量仅在 docker build 的过程中有效 ;

    ARG <name> <value>
    ARG <name>=<value>
  • WORKDIR:为后续的 RUN、CMD 和 ENTRYPOINT 指令配置工作目录,可以使用多个指令,后续的指令如果是相对路径,则会基于之前命令指定的路径;

    WORKDIR /path/to/workdir
  • COPY:从宿主机复制数据到容器中 ;

    COPY <src> <dest>
    src: 宿主机源路径
    dest: 容器内目标路径,可以是绝对路径,也可以是工作目录(WORKDIR)的相对路径,如无路径会自动创建
  • ADD:类似 COPY ,不过在源文件为 tar 压缩文件的话,压缩格式为 gzip, bzip2 , xz 的情况下,会自动复制并解压到目标路径 ;如无自动解压的需求,请优先使用 COPY ;

    ADD <src> <dest>
    src: 宿主机源路径
    dest: 容器内目标路径
    
    # 如源文件是 gzip bzip2 xz 格式的压缩文件,ADD 会自动解压

    用法基本与 ADD相同,但是<src>只能是本地主机的路径

  • VOLUME:定义匿名数据卷,在启动容器时忘记挂载数据卷,会自动挂载到匿名卷,避免重要的数据,因容器重启而丢失 ;

    VOLUME ["<路径1>", "<路径2>", ...]
    VOLUME <路径>
    
    # 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
  • EXPOSE:仅仅只是声明容器内服务所监听的端口 ;

    EXPOSE <port1> <port2>
  • USER:用于指定后续执行命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在);

    USER <用户名>[:<用户组>]
    
    # 当服务不需要管理员权限时,可以通过该命令指定运行用户
    RUN groupadd -r postgres && useradd -r -g postgres postgres
  • ONBUILD:配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令 ,可以有多个 ONBUILD 指令 ;

    ONBUILD [instruction]
    # 示例:
    ONBUILD ADD . /app/src
  • STOPSIGNAL:指定镜像构建的容器接收的退出信号的值 ;

    STOPSIGNAL signal
  • HEALTHCHECK:用于指定某个程序或者指令来监控 docker 容器服务的运行状态 ;

    HEALTHCHECK [Options] CMD command:设置检查容器健康状况的命令,根据所执行命令返回值来判断 ;
    [Options]:
     	--interval=DURARION (默认:30s):多久检查一次
     	--timeout=DURARION (默认:30s):每次检查等待结果的超时时间
     	--retries=N (默认:3):如果失败了,重试几次才最终确定失败
    
    # 禁止基础镜像中的健康检查
    HEALTHCHECK NONE
  • SHELL:指定其他命令使用 shell 时默认的 shell 类型,默认值为:[“/bin/sh”, “-c”] ;

    SHELL ["executable", "parameters"]
  • MAINTAINER:指定维护者信息 ;

  • LABEL:用来生成镜像的元数据标签信息,可以有多个 LABEL ;

    LABEL <key> <value>
    LABEL <key>=<value>
    # 示例:
    LABEL version="1.0"

示例

FROM python:3.8-buster

MAINTAINER Chen

ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
ENV TZ Asia/Shanghai

WORKDIR  /app

COPY ./the_first/ /app/the_first/

RUN pip install gunicorn && \
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ -r /app/the_first/requirements.txt

CMD cd ./the_first && \
    python3 manage.py collectstatic --noinput && \
    gunicorn --workers 2  --log-level debug --bind '0.0.0.0:8000'  'the_first.wsgi'

Docker-compose

语法规则

version: '3'

# 创建容器数据卷
volumes:
  # 数据卷名
  static:

# 创建网络
networks:
  # 网络名称
  django_network:
    # 网络模式
    driver: bridge

# 创建加密文件
secrets:
  my_secret:
    file: ./my_secret.txt

services:
  # 定义一个服务名
  the_first_django:
    # 指定构建容器的 Dockerfile 所在的路径
    build:
      # 指定上下文环境,是基于 compose.yml 的相对路径
      context: ./
      # 指定 Dockerfile的路径,是 基于 context 的相对路径
      dockerfile: compose/production/django/Dockerfile
      # 指定构建过程中的环境变量,构建后删除
      args:
        buildno: 1
        password: secret

    # 指定容器运行的镜像,不使用 build
    image: django:latest

    # 指定容器名称
    container_name: the_first

    # 网络模式:bridge|host|none
    # network_mode: "service:[service name]"
    # network_mode: "container:[container name/id]"
    network_mode: "bridge"

    # 加入指定的网络
    networks:
      - django_network

    # 映射端口(宿主机:容器)
    ports:
      - "8000:8000"

    # 暴露端口,但不映射到宿主机,只被连接的服务访问
    expose:
      - '8080'

      # 设置容器自动重启策略
      # no:默认,在任何情况下都不会重启容器。
      # always:总是重新启动
      # on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
      # unless-stopped:总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
    restart: on-failure:3

    # 是否拥有宿主机 root 权限
    privileged: true

    # 添加环境变量
    environment:
      - RACK_ENV: development
      # 布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False
      - SHOW: 'true'

    # 从文件添加环境变量
    env_file:
      - ./common.env

    # 挂载一个目录或者已经存在的数据卷容器
    volumes:
      - static:/app/the_first/static/  # 将该容器的静态文件共享到其他的容器中
      - /opt/data:/var/lib/mysql  # 使用绝对路径挂载数据卷
      # :ro 表示为只读
      - ./configs:/etc/configs/:ro  # 使用以 Compose 配置文件为基本路径的相对路径

    # 容器启动后执行的命令
    # command: /start.sh

    # ENTRYPOINT,覆盖 RUN 命令 和 Dockerfile 中的同名指令
    # entrypoint: /code/entrypoint.sh

    # 容器依赖
    depends_on:
      - mysql-django  # 另外的服务名
      - redis-django

    # 指定设备映射列表
    devices:
      - "/dev/ttyUSB0:/dev/ttyUSB0"

    # 自定义 DNS 服务器
    dns:
      - 8.8.8.8
      - 9.9.9.9

    # 自定义 DNS 搜索域
    dns_search:
      - dc1.example.com
      - dc2.example.com

    # 添加主机名映射,类似 docker client --add-host
    # 会在此服务的内部容器的 /etc/hosts 中创建 IP 和主机名的映射关系
    extra_hosts:
      - "somehost:162.242.195.82"
      - "otherhost:50.31.209.229"

    # 存储敏感数据,例如密码
    secrets:
      - my_secret

    # 在容器内安装一个临时文件系统
    tmpfs:
      - /tmp

    # 用于检测 docker 服务是否健康运行
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost" ] # 设置检测程序
      interval: 1m30s # 设置检测间隔
      timeout: 10s # 设置检测超时时间
      retries: 3 # 设置重试次数
      start_period: 40s # 启动后,多少秒开始启动检测程序

    # 链接到其它服务器中的容器
    links:
      - db
      - db:mysql
      - redis

    # 让 compose 项目里面的容器链接到项目配置外部的容器(外部容器中必须至少有一个容器链接到项目内服务的同一个网络里)
    external_links:
      - redis_1
      - project_db_1:mysql
      - project_db_1:postgresql

    # 服务的日志记录配置
    logging:
      # 指定服务容器的日志记录驱动程序: json-file/syslog/none
      driver: json-file
      options:
        # 当 driver: syslog 时
        # syslog-address: "tcp://ip"  # 指定日志接收地址

        # 当 driver: json-file 时
        max-size: "200k"  # 单个文件大小为 200 k
        max-file: "10"  # 最多10个文件

  # 被依赖的服务
  redis-django:
    image: redis

  mysql-django:
    image: mysql

常用命令

# -f  指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。
docker-compose -f docker-compose.yml up -d

# 启动所有容器,-d 将会在后台启动并运行所有的容器
docker-compose up -d

# 停用移除所有容器以及网络相关
docker-compose down

# 查看服务容器的输出
docker-compose logs

# 列出项目中目前的所有容器
docker-compose ps

# 构建(重新构建)项目中的服务容器。服务容器一旦构建后,将会带上一个标记名,例如对于 web 项目中的一个 db 容器,可能是 web_db。可以随时在项目目录下运行 docker-compose build 来重新构建服务
docker-compose build

# 拉取服务依赖的镜像
docker-compose pull

# 重启项目中的服务
docker-compose restart

# 删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop 命令来停止容器。
docker-compose rm

# 在指定服务上执行一个命令。
docker-compose run ubuntu ping docker.com

# 设置指定服务运行的容器个数。通过 service=num 的参数来设置数量
docker-compose scale web=3 db=2

# 启动已经存在的服务容器。
docker-compose start

# 停止已经处于运行状态的容器,但不删除它。通过 docker-compose start 可以再次启动这些容器。
docker-compose stop

示例

version: '3'

volumes:
  static:
  media:

networks:
  django_network:
    driver: bridge

services:

  # mysql 服务
  mysql-django:
    image: mysql:latest
    container_name: mysql-django
    networks:
      - django_network
    ports:
      - 13306:3306
    restart: always
    privileged: true
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: mysql13306123456
      MYSQL_DATABASE: the_first
    volumes:
      - /usr/local/workspace/mysql/data/:/var/lib/mysql/
    command:
      # MySQL8.0 之后,默认的加密规则使用的是 caching_sha2_password
      # 客户端工具不支持,所以不要修改其加密规则
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci

  # redis 服务
  redis-django:
    image: redis:latest
    container_name: redis-django
    networks:
      - django_network
    ports:
      - 16379:6379
    restart: always
    privileged: true
    environment:
      TZ: Asia/Shanghai
    # 容器启动后,启动根据配置文件启动 redis-server
    command: redis-server /etc/redis/redis.conf --appendonly yes --requirepass 'redis16379123456'
    volumes:
      - /usr/local/workspace/redis/data:/data/
      - /usr/local/workspace/redis/redis.conf:/etc/redis/redis.conf/

  # django 服务
  the_first:
    image: the_first:latest
    container_name: the_first
    networks:
      - django_network
    expose:
      - '8000'
    restart: always
    privileged: true
    environment:
      TZ: Asia/Shanghai
    volumes:
      - static:/app/the_first/static/  # 将该容器的静态文件共享到其他的容器中
      - media:/app/the_first/media/
    depends_on:
      - mysql-django
      - redis-django

  # nginx 服务
  nginx-django:
    image: nginx:latest
    container_name: nginx-django
    networks:
      - django_network
    ports:
      - 80:80
      - 443:443
    restart: always
    privileged: true
    environment:
      TZ: Asia/Shanghai
    volumes:
      # 与 django 服务共享 static media 目录
      - static:/app/the_first/static/
      - media:/app/the_first/media/
      - /usr/local/workspace/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - /usr/local/workspace/nginx/conf.d:/etc/nginx/conf.d
      - /usr/local/workspace/nginx/html:/usr/share/nginx/html
      - /usr/local/workspace/nginx/log:/var/log/nginx
    depends_on:
      - the_first

Docker 命令快捷栏

  • 设置 docker 开机自动启动(服务器重启后自动重启)

    $ systemctl enable docker
  • 进去容器内部

    $ docker exec -it 容器id/name /bin/bash
  • 启动一个 redis 容器

    $ docker run -itd -p 16379:6379 --name='redis-django' --network='bridge' --restart='always' \
    -v /usr/local/workspace/redis/data:/data \
    -v /usr/local/workspace/redis/redis.conf:/etc/redis/redis.conf \
    redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass 'redis16379123456'
    
    # 参数解释:
    # 挂载数据卷和配置文件
    -v /usr/local/workspace/redis/data:/data
    -v /usr/local/workspace/redis/redis.conf:/etc/redis/redis.conf
    # 使用配置文件启动
    /etc/redis/redis.conf
    --appendonly yes: 开启持久化
    --requirepass 'redis16379123456': 设置密码
  • 启动一个 mysql 容器

    $ docker run -itd -p 13306:3306 --name='mysql-django' --network='bridge' --restart='always' -e MYSQL_ROOT_PASSWORD=mysql13306123456 \
    -v /usr/local/workspace/mysql/data:/var/lib/mysql \
    mysql:latest
    
    # 参数解释:
    # 挂载数据卷和配置文件
    -v /usr/local/workspace/mysql/data:/var/lib/mysql
    -v /usr/local/workspace/mysql/etc:/etc/mysql
    -e: 为容器设置环境变量,为 mysql 初始密码
  • 启动一个 rabbitmq 容器

    $ docker run -itd  -p 5672:5672 --name='rabbitmq-django' --network='bridge' --restart='always' rabbitmq:latest
    
    # 端口参数解释:
    5672、5671: AMQP 0-9-1 without and with TLSclient 端通信口
    15671: 管理监听端口
    15672: 管理界面ui使用的端口
    25672: (Erlang distribution)server 间内部通信口
    4369: (epmd)epmd代表 Erlang 端口映射守护进程,erlang 发现口
  • 启动一个 nginx 容器

        $ docker run -itd -p 80:80 --name='nginx-django' --network='bridge' --restart='always' \
        -v /usr/local/workspace/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
    -v /usr/local/workspace/nginx/conf.d:/etc/nginx/conf.d \
        -v /usr/local/workspace/nginx/html:/usr/share/nginx/html \
        -v /usr/local/workspace/nginx/log:/var/log/nginx \
        nginx
        
        # 参数解释:
        # 将宿主机 workspace/nginx/ 下的配置文件、日志、html 文件挂载到 Nginx 容器中
        -v /usr/local/workspace/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
        -v /usr/local/workspace/nginx/conf.d:/etc/nginx/conf.d
        -v /usr/local/workspace/nginx/html:/usr/share/nginx/html
        -v /usr/local/workspace/nginx/log:/var/log/nginx
  • 启动一个 Django 项目

    $ docker run -itd -p 8000:8000 --name='django' --network='bridge' --restart='always' django