参考链接:https://docs.docker.com/engine/reference/builder/
简介:
创建镜像有三种方式,即
1.从已有的容器创建:docker commit
2.从本地导入;docker import 或 docker load
3.使用dockerfile创建
下面详细学习以下dockerfile:
Dockerfile 可以自定义镜像,通过 Docker 命令去运行镜像,从而达到启动容器的目的。Dockerfile 是由一行行命令语句组成,并且支持已 # 开头的注释行。
Dockerfile 分为四个部分:
- 基础镜像(父镜像)信息指令 FROM。
- 维护者信息指令 MAINTAINER。
- 镜像操作指令 RUN 、EVN 、ADD 和 WORKDIR 等。
- 容器启动指令 CMD 、ENTRYPOINT 和 USER 等。
例子:
1.首先创建一个dockerfile目录,里面包含两个文件:Dockerfile、index.html.
x
qkang@xqkang:~/docker/dockerfile$ cat index.html
<h1>my first dockerfile<h1>
xqkang@xqkang:~/docker/dockerfile$ cat Dockerfile
#nginx基础镜像
FROM nginx
#指定工作路径
WORKDIR /usr/share/nginx/html
#将前前路径下的所有文件都COPY到工作路径下
COPY . .
#EXPOSE 命令用来指定对外开放的端口,实际用处不大,可不写
EXPOSE 80
2.docker build 创建镜像
docker build --tag 镜像名称 运行的路径
xqkang@xqkang:~/docker/dockerfile$ docker build --tag firstdemo .
Sending build context to Docker daemon 3.072kB
Step 1/4 : FROM nginx
---> 231d40e811cd
Step 2/4 : WORKDIR /usr/share/nginx/html
---> Running in c66cd030aeca
Removing intermediate container c66cd030aeca
---> 44d659f885c7
Step 3/4 : COPY . .
---> f7b79676b25c
Step 4/4 : EXPOSE 80
---> Running in 925353a7762a
Removing intermediate container 925353a7762a
---> e1603cc26646
Successfully built e1603cc26646
Successfully tagged firstdemo:latest
常用命令详解:
Dockerfile 中的常用命令一定要大写。
FROM
FROM 是用于指定基础的 images ,一般格式为 FROM 。所有的 Dockerfile 都应该以 FROM 开头,FROM 命令指明 Dockerfile 所创建的镜像文件以什么镜像为基础,FROM 以后的所有指令都会在 FROM 的基础上进行创建镜像。可以在同一个 Dockerfile 中多次使用 FROM 命令用于创建多个镜像。
MAINTAINER
MAINTAINER 是用于指定镜像创建者和联系方式,一般格式为 MAINTAINER。
COPY
COPY 是用于复制本地主机的(为 Dockerfile 所在目录的相对路径)到容器中的。当使用本地目录为源目录时,推荐使用 COPY 。一般格式为 COPY。例如我们要拷贝当前目录到容器中的 /app 目录下,我们可以这样操作:COPY ./app
WORKDIR
WORKDIR 用于配合 RUN,CMD,ENTRYPOINT 命令设置当前工作路径。可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令。默认路径为/。一般格式为 WORKDIR /path/to/work/dir。
RUN
RUN 用于容器内部执行命令。每个 RUN 命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。一般格式为 RUN。例如我们要安装 Python 依赖包,我们做法如下:RUN pip install -r requirements.txt
EXPOSE
EXPOSE 命令用来指定对外开放的端口。一般格式为 EXPOSE[…]。例如上面那个例子,开放80端口:EXPOSE 80
ENTRYPOINT
ENTRYPOINT 可以让你的容器表现得像一个可执行程序一样。一个 Dockerfile 中只能有一个 ENTRYPOINT,如果有多个,则最后一个生效。
ENTRYPOINT 命令也有两种格式:
ENTRYPOINT ["executable", "param1", "param2"] :推荐使用的 Exec 形式。
ENTRYPOINT command param1 param2 :Shell 形式。
CMD
CMD 命令用于启动容器时默认执行的命令,CMD 命令可以包含可执行文件,也可以不包含可执行文件。
不包含可执行文件的情况下就要用 ENTRYPOINT 指定一个,然后 CMD 命令的参数就会作为 ENTRYPOINT 的参数。
CMD 命令有三种格式:
CMD ["executable","param1","param2"]:推荐使用的 exec 形式。
CMD ["param1","param2"]:无可执行程序形式。
CMD command param1 param2:Shell 形式。
一个 Dockerfile 中只能有一个 CMD,如果有多个,则最后一个生效。而 CMD 的 Shell 形式默认调用 /bin/sh -c 执行命令。
CMD 命令会被 Docker 命令行传入的参数覆盖:docker run nginx /bin/echo Hello Docker 会把 CMD 里的命令覆盖。
例子2:
xqkang@xqkang:~/docker/dockertest1$ cat Dockerfile
FROM ubuntu
MAINTAINER xqkang "kk@qq.com"
ENV REFRESHED_AT 2019.12.10
#更新资源库
RUN apt-get -yqq update
#安装curl
RUN apt-get install iputils-ping -y
#安装ifconfig
RUN apt-get install net-tools -y
RUN echo aaaa
CMD echo bbbbb
CMD echo ccccc
ENTRYPOINT hostname
xqkang@xqkang:~/docker/dockertest1$ docker build -t second .
Sending build context to Docker daemon 2.048kB
Step 1/10 : FROM ubuntu
---> 775349758637
Step 2/10 : MAINTAINER xqkang "kk@qq.com"
---> Running in 2c3eaac2eb54
Removing intermediate container 2c3eaac2eb54
---> ed1fc4e605fd
Step 3/10 : ENV REFRESHED_AT 2019.12.10
---> Running in e495f4ea6b35
Removing intermediate container e495f4ea6b35
---> 81fae98c9ec5
Step 4/10 : RUN apt-get -yqq update
---> Running in 2537a3df7522
Removing intermediate container 2537a3df7522
---> 68539a99bb2e
Step 5/10 : RUN apt-get install iputils-ping -y
---> Running in 084fd5e7026c
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
libcap2 libcap2-bin libidn11 libpam-cap
The following NEW packages will be installed:
iputils-ping libcap2 libcap2-bin libidn11 libpam-cap
0 upgraded, 5 newly installed, 0 to remove and 2 not upgraded.
Need to get 142 kB of archives.
After this operation, 537 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu bionic/main amd64 libcap2 amd64 1:2.25-1.2 [13.0 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libidn11 amd64 1.33-2.1ubuntu1.2 [46.6 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 iputils-ping amd64 3:20161105-1ubuntu3 [54.2 kB]
Get:4 http://archive.ubuntu.com/ubuntu bionic/main amd64 libcap2-bin amd64 1:2.25-1.2 [20.6 kB]
Get:5 http://archive.ubuntu.com/ubuntu bionic/main amd64 libpam-cap amd64 1:2.25-1.2 [7268 B]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 142 kB in 2s (83.8 kB/s)
Selecting previously unselected package libcap2:amd64.
(Reading database ... 4046 files and directories currently installed.)
Preparing to unpack .../libcap2_1%3a2.25-1.2_amd64.deb ...
Unpacking libcap2:amd64 (1:2.25-1.2) ...
Selecting previously unselected package libidn11:amd64.
Preparing to unpack .../libidn11_1.33-2.1ubuntu1.2_amd64.deb ...
Unpacking libidn11:amd64 (1.33-2.1ubuntu1.2) ...
Selecting previously unselected package iputils-ping.
Preparing to unpack .../iputils-ping_3%3a20161105-1ubuntu3_amd64.deb ...
Unpacking iputils-ping (3:20161105-1ubuntu3) ...
Selecting previously unselected package libcap2-bin.
Preparing to unpack .../libcap2-bin_1%3a2.25-1.2_amd64.deb ...
Unpacking libcap2-bin (1:2.25-1.2) ...
Selecting previously unselected package libpam-cap:amd64.
Preparing to unpack .../libpam-cap_1%3a2.25-1.2_amd64.deb ...
Unpacking libpam-cap:amd64 (1:2.25-1.2) ...
Setting up libcap2:amd64 (1:2.25-1.2) ...
Setting up libidn11:amd64 (1.33-2.1ubuntu1.2) ...
Setting up iputils-ping (3:20161105-1ubuntu3) ...
Setting up libpam-cap:amd64 (1:2.25-1.2) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)
debconf: falling back to frontend: Teletype
Setting up libcap2-bin (1:2.25-1.2) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Removing intermediate container 084fd5e7026c
---> 2e224bd68d74
Step 6/10 : RUN apt-get install net-tools -y
---> Running in f739dd8fd754
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
net-tools
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 194 kB of archives.
After this operation, 803 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu bionic/main amd64 net-tools amd64 1.60+git20161116.90da8a0-1ubuntu1 [194 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 194 kB in 2s (112 kB/s)
Selecting previously unselected package net-tools.
(Reading database ... 4089 files and directories currently installed.)
Preparing to unpack .../net-tools_1.60+git20161116.90da8a0-1ubuntu1_amd64.deb ...
Unpacking net-tools (1.60+git20161116.90da8a0-1ubuntu1) ...
Setting up net-tools (1.60+git20161116.90da8a0-1ubuntu1) ...
Removing intermediate container f739dd8fd754
---> ce5c5990e4cf
Step 7/10 : RUN echo aaaa
---> Running in ad2f950920ea
aaaa
Removing intermediate container ad2f950920ea
---> 3252e697f659
Step 8/10 : CMD echo bbbbb
---> Running in a9d83e14383f
Removing intermediate container a9d83e14383f
---> f734e30353cc
Step 9/10 : CMD echo ccccc
---> Running in ca870d67e64b
Removing intermediate container ca870d67e64b
---> 99af0d49b0ff
Step 10/10 : ENTRYPOINT hostname
---> Running in a10b888ffd31
Removing intermediate container a10b888ffd31
---> cf209d562a39
Successfully built cf209d562a39
Successfully tagged second:latest
xqkang@xqkang:~/docker/dockertest1$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
second latest cf209d562a39 About a minute ago 95MB
firstdemo latest e1603cc26646 About an hour ago 126MB
192.168.10.46:5000/ui_ubuntu latest 1f38d2b9684c 20 hours ago 64.2MB
nginx latest 231d40e811cd 2 weeks ago 126MB
xqkang/ubuntu 18.04 775349758637 5 weeks ago 64.2MB
ubuntu 18.04 775349758637 5 weeks ago 64.2MB
ubuntu latest 775349758637 5 weeks ago 64.2MB
registry latest f32a97de94e1 9 months ago 25.8MB
xqkang/registry latest f32a97de94e1 9 months ago 25.8MB
hello-world latest fce289e99eb9 11 months ago 1.84kB
xqkang@xqkang:~/docker/dockertest1$ docker run -it second
4559e95cd0a6
上面的例子中只有aaaa被打印出来了,下面的bbbb,ccccc没被打印出来,是被entrypoint覆盖了。entrypoint执行hostname命令。
这里面后面加echo ddddd不起作用,因为entrypoint 指定的是uname,在uname可执行程序下,不能执行echo
xqkang@xqkang:~/docker/dockertest1$ docker run -it second echo ddddd
b7a358553d98
上面的例子没有entrypoint的时候,docker run -it second echo ddddd这时,会打印ddddd
将entrypoint 重新加入,病改为/bin/bash ,run容器的时候会直接进入容器里的bash终端。
来源:CSDN
作者:小二来碗面
链接:https://blog.csdn.net/qq_39122146/article/details/103469142