DockerFile詳解
1、DockerFile基本介紹
DockerFile是用來構建Docker鏡像文件,是由一系列命令和參數構成的腳本。
構建步驟:
- 編寫一個Dockerfile文件
- docker build 構建成爲一個鏡像
- docker run運行一個鏡像
- docker push 發佈鏡像(Docker Hub,阿里雲倉庫)
可以看到從Docker Hub點擊某個鏡像的某個版本號,進去之後看到就是Dockerfile文件,以CentOS 7爲例:
2、DockerFile構建過程
基礎:
- 每條保留字指令必須爲大寫字母,且後面至少要跟隨一個參數
- 指令按照從上到下,順序執行
- #表示註釋
- 每條指令都會創建一個新的鏡像層,並對鏡像進行提交
從應用軟件的角度看,DockerFile、Docker鏡像與Docker容器分別代表軟件的三個不同階段:
- DockerFile是軟件的原材料
- Docker鏡像是軟件的交付品
- Docker容器則可以認爲是軟件的運行態。
DockerFile面向開發,Docker鏡像成爲交付標準,Docker容器則涉及部署與運維,三者缺一不可,合力充當Docker體系的基石。
詳細解釋:
- DockerFile,需要定義一個DockerFile,DockerFile定義了進程需要的一切東西。DockerFile涉及的內容包括執行代碼或者是文件、環境變量、依賴包、運行時環境、動態鏈接庫、操作系統的發行版、服務進程和內核進程(當應用進程需要和系統服務和內核進程打交道,這是需要考慮如何涉及namespace的權限控制)等到。
- Docker鏡像,在用DockerFile定義一個文件後,docker build會產生一個Docker鏡像,當運行Docker鏡像時,會真正開始提供服務。
- Docker容器,容器直接提供服務。
3、DockerFile保留關鍵字
FROM #基礎鏡像,當前鏡像是基於哪個鏡像的
MAINTAINER #鏡像作者 姓名+郵箱
RUN #容器構建是需要運行的命令(構建鏡像中執行一些命令,如Redis的DockerFile中的run命令建立用戶組)
ADD #將宿主機目錄下的文件拷貝進鏡像,且 ADD命令會自動處理URL和解壓tar文件
COPY #類似ADD,拷貝文件和目錄到鏡像中。將從構建上下文目錄<源路徑>的文件/目錄複製到新的一層的鏡像內<目標路徑>位置。
VOLUME #容器數據卷,用於數據保存和持久化工作
CMD #指定容器啓動時要運行的命令。DockerFile中可以有多個CMD指令,但只有最後一個生效(覆蓋),CMD會被docker run 之後的參數替換
ENTRYPOINT #指定容器啓動時要運行的命令。ENTRYPOINT的目的和CMD一樣,都是在指定容器啓動程序以及參數(但是不會被覆蓋)
EXPOSE #當前容器對外暴露的端口
WORKDIR #指定在創建容器後,終端默認登錄(啓動後的工作目錄)進來的工作目錄,一個落腳點
ENV #用來在構建鏡像過程中設置環境變量
ONBUILD #當構建一個被集成的DockerFile時運行命令,父鏡像在被子集成後父鏡像的ONBUILD被觸發
補充:
ENV設置環境變量:
ENV MY_PATH /usr/mytest #設置一個環境變量
這個環境變量可以在後續的任何RUN指令中使用,這就如同在命令前面指定了環境變量前綴一樣;也可以在其它指令中直接使用這些環境變量,比如WORKDIR $MY_PATH #在此處使用該環境變量來指定工作目錄
COPY兩種寫法:
COPY src desc
COPY ["SRC","dest"]
注意:CMD會被docker run之後的參數替換
4、DockerFile案例
常見的如CentOS中都有FROM scratch,其中的scratch就是Base鏡像,相當於java中的Object。
1)案例一:CentOS
默認pull下的CentOS很多命令沒有而且工作目錄在根目錄,此處修改這些配置:
1、編寫dockerfile文件
FROM centos #基於centos構建
MAINTAINER miracle<****@qq.com>
ENV MYPATH /usr/local #將環境遍歷
WORKDIR $MYPATH #將默認登錄進來的工作目錄設爲MYPATH
RUN yum -y install vim #安裝yum
RUN yum -y install net-tools #安裝包含ifconfig的包
EXPOSE 80 #設置暴露的端口爲80
CMD echo $MYPATH
CMD echo --------end--------
CMD /bin/bash
2、根據dockerfile文件構建鏡像
#命令
docker build -f dockerfile文件路徑 -t 鏡像名 .
[root@Eva dockerfile]# docker build -f centos.dockerfile -t mycentos:0.1 .
3、測試運行生成的鏡像,可以看看到默認的工作路徑是/usr/local。而且vim和ifconfig命令都可以使用
[root@Eva dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 18601a7f4f0d 2 minutes ago 317MB
[root@Eva dockerfile]# docker run -it 18601a7f4f0d bash
[root@b9c0c04dd0f1 local]# pwd
/usr/local
[root@b9c0c04dd0f1 local]# vim abc
[root@b9c0c04dd0f1 local]# ls
abc bin etc games include lib lib64 libexec sbin share src
[root@b9c0c04dd0f1 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 02:42:ac:12:00:06 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
使用history命令可以查看鏡像構建的過程
docker history 鏡像名 #查看鏡像結構(歷史)
CMD 和 ENTRYPOINT區別
CMD # 指定這個容器啓動的時候要運行的命令,只有最後一個會生效,可被替代。
ENTRYPOINT # 指定這個容器啓動的時候要運行的命令,可以追加命令
測試CMD:
# 編寫dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 構建鏡像
$ docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
# 運行鏡像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
# 想追加一個命令 -l 成爲ls -al
$ docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
# cmd的情況下 -l 替換了CMD["ls","-l"]。 -l 不是命令所有報錯
測試ENTRYPOINT:
# 編寫dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我們的命令,是直接拼接在我們得ENTRYPOINT命令後面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 16 06:32 dev
drwxr-xr-x 1 root root 4096 May 16 06:32 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....
2)案例二:Tomcat
從頭開始構建一個Tomcat鏡像
1、準備鏡像文件
準備tomcat 和 jdk到當前目錄,編寫好README
2、編寫dockerfile文件:vim DockerFile
FROM centos
MAINTAINER Miracle42<*****@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u221-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.56.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java和tomcat環境遍歷
ENV JAVA_HOME /usr/local/jdk1.8.2_21
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.56
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.56
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.56/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.56/bin/logs/catalina.out
3、構建鏡像
docker build -f Dockerfile -t mytomcat .
#由於Dockerfile命名爲Dockerfile所以也可以使用下面的命令進行構建
docker build -t mytomcat .
4、運行鏡像
#將webapp掛載都宿主機
docker run -p 8080:8080 -d --name mytomcat -v /root/dockerfile/tomcat_build/webapps:/usr/local/apache-tomcat-8.5.56/webapps mytomcat
5、部署項目
在本機webapps下創建文件夾test,再創建index.html
[root@Eva webapps]# mkdir test
[root@Eva webapps]# cd test/
[root@Eva test]# vim index.html
[root@Eva test]# cat index.html
<h1>hello world</h1>
[root@Eva test]# pwd
/root/dockerfile/tomcat_build/webapps/test
[root@Eva test]# curl localhost:8080/test/
<h1>hello world</h1>
訪問 localhost:8080/test/
5、發佈自己的鏡像
1)Docker Hub
1、在Docker Hub網站上創建並登錄Docker Hub
2、在自己服務器上登錄Docker
[root@Eva test]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: miracle42
Password:
Login Succeeded
3、將自定義鏡像Push到Docker Hub
docker push mytomcat
# 可能會push不上去,因爲如果沒有前綴的話默認是push到 官方的library
# 解決方法
# 第一種 build的時候添加你的dockerhub用戶名,然後在push就可以放到自己的倉庫了
$ docker build -t chengcoder/mytomcat:0.1 .
# 第二種 使用docker tag #然後再次push
$ docker tag 容器id chengcoder/mytomcat:1.0 #然後再次push
2)阿里雲
1、註冊登錄阿里雲
2、進入容器鏡像服務
3、設置Registry登陸密碼
4、填寫相關信息創建鏡像倉庫
5、按照提示的步驟進行鏡像發佈
測試:
[root@Eva test]# docker login --username=miralce42 registry.cn-beijing.aliyuncs.com
Password:
Login Succeeded
[root@Eva test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest f4fea7cfb67c 4 hours ago 716MB
[root@Eva test]# docker tag f4fea7cfb67c registry.cn-beijing.aliyuncs.com/miracle42/tomcat:1.0
[root@Eva test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-beijing.aliyuncs.com/miracle42/tomcat 1.0 f4fea7cfb67c 5 hours ago 716MB
[root@Eva test]# docker push registry.cn-beijing.aliyuncs.com/miracle42/tomcat:1.0
The push refers to repository [registry.cn-beijing.aliyuncs.com/miracle42/tomcat]
6c2556c201c2: Pushed
359464d6ef75: Pushed
823ea308519e: Pushed
af018e0f901e: Pushed
0683de282177: Pushed
1.0: digest: sha256:3c5f059a96e5fcbe27213027ba2d76607820eda9c7028b2279f6675a11146452 size: 1373
接下來就可以在阿里雲中看到push的鏡像