Docker
- Docker 是一个开源的应用容器引擎
- 开发者打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。就好像 Java 虚拟机一样,“一次编写,到处运行(Write once, run anywhere)”,而 Docker 是“一次构建,到处运行(Build once,run anywhere)”。
- 一个完整的Docker有以下几个部分组成:
Docker Client客户端
Docker Daemon守护进程
Docker Image镜像
Docker Container容器 - Docker 的优点
- 轻量级:所有容器在一台机器上共享同一个操作系统内核,更有效地利用内存。Image 是从分层文件系统的构建,能够共享公共文件,使得磁盘使用率和 Image 的下载更高效。
- 开放:Docker 容器是基于开发的标准,允许容器运行在主流的 Linux 发布版和 Microsoft 操作系统作为所有的基础设施。
- 安全:容器使得应用程序彼此隔离,而基础架构同时为应用程序提供了额外的保护层。
Docker 与 虚拟机的区别
容器与虚拟机有着类似的资源隔离和分配的优点,但不同的架构方法使容器能够更加便携,高效等。
每个虚拟机都包括应用程序、必要的二进制文件和库以及一个完整的客户操作系统(Guest OS),尽管它们被分离,它们共享并利用主机的硬件资源,将近需要十几个 GB 的大小。
容器包括应用程序及其所有的依赖,但与其他容器共享内核。它们以独立的用户空间进程形式运行在主机操作系统上。他们也不依赖于任何特定的基础设施,Docker 容器可以运行在任何计算机上,任何基础设施和任何云上。
Docker的部署安装
1.配置7.5镜像的yum 源,便于解决依赖性
官方网站阿里云开源镜像网站软件包列表:
docker-ce-18.09.6-3.el7.x86_64.rpm
docker-ce-cli-18.09.6-3.el7.x86_64.rpm
containerd.io-1.2.5-3.1.el7.x86_64.rpm
container-selinux-2.21-1.el7.noarch.rpm
[root@server1 ~]# cat /etc/yum.repos.d/yum.repo
[rhel7.5]
name=rhel
baseurl=http://172.25.19.250/rhel7.5
gpgcheck=0
[docker]
name=rhel
baseurl=http://172.25.19.250/docker
gpgcheck=0
安装软件解决依赖性:
yum install -y docker-ce-18.09.6-3.el7.x86_64.rpm
docker-ce-cli-18.09.6-3.el7.x86_64.rpm
containerd.io-1.2.5-3.1.el7.x86_64.rpm
container-selinux-2.21-1.el7.noarch.rpm
[root@server1 docker]# systemctl start docker
[root@server1 docker]# systemctl enable docker
[root@server1 ~]# yum install -y bash-* #安装tab自动补齐的软件包
镜像的导入和容器使用
简单搭建一个2048小游戏
获取一个容器镜像,导入到docker 引擎
[root@server1 ~]# ls
docker game2048.tar rhel7.tar ubuntu.tar
[root@server1 ~]# docker load -i game2048.tar
011b303988d2: Loading layer 5.05MB/5.05MB
36e9226e74f8: Loading layer 51.46MB/51.46MB
192e9fad2abc: Loading layer 3.584kB/3.584kB
6d7504772167: Loading layer 4.608kB/4.608kB
88fca8ae768a: Loading layer 629.8kB/629.8kB
Loaded image: game2048:latest
[root@server1 ~]# docker run -d --name vm1 -p 80:80 game2048
9cb414e5530c4e37d3d5b25141439d3f212c9275ab55a0ef89ffb4388fbee366
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9cb414e5530c game2048 "/bin/sh -c 'sed -i …" 11 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp, 443/tcp vm1
[root@server1 ~]# docker inspect vm1
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
game2048 latest 19299002fdbe 2 years ago 55.5M
docker常用的基础命令
docker load -i 镜像名 #导入镜像
docker run -i --name 容器名 镜像名 #创建容器以镜像为模版
docker ps #查看容器状态
docker ps -a #查看容器状态(包或不活跃的容器)
docker attach vm1 连接容器
docker top vm1 查看容器进程
docker logs vm1 查看容器指令输出 -f参数可以实时查看
docker inspect vm1 查看容器详情
docker stats vm1 查看容器资源使用率
docker diff vm1 查看容器修改
docker stop vm1 停止容器
docker start vm1 启动容器
docker kill vm1强制杀死容器进程
docker restart vm1 重启容器
docker rm vm1 删除容器
docker pause/uppause vm1 暂停/恢复容器
Docker镜像的分层结构
- 共享宿主机的kernel(内核)
- base镜像提供的是最小的Linux发行版
- 同一docker主机支持运行多种linux发行版
- 采用分层结构的最大好处:共享资源(节省本地空间占用)
镜像分层的特点:
- Copy-on-Write 可写容器层
- 容器层以下所有镜像层都是只读的
- docker从上往下一次查找文件(先看到容器层部分)
- 容器层保存镜像变化的部分并不会对镜像本身有任何修改
- 一个镜像最多127层 (层数越小越好)
镜像构建
docker commit 方式构建:
[root@server1 ~]# docker load -i ubuntu.tar #加载镜像
56abdd66ba31: Loading layer 196.8MB/196.8MB
9468150a390c: Loading layer 208.9kB/208.9kB
11083b444c90: Loading layer 4.608kB/4.608kB
5f70bf18a086: Loading layer 1.024kB/1.024kB
Loaded image: ubuntu:latest
[root@server1 ~]# docker run -it --name vm1 ubuntu # -it以交互式形式打开一个tty
root@b208daafaa16:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@b208daafaa16:/# touch file001 #在容器层创建文件(删除文件、修改文件),不会影响镜像层
root@b208daafaa16:/# ls
bin dev file001 lib media opt root sbin sys usr
boot etc home lib64 mnt proc run srv tmp var
root@b208daafaa16:/# exit
[root@server1 ~]# docker commit vm1 ubuntu:v1 #将容器保存为新的镜像
sha256:447f0343f2c9beffaf565043ae903200390118013c0850a1cf4c7fc59aa13e17
[root@server1 ~]# docker images #查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v1 447f0343f2c9 16 seconds ago 188MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 ~]# docker run -it --name vm2 ubuntu:v1 #运行ubuntu:v1镜像
root@b81ea991db1a:/# ls
bin dev file001 lib media opt root sbin sys usr
boot etc home lib64 mnt proc run srv tmp var
root@b81ea991db1a:/# uname -r ##print the kernel release
3.10.0-514.el7.x86_64
root@b81ea991db1a:/# exit
[root@server1 ~]# docker history ubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
07c86167cdc4 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 years ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$… 1.9kB
<missing> 3 years ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli… 195kB
<missing> 3 years ago /bin/sh -c #(nop) ADD file:b9504126dc5590898… 188MB
[root@server1 ~]# docker history ubuntu:v1 #查看镜像创建历史,可以看到v1在 ubuntu镜像基础上创建
IMAGE CREATED CREATED BY SIZE COMMENT
447f0343f2c9 4 minutes ago /bin/bash 20B
07c86167cdc4 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 years ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$… 1.9kB
<missing> 3 years ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli… 195kB
<missing> 3 years ago /bin/sh -c #(nop) ADD file:b9504126dc5590898… 188MB
Dockerfile 方式构建:
注意:dockerfile自动构建也是基于docker commit的层层构建得出
[root@server1 ~]# docker load -i busybox.tar #加载镜像
[root@server1 ~]# mkdir docker #创建一个dockerfile 构建目录(默认情况下会把当前目录的内容发送docker引擎作为构建引擎)
[root@server1 ~]# cd docker/
[root@server1 docker]# pwd ##尽量不要把目录建在根目录下(根目录下的数据比较多)
/root/docker
[root@server1 docker]# vim dockerfile
[root@server1 docker]# cat dockerfile
FROM busybox #指定base镜像,如果本地不存在会从远程仓库下载(可以联网)
RUN echo 'hello world'
[root@server1 docker]# docker build -t busybox:v2 . ##'.' 表示当前目录构建内容加载到docker引擎, -t 指定镜像名称
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM busybox ##基础镜像是busybox
---> 59788edf1f3e
Step 2/2 : RUN echo 'hello world' ##构建容器,我们在容器中运行的指令
---> Running in e92d2e8fb8b3
hello world
Removing intermediate container e92d2e8fb8b3#删除临时容器的id
---> 068533611022
Successfully built 068533611022
Successfully tagged busybox:v2 ##生成镜像层
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox v2 068533611022 10 minutes ago 1.15MB
busybox latest 59788edf1f3e 9 months ago 1.15MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 docker]# docker history busybox:latest
IMAGE CREATED CREATED BY SIZE COMMENT
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
[root@server1 docker]# docker history busybox:v2
IMAGE CREATED CREATED BY SIZE COMMENT
068533611022 10 minutes ago /bin/sh -c echo 'hello world' 0B #可以看见指令 ,便于审计
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
缓存特性:
[root@server1 docker]# vim dockerfile
[root@server1 docker]# cat dockerfile
FROM busybox
RUN echo 'hello world' #RUN运行一次,创建一个镜像层
RUN echo testfile > file1
RUN echo testfile > file2
root@server1 docker]# docker build -t busybox:v3 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM busybox
---> 59788edf1f3e
Step 2/4 : RUN echo 'hello world'
---> Using cache ##运行过的cache 直接使用
---> 068533611022
Step 3/4 : RUN echo testfile > file1
---> Running in 4fee74ff45a5 #新建的步骤会生成一个中间的容器
Removing intermediate container 4fee74ff45a5 ##运行后删除容器
---> 7f213cefba57 #提交镜像层
Step 4/4 : RUN echo testfile > file2
---> Running in e978b6309e99
Removing intermediate container e978b6309e99
---> b794a5c7bc39
Successfully built b794a5c7bc39
Successfully tagged busybox:v3
[root@server1 docker]# docker history busybox:v3
IMAGE CREATED CREATED BY SIZE COMMENT
b794a5c7bc39 3 minutes ago /bin/sh -c echo testfile > file2 9B
7f213cefba57 3 minutes ago /bin/sh -c echo testfile > file1 9B
068533611022 20 hours ago /bin/sh -c echo 'hello world' 0B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
[root@server1 docker]# docker history busybox:v2
IMAGE CREATED CREATED BY SIZE COMMENT
068533611022 20 hours ago /bin/sh -c echo 'hello world' 0B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
v2 和v3相比之前的两层都一样,每个run是一层,
Dockerfile详解
dickerfile 常用指令:
FROM: 指定base镜像,如果本地不存在会从远程仓库下载(可以联网)
MAINTAINER:设置镜像的作者,如用户邮箱等(不是必须的)
COPY:把文件从构建目录复制到镜像
支持两种形式:CPOY src dest 和 COPY [" src" ,"dest "]
src 源文件一定要在构建目录中
[root@server1 docker]# cat dockerfile
FROM busybox #FROM 制定base镜像
COPY testfile /tmp #cpoy testfile到 /tmp文件 后面可以加制定的文件名
[root@server1 docker]# echo testfile > testfile #创建文件,注意源文件一定要在构建目录中
[root@server1 docker]# ls
dockerfile testfile
[root@server2 docker]# docker run -it --name vm1 busybox:v1
/ # ls
bin dev etc home proc root sys tmp usr var
/ # cd tmp/
/tmp # ls
testfile
/tmp #
[root@server1 docker]# docker rmi busybox:v1 #删除不用的镜像
Untagged: busybox:v1
Deleted: sha256:fc63aa93b2b4eee339dd8c3bbb0e7fd79478e560ed8e75b002ce85efe03aa750
Deleted: sha256:6a60ed6c36d0159665b09d84b7a81564dc77
ADD用法与CPOY类似,不同的是src可以是归档压缩文件,文件会自动解压到dest,也可以自动下载URL并拷贝到镜像
- ADD html.tar /var/www
- ADD http://ip/html.tar /var/www
[root@server1 docker]# vim dockerfile
FROM busybox
COPY testfile /tmp
ADD nginx-1.15.8.tar.gz /tmp
[root@server1 docker]# ls
dockerfile nginx-1.15.8.tar.gz testfile
[root@server1 docker]# docker build -t test:v1 .
Sending build context to Docker daemon 1.032MB
Step 1/3 : FROM busybox
—> 59788edf1f3e
Step 2/3 : COPY testfile /tmp
—> 7fa33b685481
Step 3/3 : ADD nginx-1.15.8.tar.gz /tmp
—> e986dbe19784
Successfully built e986dbe19784
Successfully tagged test:v1
[root@server1 docker]# docker run -it --name vm1 test:v1
/ # ls
bin dev etc home proc root sys tmp usr var
/ # cd tmp/
/tmp # ls
nginx-1.15.8 testfile #查看到有nginx的解压包
/tmp # cd nginx-1.15.8/
/tmp/nginx-1.15.8 # ls
CHANGES LICENSE auto configure html src
CHANGES.ru README conf contrib man
ENV 设置环境变量(定义主机名…),变量可以被后续的指令(CMD结合)使用
- ENV HOSTNAME server1
EXPOSE 如果容器中运行应用服务,可以把端口暴露出去;
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v1 e986dbe19784 2 hours ago 7.32MB
busybox latest 59788edf1f3e 9 months ago 1.15MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 docker]# docker history game2048:latest
IMAGE CREATED CREATED BY SIZE COMMENT
19299002fdbe 2 years ago /bin/sh -c #(nop) CMD ["/bin/sh" “-c” "sed … 0B
2 years ago /bin/sh -c #(nop) EXPOSE 80/tcp #暴露镜像内部的应用所监听的端口,方便作端口映射 0B
2 years ago /bin/sh -c #(nop) COPY dir:cb74e9c037a3d501c… 600kB
2 years ago /bin/sh -c #(nop) MAINTAINER Golfen Guo <go… 0B
2 years ago /bin/sh -c #(nop) CMD [“nginx” “-g” "daemon… 0B
2 years ago /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp 0B
2 years ago /bin/sh -c #(nop) COPY file:d15ceb73c6ea776c… 1.1kB
VOLUME 申明数据卷,通常指应用的数据挂载点:
- VOLUME [ “/var/www/html”]
WORKDLIR 为RUN,ENTRYPOINT,ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动建立
[root@server1 docker]# docker run -it --name vm1 test:v1
/ # ls
bin dev etc home proc root sys tmp usr var
[root@server1 docker]# vim dockerfile
[root@server1 docker]# cat dockerfile
FROM busybox
COPY testfile /tmp
ADD nginx-1.15.8.tar.gz /tmp
VOLUME ["/data"] # /data目录在容器本没有
创建镜像后运行:
[root@server1 docker]# docker run -it --name vm3 test:v2 #创建容器vm3,运行镜像test:v2
/ # ls
bin data dev etc home proc root sys tmp usr var #自动新建,按装docker的宿主机上
/ # # 按ctrl+pq 退出但依旧运行
[root@server1 docker]# docker inspect vm3
"Source": "/var/lib/docker/volumes #在封装时申明了数据卷,容器启动时dicker引擎会自动在本地生成数据目录并挂到容器内的数据挂载点
/c3e66b8a21fdde6b5ee7b5b969c0e9de7c3765921f30736e58707bfdc3cc51fe/_data",
"Destination": "/data",
"Driver": "local",
[root@server1 docker]# cd /var/lib/docker/volumes /c3e66b8a21fdde6b5ee7b5b969c0e9de7c3765921f30736e58707bfdc3cc51fe/_data #此时容器内往/data操作也就是在该目录中操作
[root@server1 _data]# touch file1
[root@server1 _data]# pwd
/var/lib/docker/volumes/c3e66b8a21fdde6b5ee7b5b969c0e9de7c3765921f30736e58707bfdc3cc51fe/_data
[root@server1 _data]# docker attach vm3
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # cd data/
/data # ls
file1
/data # rm -fr file1
/data # touch file2
/data # read escape sequence
[root@server1 _data]# cd /var/lib/docker/volumes/c3e66b8a21fdde6b5ee7b5b969c0e9de7c3765921f30736e58707bfdc3cc51fe/_data
[root@server1 _data]# ls
file2
手动指定数据卷
[root@server1 ~]# docker run -it --name vm4 -v /opt/data:/data test:v2 #-v 挂接数据卷,“:”前是宿主机上的路径(没有的话会自动新建),之后的是容器内的路径
/ # cd data/
/data # touch file1
/data # touch file2
/data # touch file3
[root@server1 ~]# cd /opt/data/ #自动存储在宿主机的指定位置,不指定的时候docker自动分配挂在点
[root@server1 data]# ls
file1 file2 file3
WORKDLIR 为RUN,ENTRYPOINT,ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动建立(相当于cd,但可自动创建目录)
RUN 在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim (每个run 都会多一层)
CMD和ENTRRYPOINT 这两个指令都用于设置容器启动后执行的命令,但CMD会被docker run 后面的命令覆盖,而ENTRYPOINT不会被忽略,一定会执行。
docke run后面的参数可以传递给ENTRYPOINT指令当作参数;
Dockerfile中只能指定一个ENTRYPOINT,如果指定多个,只有最后一个有效
Shell和exec格式的区别:
Shell 格式底层会调用/bin/sh -c来执行命令,可以解析变量,而exec格式不会;
Shell 格式:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo “hello,$name”
exec格式:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", “hello,$name”]
调用变量的话:
FROM busybox
ENV name world
ENTRYPOINT["/bin/sh","−c","echo hello,$name”]
shell方式:
[root@server1 docker]# cat dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo "hello,$name" #$name 被解析
[root@server1 docker]# docker build -t test:v1 . #构建
Sending build context to Docker daemon 1.032MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Running in 531dcf97954b
Removing intermediate container 531dcf97954b
---> 171917472c12
Step 3/3 : ENTRYPOINT echo "hello,$name"
---> Running in 176f9b4a07f1
Removing intermediate container 176f9b4a07f1
---> aac161403dbc
Successfully built aac161403dbc
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test:v1 #--rm 表示本次运行之后就会自动删除
hello,world
exec模式:
[root@server1 docker]# cat dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello,$name"]
[root@server1 docker]# docker build -t test:v1 .
Sending build context to Docker daemon 1.032MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Using cache
---> 171917472c12
Step 3/3 : ENTRYPOINT ["/bin/echo", "hello,$name"]
---> Running in 8d560ac187a9
Removing intermediate container 8d560ac187a9
---> 1e6e19156aa2
Successfully built 1e6e19156aa2
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test:v1
hello,$name #变量不会被解析
EXEC调用变量的写法:
[root@server1 docker]# cat dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh","-c", "echo hello,$name"]
[root@server1 docker]# vim dockerfile
[root@server1 docker]# docker build -t test:v1 .
Sending build context to Docker daemon 1.032MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Using cache
---> 171917472c12
Step 3/3 : ENTRYPOINT ["/bin/sh","-c", "echo hello,$name"]
---> Running in a695adb33f72
^[[ARemoving intermediate container a695adb33f72
---> 20779a8060c0
Successfully built 20779a8060c0
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test:v1
hello,world
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换,在shell格式时ENTRYPOINT会忽略任何CMD和docker run 提供的参数
FROM busybox
ENTRYPOINT ["/bin/echo", “ hello"]
CMD [“world”]
[root@server1 docker]# cat dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
[root@server1 docker]# docker build -t test:v1 .
Sending build context to Docker daemon 1.032MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENTRYPOINT ["/bin/echo", "hello"]
---> Running in 630bd1c4713b
Removing intermediate container 630bd1c4713b
---> dc953ab1563a
Step 3/3 : CMD ["world"]
---> Running in 6f8c56c21c79
Removing intermediate container 6f8c56c21c79
---> c644bf42cf64
Successfully built c644bf42cf64
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test:v1
hello world
[root@server1 docker]# docker run --rm test:v1 westos
hello westos
镜像的优化
镜像优化:
1.选择最精简的镜像基础
2.减少镜像层数
3.清空镜像构建的中间产物
4.优化网络请求
5.尽量用构建缓存
6.使用多阶段构建镜像(把debug关闭,可以编译最小nginx;把编译的过程放一个阶段,将编译后的二进制文件拷贝到新的镜像)
docker编译nginx
[root@server1 docker]# docker load -i rhel7.tar
[root@server1 docker]# ls
dockerfile nginx-1.15.8.tar.gz testfile yum.repo
[root@server2 docker]# vim dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.8.tar.gz /mnt
COPY yum.repo /etc/yum.repos.d/yum.repo
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.15.8
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] ##编译的数据都在/usr/local/nginx/sbin/nginx下
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v1 9494759d5de4 2 minutes ago 325MB ##编译的325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB #基础镜像
减少层数:
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.8.tar.gz /mnt
COPY yum.repo /etc/yum.repos.d/yum.repo
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && ./configure --prefix=/usr/local/nginx && make && make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t rhel7:v2 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v2 a0fc29e192b6 4 minutes ago 318MB ##减少层数后
rhel7 v1 9494759d5de4 26 minutes ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
清空镜像构建的中间产物
[root@server1 docker]# vim dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.8.tar.gz /mnt
COPY yum.repo /etc/yum.repos.d/yum.repo
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS=$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.15.8
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t rhel7:v3 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 a9b24470bc81 29 seconds ago 254MB
rhel7 v2 a0fc29e192b6 16 minutes ago 318MB
rhel7 v1 9494759d5de4 37 minutes ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
多阶段构建镜像
[root@server1 docker]# vim dockerfile
FROM rhel7 as build
ADD nginx-1.15.8.tar.gz /mnt
COPY yum.repo /etc/yum.repos.d/yum.repo
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS=$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.15.8
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t rhel7:v4 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v4 4c34cad083cc 32 seconds ago 141MB
rhel7 v3 a9b24470bc81 10 minutes ago 254MB
rhel7 v2 a0fc29e192b6 25 minutes ago 318MB
rhel7 v1 9494759d5de4 About an hour ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB