docker学习笔记 2021年01月12日 未雨晴空 0评论 76阅读 0喜欢 阅读模式 隐藏边栏 显示边栏 # 什么是Docker * [Docker](https://docs.docker.com)是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。 * Docker 属于**Linux 容器**的一种封装,提供简单易用的容器使用接口。 * Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。 * 用户可以通过docker命令来创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。 # linux下安装Docker 关于docker的安装,[docker官方文档](https://docs.docker.com/get-docker/)介绍了如何在linux系统和window系统下的安装方式 ## 开发环境下安装 Docker在[get.docker.com](https://get.docker.com/) 和[test.docker.com上](https://test.docker.com/)提供了方便脚本,用于将Docker Engine-Community的边缘版本和测试版本快速且非交互地安装到开发环境中。 **不建议在生产环境中使用这些脚本**,由于脚本需要运行`root`或具有`sudo`特权。因此,在运行脚本之前,应仔细检查和审核脚本。 ```bash # 获取一键安装脚本 $ curl -fsSL https://get.docker.com -o get-docker.sh # 执行脚本 $ sudo sh get-docker.sh # 查看docker的版本号 $ docker version # 或者 $ docker info # service命令启动docker $ sudo service docker start # systemctl命令启动docker $ sudo systemctl start docker ``` ## 生产环境下安装(略) # docker配置镜像加速 阿里云提供了docker配置加速器,也给出了配置方法  ```bash $ sudo mkdir -p /etc/docker $ sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"] } EOF $ sudo systemctl daemon-reload $ sudo systemctl restart docker # 检查加速器是否生效 $ docker info Registry Mirrors: https://xxxxx.mirror.aliyuncs.com/ ``` # docker镜像 **image 文件生成的容器实例,本身也是一个文件,称为容器文件。**也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。 ## 列出镜像 ```bash $ docker image ls 或 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ``` TAG相当于某一个镜像仓库的多个版本号,使用 **REPOSITORY:TAG** 来定义不同版本的镜像。 | 选项 | 解释 | | :--------: | :----------: | | REPOSITORy | 镜像仓库 | | TAG | 镜像标签 | | IMAGE ID | 镜像ID | | CREATED | 镜像创建时间 | | SIZE | 镜像大小 | ## 查找镜像 ```bash $ docker search redis ```  | 选项 | 解释 | | :---------: | :----------------: | | NAME | 名称 | | DESCRIPTION | 描述 | | OFFICIAL | 是否docker官方发布 | | stars | 点赞数 | | AUTOMATED | 自动构建 | ## 拉取镜像 ```bash $ docker image pull library/hello-world 或者 $ docker image pull [imageName] ``` 上面的`library/hello-world`是image(镜像)文件在仓库里面的位置,其中`library`是image(镜像)文件所在的组,`hello-world`是image(镜像)文件的名字。由于 Docker 官方提供的image(镜像)文件,都放在[`library`](https://hub.docker.com/r/library/)组里面,所以它的是默认组,可以省略。 ## 删除镜像 ```bash $ docker rmi [imageName] 或 $ docker image rm [imageName] ``` ## 更新镜像 更新镜像之前,我们需要使用某个镜像来创建一个容器。然后对容器里面的东西进行更新,完成更新操作后,获取到更新后的容器id来提交容器。 ```bash $ docker commit -m="update xxxx" -a="jack" <容器id> <组>/<仓库名>:<标签> ``` | 参数 | 解释 | | :--: | :------------: | | -m | 提交的描述信息 | | -a | 镜像作者 | ## 设置镜像标签 下面的860c279d2fec是镜像ID ```bash $ docker tag 860c279d2fec runoob/centos:dev ``` ## 构建镜像 ### 编辑Dockerfile ```bash $ touch Dockerfile FROM centos:6.7 MAINTAINER admin "admin@admin.com" RUN useradd jack RUN /bin/echo 'jack:123456' |chpasswd RUN /bin/echo "hello world!" > /home/a.txt ``` ### build Dockerfile ```bash $ docker build -t runoob/centos:6.7 . ``` | 参数 | 解释 | | :--: | :----------------------------------------------------------: | | t | 新的镜像的信息<组>/<仓库名>:<标签> | | . | ".”是 Dockerfile所在的路径(当前目录),也可以替换为一个具体的 Dockerfile 的路径。 | 执行完结果如下图:  ### 查看构建好的镜像 ```bash $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE tyb/centos 6.7 b9a85a758e21 38 seconds ago 191MB ``` ### 利用新构建的镜像来启动容器 执行下面的命令会进入当前容器,在这个容器里面可以进行简单的测试查看上面的命令是否执行成功了,如我们的命令里面的新增linux用户命令和在 `/home/a.txt`写入内容命令。 ```bash # 启动容器 $ docker run -it tyb/centos:6.7 /bin/bash ``` # docker容器 ### 运行容器 使用 ubuntu 镜像启动一个只在后台运行的容器 ```bash $ docker run -itd --name myubuntu --network test-net ubuntu:15.10 /bin/bash ``` | 参数 | 解释 | | :------------------------------------- | :----------------------------------------------------------- | | ubuntu:15.10 | 镜像+版本号 | | /bin/bash | 命令 | | -i,--interactive=true | 打开交互式操作界面 | | -t,--tty=false | 分配tty设备,该可以支持终端登录,默认为false | | -d,--detach=false | 指定容器是否后台运行,默认false | | -u, --user="" | 指定容器的用户 | | -w, --workdir="" | 指定容器的工作目录 | | -P,--publish-all=false | 将容器内部使用的网络端口随机映射到主机上。 | | -p,--publish=[p 宿主机端口:容器端口]] | 将容器内部指定端口绑定到指定的主机端口。 | | --name="" | 指定容器名字,后续可以通过名字进行容器管理 | | -h,--hostname="" | 设置容器的主机名, 默认随机生成 | | --dns 8.8.8.8 | 指定容器使用的DNS服务器, 默认和宿主一致 | | -e,--env=[] | 指定环境变量,容器中可以使用该环境变量 | | -a, --attach=[] | 登录容器(必须是以docker run -d启动的容器) | | --net bridge | 指定容器的网络连接类型, 支持 bridge / host / none / container 四种类型 | | --ip 172.18.0.13 | 为容器分配固定ip(需要使用自定义网络) | | --expose=[] | 指定容器暴露的端口,即修改镜像的暴露端口 | | --cap-add=[] | 添加权限 | | --cap-drop=[] | 删除权限 | | --cidfile="" | 运行容器后,在指定文件中写入容器PID值 | | -v,--volume=[] | [宿主机目录路径]:[容器内目录路径] | | --add-host [主机名]:[ip] | 为容器hosts文件追加host, 默认会在hosts文件最后追加 [主机名]:[容器ip] | | --volumes-from [其他容器名] | 将其他容器的数据卷添加到此容器 | | --env-file=[] | 指定环境变量文件,文件格式为每行一个环境变量 | | --link [其他容器名]:[在该容器中的别名] | 添加链接到另一个容器, 在本容器hosts文件中加入关联容器的记录, 效果类似于 --add-host | | -c, --cpu-shares=0 | 设置容器CPU权重,在CPU共享场景使用 | | -m, --memory="" | 指定容器的内存上限 | | --cpuset="0,1,2" | 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU | | --device=[] | 添加主机设备给容器 | | --dns=[] | 指定容器使用的DNS服务器, 默认和宿主一致 | | --dns-search=[] | 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件 | | --entrypoint="" | 覆盖image的入口点 | | -lxc-conf=[] | 指定容器的配置文件,只有在指定--exec-driver=lxc时使用 | | --privileged=false | 指定容器是否为特权容器,特权容器拥有所有的capabilitie | | --restart="no" | 指定容器停止后的重启策略 | | --rm=false | 指定容器停止后自动删除容器(不支持以docker run -d启动的容器) | | --sig-proxy=true | 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理 | `docker run`命令会从image(镜像)文件,生成一个正在运行的容器实例。需要注意的是`docker container run`命令具有自动抓取 image(镜像)文件的功能。如果发现本地没有指定的image(镜像)文件,就会从仓库自动抓取。所以有的时候`docker image pull`命令并不是必需的步骤。 ### 查看容器 ```bash # 查看正在运行的容器 $ docker ps # 查看所有的容器 $ docker ps -a # 查询最后一次创建的容器 $ docker ps -l # 检查容器 $ docker inspect d27bd3008ad9 # 查看容器进程 $ docker top d27bd3008ad9 # 查看容器运行日志 $ docker logs -f bf08b7f2cd89 # 查看容器端口映射 $ docker port bf08b7f2cd89 5000/tcp -> 0.0.0.0:5000 ``` ### 启动容器 下面的字符串为容器ID ```bash $ docker start d27bd3008ad9 ``` ### 进入容器 一般是进入后台运行的容器,使用 `docker exec` 命令相较于`docker attach`是当使用 `docker exec` 退出容器终端,不会导致容器的停止。下面的字符串为容器ID。 ```bash $ docker attach -it d27bd3008ad9 /bin/bash $ docker exec -it d27bd3008ad9 /bin/bash ``` ### 停止容器 下面的字符串为容器ID。 ```bash # 停止指定容器 $ docker stop d27bd3008ad9 # 停用全部运行中的容器 $ docker stop $(docker ps -q) # 停用并删除容器 $ docker stop $(docker ps -q) & docker rm $(docker ps -aq) ``` ### 导出容器 下面的字符串为容器ID。 ```bash $ docker export d27bd3008ad9 > xxxx.tar ``` ### 导入容器 ```bash $ docker import http://example.com/exampleimage.tgz example/imagerepo 或 $ cat docker/xxxx.tar | docker import - test/ubuntu:v1 ``` ### 删除容器 下面的字符串为容器ID。 ```bash # 删除指定的容器 $ docker rm -f d27bd3008ad9 # 删除全部容器 $ docker rm $(docker ps -aq) ``` # docker网络 [关于docker网络](https://www.jianshu.com/p/22a7032bb7bd) # docker容器连接 ## 容器连接主机 ```bash # 容器内部端口随机映射到主机的高端口 $ docker run -d -P training/webapp python app.py $ docker ps CONTAINER ID IMAGE PORTS NAMES f119bb4dd69a training/webapp ... 0.0.0.0:49154->5000/tcp nice_diffie # 指定容器的5000端口绑定到主机的网络地址为127.0.0.1:5001 $ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py $ docker ps CONTAINER ID IMAGE PORTS NAMES 51d50a2cc8eb training/webapp ... 127.0.0.1:5001->5000/tcp exciting_morse # 指定容器的5000/udp端口绑定到主机的网络地址为127.0.0.1:5001 $ docker run -d -p 127.0.0.1:5001:5000/udp training/webapp python app.py $ docker ps CONTAINER ID IMAGE PORTS NAMES 3283840f7975 training/webapp ... 5000/tcp, 127.0.0.1:5001->5000/udp beautiful_davinci # docker port 命令查看容器端口的绑定信息 ~$ docker port 3283840f7975 5000 5000/udp -> 127.0.0.1:5001 ``` - **-P :**是容器内部端口**随机**映射到主机的高端口。 - **-p :** 是容器内部端口绑定到**指定**的主机端口。 - PORTS下的内容格式`主机端口->容器端口` ## 容器连接容器 ```bash # 新建网络 $ docker network create -d bridge test-net # 运行test-net网络下的ubuntu-A容器 $ docker run -itd --name ubuntu-A --network test-net ubuntu:15.10 /bin/bash # 运行test-net网络下的ubuntu-B容器 $ docker run -itd --name ubuntu-B --network test-net ubuntu:15.10 /bin/bash # 进入ubuntu-A容器 $ docker exec -it ubuntu-A /bin/bash $ apt-get update $ apt install iputils-ping $ ping ubuntu-B PING ubuntu-B (172.18.0.3) 56(84) bytes of data. 64 bytes from ubuntu-B.test-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.072 ms 64 bytes from ubuntu-B.test-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.058 ms ... # 进入ubuntu-B容器 $ docker exec -it ubuntu-B /bin/bash $ apt-get update $ apt install iputils-ping $ ping ubuntu-A PING ubuntu-A (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.063 ms 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.070 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.071 ms 64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.071 ms ... ``` # Dockerfile Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。 ### COPY 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。 **语法** ```bash COPY [--chown=:] <源路径1>... <目标路径> COPY [--chown=:] ["<源路径1>",... "<目标路径>"] ``` | 参数 | 解释 | | :----------------------- | ------------------------------------------------------------ | | [--chown=:] | 可选参数,用户改变复制到容器内文件的拥有者和属组。 | | **<源路径>** | 源文件或者源目录,这里可以是通配符表达式, | | <目标路径> | 容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。 | **demo** ```bash COPY hom* /mydir/ COPY hom?.txt /mydir/ ``` ### ADD ADD 指令和 COPY 的使用方法差不多,主要有下面几点不同之处: - ADD 的优点:在执行 <源文件> 为压缩文件的情况下,会自动复制并解压到 <目标路径>。 - ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。 ### CMD 为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。 **注意**: 1. 如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。 2. CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。 3. CMD 在`docker run` 时运行。而RUN 是在 `docker build`运行。 **语法** ``` CMD CMD ["<可执行文件或命令>","","",...] CMD ["","",...] ``` 推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是sh。 **demo** ```bash CMD ["nginx", "-g", "daemon off;"] ``` ### ENTRYPOINT 类似于 CMD 指令,但其不会被docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。 但是, **注意**: 1. 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。 2. 在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。 3. 如果运行 docker run 时使用了 **--entrypoint** 选项,此选项的参数里面的程序会覆盖 ENTRYPOINT 指令指定的程序。需要注意的是覆盖的是程序!!! **语法** ```bash ENTRYPOINT ["","","",...] ``` **demo** 假设已经构建好了一个nginx:test镜像,下面是该镜像的dockefile文件内容 ```bash FROM nginx ENTRYPOINT ["nginx", "-c"] # 定参 CMD ["/etc/nginx/nginx.conf"] # 变参 ``` ```bash # 不传参运行 $ 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 设置环境变量,定义了环境变量,那么在**后续的指令**中,就可以使用这个环境变量。 **语法** ```bash ENV ENV = =... ``` **demo** ```bash ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v $NODE_VERSION /node-v$NODE_VERSION.tar.gz ``` 上面的示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用。 ### ARG 构建参数,与 ENV 作用一至。不过作用域不一样。 **注意** 1. ARG 设置的环境变量仅对Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。 2. 构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。 **语法** ```bash ARG <参数名>[=<默认值>] ``` **demo** ```bash ARG SIZE=1000 ``` ### VOLUME 容器运行时应该尽量保持容器存储层不发生写操作,对于数据库以及媒体资源等需要保存动态数据的应用,其数据应该保存于卷(volume)中,为了防止运行时忘记将动态文件所保存目录挂载为卷,一般在 `Dockerfile` 中先指定某些目录挂载为匿名卷,这样在启动容器时忘记挂载数据卷,会自动挂载到匿名卷,应用也可以正常运行,不会向容器存储层写入大量数据。 注意 1. docker run命令的-v标识创建的挂载点只能对创建的容器有效。而VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。 2. VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。 3. 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。 语法 ```bash VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径> ``` demo ```bash VOLUME ["/data1","/data2"] ``` 可以通过`docker inspect <容器ID> `来查询容器的挂载点情况 ### EXPOSE 声明个镜像服务的守护端口,以方便配置映射。在运行时使用随机端口映射时,也就是`docker run -P` 时,会自动随机映射EXPOSE 的端口。 **注意** 1. 这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。 **语法** ```bash EXPOSE <端口> EXPOSE [<端口1>...] ``` **demo** ```bash EXPOSE 8080 ``` ### WORKDIR 使用 `WORKDIR` 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,`WORKDIR` 会帮你建立目录。 ``` RUN cd /app RUN echo "hello" > world.txt ``` 如果我们通过上面的 `Dockerfile` 内容进行构建镜像运行后,会发现找不到 `/app/world.txt` 文件,或者其内容不是 `hello`。原因其实很简单,在 `Dockerfile` 中,这两行 `RUN` 命令的执行环境根本不同,是两个完全不同的容器,关于为什么是容器,可以看上面的docker镜像构建镜像的配图,每一个 `RUN` 都是启动一个容器、执行命令、然后提交存储层文件变更、然后再移除容器。第一层 `RUN cd /app` 的执行仅仅是当前进程的工作目录切换,而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继续维持上一个容器的目录。 因此如果需要改变以后各层的工作目录的位置,那么应该使用 `WORKDIR` 指令。docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。 **语法** ``` WORKDIR <工作目录路径> ``` **demo** ``` WORKDIR /app ``` ### USER `USER` 指令和 `WORKDIR` 相似,都是改变环境状态并影响以后的层。`WORKDIR` 是改变工作目录,`USER` 则是改变之后层的执行 `RUN`, `CMD` 以及 `ENTRYPOINT` 这类命令的身份(用户和用户组必须提前已经存在)。 **格式** ```bash USER <用户名>[:<用户组>] ``` **demo** ```bash RUN groupadd -r redis && useradd -r -g redis redis USER redis RUN [ "redis-server" ] ``` ### HEALTHCHECK 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。和 `CMD`, `ENTRYPOINT` 一样,`HEALTHCHECK` 只可以出现一次,如果写了多个,只有最后一个生效。 `HEALTHCHECK` 支持下列选项 | 选项 | 解释 | | :---------------- | :----------------------------------------------------------- | | --interval=<间隔> | 两次健康检查的间隔,默认为 30 秒 | | --timeout=<时长> | 健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒; | | --retries=<次数> | 当连续失败指定次数后,则将容器状态视为 `unhealthy`,默认 3 次。 | **语法** ```bash # 设置检查容器健康状况的命令 HEALTHCHECK [选项] CMD <命令> # 如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 HEALTHCHECK NONE # 这边 CMD后面跟随的命令使用,可以参考CMD的用法。 HEALTHCHECK [选项] CMD <命令> ``` **demo** ```bash HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1 ``` # docker-compose ## linux下安装 ```bash # 下载安装,uname -s显示操作系统名称;uname -m显示电脑类型。 $ curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose # 修改权限 $ chmod +x /usr/local/bin/docker-compose # 查看版本 $ docker-compose --version ``` ## 常用命令 ```bash # 查看帮助 $ docker-compose -h # 构建镜像 $ docker-compose build nginx # 不带缓存的构建 $ docker-compose build --no-cache nginx # 创建并运行所有容器 $ docker-compose up # 构建并后台运行容器nginx $ docker-compose up -d nginx # 显示所有容器 $ docker-compose ps # 登录到nginx容器中 $ docker-compose exec nginx bash # 指定模板 $ docker-compose -f docker-compose.yml up -d # 删除容器(删除前必须关闭容器) docker-compose rm nginx # 停止并删除容器、网络、卷、镜像。 $ docker-compose down # 查看容器nginx实时日志 $ docker-compose logs nginx # 查看容器nginx实时日志 $ docker-compose logs -f nginx # 以json的形式输出nginx的docker日志 docker-compose events --json nginx # 拉取依赖镜像 $ docker-compose pull # 检查docker-compose.yml文件配置 $ dokcer-compose config # 检查docker-compose.yml文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。 $ dokcer-compose config -q # 重启服务 $ docker-compose restart nginx # 启动服务 $ docker-compose start nginx # 暂停服务 docker-compose pause nginx # 恢复服务 docker-compose unpause nginx # 停止服务 $ docker-compose stop nginx ``` ## docker-compose使用 1.创建测试目录 ```bash mkdir composetest cd composetest ``` 2.新建一个test.py文件,内容如下 这是一个测试uwsgi是否正常使用的文件 ```python def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World\n"] ``` 3.创建Dockerfile文件,内容如下 ```bash FROM python:3.7-alpine WORKDIR /app COPY test.py test.py RUN set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories RUN apk add --no-cache gcc make libc-dev linux-headers pcre-dev RUN pip install uwsgi CMD uwsgi --http :8000 --wsgi-file test.py ``` `RUN set -eux xxx`是解决alpine镜像安装软件慢的问题;在Docker中下载了一个 `python:3.6-alpine` 的镜像,相比其它版本,更加精简。但同时也缺少了很多必要的包,所以直接安装`uwsgi`时会产生无法编译的错误,需要执行 `RUN apk add --no-cache gcc make libc-dev linux-headers pcre-dev`来解决。 4.创建 docker-compose.yml ```bash version: '3' services: web: build: . ports: - "8000:8000" ``` 该 Compose 文件定义了一个服务:web ,该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口8000。此服务使用 uwsgi服务器的默认端口8000 。 5.构建和运行应用 ```bash $ docker-compose up -d ``` 6.访问链接 ```bash $ curl 127.0.0.1:8000 Hello World ``` ## yml 配置参数 | 参数 | 解释 | | ----------------- | ------------------------------------------------------------ | | version | 指定本yml文件根据哪个版本的compose制定的 | | image | 指定容器运行的镜像 | | container_name | 指定自定义容器名称,而不是生成的默认名称 | | command | 覆盖容器启动的默认命令 | | cgroup_parent | 为容器指定父 cgroup 组,意味着将继承该组的资源限制 | | depends_on | 解决了容器的依赖、启动先后的问题 | | devices | 指定设备映射列表 | | dns | 自定义 DNS 服务器,可以是单个值或列表的多个值 | | dns_search | 自定义 DNS 搜索域。可以是单个值或列表 | | entrypoint | 覆盖容器默认的 entrypoint | | env_file | 从文件添加环境变量。可以是单个值或列表的多个值 | | environment | 添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False | | expose | 暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数 | | extra_hosts | 添加主机名映射。类似 docker client --add-host | | network_mode | 设置网络模式 | | volumes | 将主机的数据卷或着文件挂载到容器里。 | | sysctls | 设置容器中的内核参数,可以使用数组或字典格式。 | | tmpfs | 在容器内安装一个临时文件系统。可以是单个值或列表的多个值 | | ulimits | 覆盖容器默认的 ulimit | | stop_signa | 设置停止容器的替代信号。默认情况下使用 SIGTERM 。 | | stop_grace_period | 指定在容器无法处理任何 stop_signal的信号),等待多久后发送 SIGKILL 信号关闭容器。默认的等待时间是 10 秒。 | ### build 为服务指定上下文来构建镜像 ```yaml version: "3.7" services: webapp: build: context: ./dir dockerfile: Dockerfile-1 args: number: 1 labels: - "xxxx" target: prod ``` | 参数 | 解释 | | ---------- | ---------------------------------------------- | | context | 上下文路径 | | dockerfile | 指定构建镜像的 Dockerfile 文件名 | | args | 添加构建参数,这是只能在构建过程中访问的环境变 | | labels | 设置构建镜像的标签 | | target | 多层构建,可以指定构建哪一层 | ### cap_add,cap_drop 添加或删除容器拥有的宿主机的内核功能。 ```yaml cap_add: - ALL # 开启全部权限 cap_drop: - SETPCAP # 关闭SETPCAP权限 ``` ### healthcheck 用于检测 docker 服务是否健康运行。 ```yaml healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序 interval: 1m30s # 设置检测间隔 timeout: 10s # 设置检测超时时间 retries: 3 # 设置重试次数 start_period: 40s # 启动后,多少秒开始启动检测程序 ``` ### logging 服务的日志记录配置。 ```yaml logging: # 指定服务容器的日志记录驱动程序,默认值为json-file driver: json-file # 其他选项:"syslog" 和 "none" options: # 仅在json-file驱动程序下,可以使用以下参数,限制日志得数量和大小。 max-size: "200k" # 单个文件大小为200k,当达到文件限制上限,会自动删除旧得文件。 max-file: "10" # 最多10个文件 ``` ```yaml logging: driver: syslog # syslog 驱动程序下 options: syslog-address: "tcp://192.168.0.42:123" # 可以使用 syslog-address 指定日志接收地址。 ``` ### ports 用作端口映射,如果指定容器的端口,宿主机会随机映射端口 ```yaml ports: - "0.0.0.0:80:8000" - "0.0.0.0:443:1443" ``` ### restart 容器重启策略 | 选项 | 解释 | | -------------- | ------------------------------------------------------------ | | no | 默认的重启策略,在任何情况下都不会重启容器 | | always | 容器总是重新启动 | | on-failur | 在容器非正常退出时(退出状态非0),才会重启容器 | | unless-stopped | 在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器 | ```yaml restart: "no" restart: always restart: on-failure restart: unless-stopped ``` © 著作权归作者所有,欢迎转载,转载请说明出处:未雨晴空博客,谢谢理解! 喜欢 打赏 分享 上一篇 下一篇 发表评论 取消回复 电子邮件地址不会被公开。 表情 请输入以http或https开头的URL,格式如:https://oneisall.top 提交评论