Docker-Dockerfile

Dockerfile是docker构建镜像的基础,也是docker区别于其他容器的重要特征,正是有了Dockerfile,docker的自动化和可移植性才成为可能。不论是开发还是运维,学会编写Dockerfile几乎是必备的。

1.Dockerfile语法

Dockerfile中每行都以一个关键字为行首,如果一行内容过长,使用“\”换行。

2.关键字

  • FROM:Dockerfile的第一行,指定从哪个基础镜像开始构建。
FROM centos
FROM java:8
FROM python:3.6.5

如果当前要构建的镜像本身就是一个基础镜像

FROM scratch
  • LABEL:描述镜像信息(镜像生成后,可以使用docker inspect查看镜像信息)。
LABEL key="value"
LABEL maintainer="author <xxx@yyy.com>"
LABEL version="1.2"
  • ENV:设置环境变量。
ENV TEST 1
  • RUN:构建镜像时执行shell命令,多条命令之间使用用&&连接,还可以使用\换行。
RUN apt-get -y update 
RUN apt-get -y install nginx
  • ADD:将外部文件拷贝到镜像里,src可以为url
ADD http://nicescale.com/  /data/nicescale.tgz
  • COPY:将编译机本地文件拷贝到镜像文件系统中(与ADD类似,不能使用URL)。
COPY /tmp/nicescale.tgz  /data/nicescale.tgz
  • WORKDIR:设置工作目录
WORKDIR /var/www
  • USER:设置用户
USER nginx
  • VOLUME:设置容器与宿主机数据共享及数据持久化

也可以在创建容器时使用-v选项 docker run -v <host_dir>:<container_dir> IMAGE (指定宿主机映射目录) 或docker run -v <host_dir>:<container_dir> IMAGE (使用默认的映射目录/var/lib/docker/volumes/<container_id>)达到同样效果

VOLUME ['/data']
  • EXPOSE:指定监听的端口。
EXPOSE 80 443
  • ENTRYPOINT:指定容器启动时执行的命令(Dockerfile中仅最后一条ENTRYPOINT有效)。
# exec方式
ENTRYPOINT ['/bin/bash', 'echo','hello world']
# shell方式
ENTRYPOINT echo "hello world"

docker run命令后如果跟了内容,会作为ENTRYPOINT指定的命令的参数,如:

ENTRYPOINT ["/bin/ls"] 

如果用以下命令创建并启动容器

docker run <image> -l

那么ENTRYPOINT中指定的命令最终会与-l参数一起运行

/bin/ls -l
  • CMD:指定容器启动时执行的命令(Dockerfile中仅最后一条CMD有效,并且docker run指定的命令会替代CMD指定的命令)。
CMD ["/bin/bash","echo","service started..."]
CMD echo "service started..."

当CMD与ENTRYPOINT同时使用时,CMD后的内容会作为ENTRYPOINT后命令的默认参数,如果docker run后又附带了内容,则附带内容会替换CMD后的内容,作为参数ENTRYPOINT后命令的参数。这样CMD与ENTRYPOINT同时使用,能够构建一个既有默认参数又支持参数传入的镜像。

3.创建镜像

通过当前目录下的Dockerfile文件构建镜像

docker build -t IMAGE:VERSION .

通过指定目录下的Dockerfile文件构建镜像

docker build -t IMAGE:VERSION /app/

4.镜像维护

使用Dockerfile文件维护镜像相对比较容易,只需要修改Dockerfile的部分内容,通过docker build重新构建即可。另外还可以通过“-t”选项指定一个新版本,在新旧两个版本间快速切换。

5.Dockerfile实例

5.1 官方镜像hello-world
# 从零开始构建基础镜像
FROM scratch
# 复制可执行文件到docker虚拟机根目录
COPY hello /
# 启动后运行可执行文件
CMD ["/hello"]
5.2 以centos为基础镜像,创建一个新的镜像,用echo输出字符串

Dockerfile文件内容如下

FROM centos 
CMD echo "hello docker $(date)"

创建镜像

$ docker build -t test .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> e934aafc2206
Step 2/2 : CMD echo "hello docker $(date)"
 ---> Running in 9ad050c6be7b
Removing intermediate container 9ad050c6be7b
 ---> 4b412e803011
Successfully built 4b412e803011
Successfully tagged test:latest

通过镜像创建容器并启动(不指定启动时运行的命令)

$ docker run test --name test1
hello docker Thu May 17 05:09:22 UTC 2018

通过镜像创建容器并启动(指定启动时运行的命令),此时CMD中指定的命令不会执行

# 指定启动时以交互模式在终端运行bash
$ docker run --name test2 -it test /bin/bash
[root@9d4414207eeb /]# 
# 指定启动时pwd命令
$ docker run test2 pwd
/
5.3 打包SpringBoot镜像

Dockerfile

FROM        openjdk:8-jre
ADD         crs-core-0.0.1-SNAPSHOT.jar /opt/jar/crs-core.jar
EXPOSE      8080
CMD         ["java","-jar","/opt/jar/crs-core.jar"]

打包镜像过程如下

$ sudo docker build -t crs-core:0.0.1 .
Sending build context to Docker daemon  41.98MB
Step 1/4 : FROM     openjdk:8-jre
 ---> dd20fb277e3c
Step 2/4 : ADD      crs-core-0.0.1-SNAPSHOT.jar /opt/jar/crs-core.jar
 ---> Using cache
 ---> 021003891a14
Step 3/4 : EXPOSE       8080
 ---> Using cache
 ---> b6f8e3d010dd
Step 4/4 : CMD      ["java","-jar","/opt/jar/crs-core.jar"]
 ---> Running in 5b6fb9d78093
Removing intermediate container 5b6fb9d78093
 ---> 6d9938a0f6be
Successfully built 6d9938a0f6be
Successfully tagged crs-core:0.0.1

查看镜像

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
crs-core            0.0.1                 6d9938a0f6be        47 seconds ago      485MB
openjdk             8-jre               dd20fb277e3c        2 weeks ago         443MB

启动容器

$ sudo docker run --name crs-core -p 9090:8080 -d crs-core:0.0.1
52dc83fe7542f1958e509bdd905a91f0ac967fe6dd094486c6c13028bc782c4a
[clinflash@localhost crs-docker]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
52dc83fe7542        crs-core:0.0.1        "java -jar /opt/jar/…"   6 seconds ago       Up 5 seconds        0.0.0.0:9090->8080/tcp     crs-core
5.4 更多实例

To be continued...

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

推荐阅读更多精彩内容