Docker踩坑指南2:Dockerfile和Docker Compose

一、Dockerfile

Dockerfile 用途

Dockerfile是用来干嘛的?之前我们介绍了Docker的主要用途,用来节省配置运行环境的开销,接着讲了一大堆docker命令,但还没讲到具体该如何生成一个镜像文件。

上次我们是讲过一条命令,docker container commit,它可以将正在运行的容器保存成镜像。然后官方提供了很多已经配置好运行环境的镜像诸如TomcatNodeJsMySQL等等都有,所以只需要运行这些镜像,再把把自己的项目文件放进去,然后用commit命令生成镜像文件,接着在服务器上下载这个镜像文件并运行就可以了。

这个方法理论上虽然可行,但每修改一次项目文件,就需要手动运行镜像然后再复制文件,这实在很不方便;再加上很多时候官方提供的镜像并不一定完全满足我们的要求,我们需要做很多自定义的配置,每次都要手动进行配置,然后再coomit保存,费时间不说还容易出错。而Dockerfile就是这样产生的,它将手动的配置运行环境转换成了一条条的特殊指令,每次修改完工程之后,只需要输入docker built命令便可以自动执行这些指令并生成镜像文件,方便又快捷。除此之外,Dockerfile 在生成镜像文件的过程中会生成很多层的缓存,重新执行docker built时如果中间某些指令执行的时候文件系统没有发生变化,这些指令就不会重复运行,从而节省了很多时间。

Dockerfile 指令举例

在明白了它的用途之后我们就来学习最关键的部分,它有哪些指令。

首先就用我个人的一个Django(Python的一个web后端框架)项目来作为范例展示:

FROM nginx
WORKDIR /usr/src/app

COPY resources/sources.list /etc/apt/sources.list
COPY resources/pip.conf /root/.pip/pip.conf
RUN apt update && apt -y install python3 python3-pip
RUN pip3 install uwsgi

COPY resources/requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

RUN mkdir -p /var/www/
COPY static /var/www/static
COPY code .
COPY resources/start.sh .
RUN chmod +x ./start.sh
ENTRYPOINT ["./start.sh"]
  • 首先开头的FROM nginx表示根据哪个镜像进行修改制作,虽然官方也有Django的镜像,但无法满足我的要求,于是直接根据官方nginx镜像进行制作。

  • 接下来的WORKDIR /usr/src/app,是设置工作目录,就和命令行的cd差不多,后面运行的所有命令都会基于这个工作目录进行,不过如果运行这条指令的时候右边的目录不存在则会自动创建这个目录。

  • 后面是配置运行环境的主要过程,主要是 COPY 和 RUN 命令。COPY xxx yyy:就是将文件从本地复制到镜像内部,xxx 是源文件在本机上的目录;yyy 是目的文件在镜像内部的路径,由于之前设置了工作目录,所以实际的目的文件路径就是 /usr/src/app/requirements.txt,例如我这里复制了 Django的Python依赖(requirements.txt)、debian 的国内下载源(sources.list)、pip 的配置文件以及整个项目工程到镜像里。

    RUN 命令也很简单,就是在生成镜像文件过程中需要运行的命令,例如我这里运行的命令有安装Python依赖、创建文件夹、设置文件权限等等。

  • 最后就是 ENTRYPOINT 命令,设置了运行镜像时要执行的命令,我这里因为要同时运行多个命令,所以把它写成了shell脚本文件。

还有其他很多诸如设置环境变量、标签、暴露端口号什么的还有很多,我觉得没必要详细介绍了,直接看官网的文档或CSDN博客就都可以理解了,这里就只重点介绍一下 ENTRYPOINTCMD 的异同。

ENTRYPOINT 和 CMD 的区别

刚刚我们的示例中用的是ENTRYPOINT,而CMD的作用也差不多,都是设置在容器运行以后执行的命令,在没有设置ENTRYPOINT的情况下,才会使用CMD后面的指令。

两者的基本语法如下:

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

第二种是官方推荐的使用方法,将命令分成几段,写成数组的形式;也可以像RUN一样写成shell的形式。

CMD <command> 或
CMD ["<executeable>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]

这里的第二种也是官方推荐的写法,而第三种用法则是和 ENTRYPOINT 一起使用的,可以实现在 ENTRYPOINT 中设置执行的程序,而在 CMD 中设置对应的参数,例如下面的示例则会执行top -b -c

ENTRYPOINT ["top"]   
CMD ["-b","-c"]  

还有一点重要的就是,docker run命令后面可以接一个默认运行的命令,它会替换掉 CMD 后面的命令,而 ENTRYPOINT 后面的命令则不会被替换掉。



二、Docker Compose

Docker Compose 是官方用 Python 写的一个小工具,因为有时候需要同时运行多个Docker服务,例如一个简单的网站就需要用到至少两个服务——网页前后端、MySQL服务,而采用手工管理多个服务(包括创建镜像,开始、停止、删除容器等等)并不是很方便,于是 Docker Compose 应运而生,它可以方便的管理多个Docker服务,同时它将 docker run 的运行参数改成了文本文件的配置方式,方便临时修改参数。

Compose file 简述

Docker Compose 主要就是一个docker-compose.yml文件,里面设置的每个service就相当于一条docker run命令,下面我也用同一个项目的文件范例来介绍:

version: '3'

services:
  database:
    image: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=XXXXXXXXX
      - MYSQL_DATABASE=bxnb_db

  web:
    image: registry.cn-hangzhou.aliyuncs.com/tommy0607/bxnb-website:v1.5
    ports:
      - "80:80"
      - "443:443"
    environment:
      - ENV=production
  • 开头第一行是Compose file的版本,现在基本上用版本3就可以了
  • 后面的services里面是不同的服务,我这里定义了数据库和网页前后端这两个服务,database和web是自定义的服务名
  • image指定了服务所使用的镜像名
  • environment设置了容器所用的环境变量,与-e xxxx=yyy的作用一致
  • ports设置了向外部映射的端口,与-p 80:80的作用一致

总之就是docker run后面的每一个参数都可以对应一个相关属性,除此之外还可以设置不同服务间的依赖关系等等,这些属性就直接看官方文档就好了,这里不再详述。

Docker Compose 命令介绍

Docker Compose里的命令都和docker里的命令相对应,实现一条命令来开始、停止、删除容器等等的操作

Commands:
  build              Build or rebuild services
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  ps                 List containers
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers

主要有上面一些命令,其他的我就不介绍了,就介绍两个up和down:

  • up命令就是一键创建镜像、运行容器,要记得加上-d参数表示在后台运行。
  • down命令就是一键停止容器、删除容器、删除镜像。

这些命令后面都可以加上针对的服务名列表如果不加服务名的话表示对所有服务执行这些命令

举个例子:docker-compose up -d database就是创建并后台运行数据库服务。


本次学习就到这里结束了,基本上掌握了Docker中需要用到的各种东西了,收获挺大的!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容