Docker容器學習梳理-Dockerfile構建鏡像


在Docker的運用中,從下載鏡像,啓動容器,在容器中輸入命令來運行程序,這些命令都是手工一條條往裏輸入的,沒法重複利用,並且效率很低。因此就須要一 種文件或腳本,咱們把想執行的操做以命令的方式寫入其中,而後讓docker讀取並分析、執行,那麼重複構建、更新將變得很方便,因此Dockerfile就此誕生了。Docker提供了Dockerfile做爲構建Docker鏡像腳本,避免人們一行一行的輸入,真是善莫大焉。Dockerfile腳本能夠作到隨時維護修改,便可以分享,更有利於在模板化,更不用說傳輸了,好處那是一大籮筐!下面就詳細介紹下Dockfile的使用:java


Dockfile是一種被Docker程序解釋的腳本,它由一條條的指令組成,每條指令對應Linux下面的一條命令。Docker程序將這些Dockerfile指令翻譯成真正的Linux命令。Dockerfile有本身書寫格式和支持的命令,Docker程序解決這些命令間的依賴關係,相似於Makefile。Docker程序將讀取Dockerfile,根據指令生成定製的image。相比image這種黑盒子,Dockerfile這種顯而易見的腳本更容易被使用者接受,它明確的代表image是怎麼產生的。有了Dockerfile,當咱們須要定製本身額外的需求時,只需在Dockerfile上添加或者修改指令,從新生成image便可,省去了敲命令的麻煩。linux


總的來講:nginx

Dockerfile分爲四部分:基礎鏡像信息、鏡像建立者信息、鏡像操做指令、容器啓動執行指令。git

一開始必需要指明所基於的鏡像名稱,接下來通常會說明鏡像建立者信息。後面則是鏡像操做指令github


1、Dockerfile的書寫規則及指令使用方法web

Dockerfile的指令是忽略大小寫的,建議使用大寫,使用 # 做爲註釋,每一行只支持一條指令,每條指令能夠攜帶多個參數。docker

Dockerfile的指令根據做用能夠分爲兩種:構建指令和設置指令。apache

構建指令用於構建image,其指定的操做不會在運行image的容器上執行;bootstrap

設置指令用於設置image的屬性,其指定的操做將在運行image的容器中執行。ubuntu

1)FROM(指定基礎image)
構建指令,必須指定且須要在Dockerfile其餘指令的前面。後續的指令都依賴於該指令指定的image。FROM指令指定的基礎image能夠是官方遠程倉庫中的,也能夠位於本地倉庫。
FROM命令告訴docker咱們構建的鏡像是以哪一個(發行版)鏡像爲基礎的。第一條指令必須是FROM指令。而且,若是在同一個Dockerfile中建立多個鏡像時,可使用多個 FROM 指令。
 
該指令有兩種格式:
FROM <image> 
指定基礎image爲該image的最後修改的版本。或者:
 
FROM <image>:<tag> 
指定基礎image爲該image的一個tag版本。
 
RUN後面接要執行的命令,好比,咱們想在鏡像中安裝vim,只需在Dockfile中寫入 RUN yum install -y vim
 
2)MAINTAINER(用來指定鏡像建立者信息)
構建指令,用於將image的製做者相關的信息寫入到image中。當咱們對該image執行docker inspect命令時,輸出中有相應的字段記錄該信息。
 
格式:
MAINTAINER <name> 
 
3)RUN(安裝軟件用)
構建指令,RUN能夠運行任何被基礎image支持的命令。如基礎image選擇了ubuntu,那麼軟件管理部分只能使用ubuntu的命令。
 
該指令有兩種格式:
RUN <command>  
RUN ["executable", "param1", "param2" ... ] 
 
4)CMD(設置container啓動時執行的操做)
設置指令,用於container啓動時指定的操做。該操做能夠是執行自定義腳本,也能夠是執行系統命令。該指令只能在文件中存在一次,若是有多個,則只執行最後一條。
 
該指令有三種格式:
CMD ["executable","param1","param2"]
CMD command param1 param2
 
當Dockerfile指定了ENTRYPOINT,那麼使用下面的格式:
CMD ["param1","param2"]
 
其中:
ENTRYPOINT指定的是一個可執行的腳本或者程序的路徑,該指定的腳本或者程序將會以param1和param2做爲參數執行。
因此若是CMD指令使用上面的形式,那麼Dockerfile中必需要有配套的ENTRYPOINT。
 
5)ENTRYPOINT(設置container啓動時執行的操做)
設置指令,指定容器啓動時執行的命令,能夠屢次設置,可是隻有最後一個有效。
 
兩種格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
 
該指令的使用分爲兩種狀況,一種是獨自使用,另外一種和CMD指令配合使用。
當獨自使用時,若是你還使用了CMD命令且CMD是一個完整的可執行的命令,那麼CMD指令和ENTRYPOINT會互相覆蓋,只有最後一個CMD或者ENTRYPOINT有效。
 
# CMD指令將不會被執行,只有ENTRYPOINT指令被執行 
CMD echo 「Hello, World!」 
ENTRYPOINT ls -l 
 
另外一種用法和CMD指令配合使用來指定ENTRYPOINT的默認參數,這時CMD指令不是一個完整的可執行命令,僅僅是參數部分;
ENTRYPOINT指令只能使用JSON方式指定執行命令,而不能指定參數。
 
FROM ubuntu 
CMD ["-l"] 
ENTRYPOINT ["/usr/bin/ls"] 
 
6)USER(設置container容器的用戶)
設置指令,設置啓動容器的用戶,默認是root用戶。
 
# 指定memcached的運行用戶 
ENTRYPOINT ["memcached"] 
USER daemon 
或者
ENTRYPOINT ["memcached", "-u", "daemon"] 
 
7)EXPOSE(指定容器須要映射到宿主機器的端口)
設置指令,該指令會將容器中的端口映射成宿主機器中的某個端口。當你須要訪問容器的時候,能夠不是用容器的IP地址而是使用宿主機器的IP地址和映射後的端口。
要完成整個操做須要兩個步驟,首先在Dockerfile使用EXPOSE設置須要映射的容器端口,而後在運行容器的時候指定-p選項加上EXPOSE設置的端口,這樣EXPOSE設置的端口號會被隨機映射成宿主機器中的一個端口號。
也能夠指定須要映射到宿主機器的那個端口,這時要確保宿主機器上的端口號沒有被使用。EXPOSE指令能夠一次設置多個端口號,相應的運行容器的時候,能夠配套的屢次使用-p選項。
 
格式:
EXPOSE <port> [<port>...] 
 
# 映射一個端口 
EXPOSE port1 
# 相應的運行容器使用的命令 
docker run -p port1 image 
   
# 映射多個端口 
EXPOSE port1 port2 port3 
# 相應的運行容器使用的命令 
docker run -p port1 -p port2 -p port3 image 
# 還能夠指定須要映射到宿主機器上的某個端口號 
docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
 
端口映射是docker比較重要的一個功能,緣由在於咱們每次運行容器的時候容器的IP地址不能指定而是在橋接網卡的地址範圍內隨機生成的。
宿主機器的IP地址是固定的,咱們能夠將容器的端口的映射到宿主機器上的一個端口,免去每次訪問容器中的某個服務時都要查看容器的IP的地址。
對於一個運行的容器,可使用docker port加上容器中須要映射的端口和容器的ID來查看該端口號在宿主機器上的映射端口。
 
8)ENV(用於設置環境變量)
主要用於設置容器運行時的環境變量
 
格式:
ENV <key> <value> 
 
設置了後,後續的RUN命令均可以使用,container啓動後,能夠經過docker inspect查看這個環境變量,也能夠經過在docker run --env key=value時設置或修改環境變量。
 
假如你安裝了JAVA程序,須要設置JAVA_HOME,那麼能夠在Dockerfile中這樣寫:
ENV JAVA_HOME /path/to/java/dirent
 
9)ADD(從src複製文件到container的dest路徑)
主要用於將宿主機中的文件添加到鏡像中
構建指令,全部拷貝到container中的文件和文件夾權限爲0755,uid和gid爲0;若是是一個目錄,那麼會將該目錄下的全部文件添加到container中,不包括目錄;
若是文件是可識別的壓縮格式,則docker會幫忙解壓縮(注意壓縮格式);若是<src>是文件且<dest>中不使用斜槓結束,則會將<dest>視爲文件,<src>的內容會寫入<dest>;
若是<src>是文件且<dest>中使用斜槓結束,則會<src>文件拷貝到<dest>目錄下。
 
格式:
ADD <src> <dest> 
 
<src> 是相對被構建的源目錄的相對路徑,能夠是文件或目錄的路徑,也能夠是一個遠程的文件url;
<dest> 是container中的絕對路徑
 
10)VOLUME(指定掛載點))
設置指令,使容器中的一個目錄具備持久化存儲數據的功能,該目錄能夠被容器自己使用,也能夠共享給其餘容器使用。咱們知道容器使用的是AUFS,
這種文件系統不能持久化數據,當容器關閉後,全部的更改都會丟失。當容器中的應用有持久化數據的需求時能夠在Dockerfile中使用該指令。
 
格式:
VOLUME ["<mountpoint>"]
 
例如:
FROM base 
VOLUME ["/tmp/data"]
 
運行經過該Dockerfile生成image的容器,/tmp/data目錄中的數據在容器關閉後,裏面的數據還存在。
例如另外一個容器也有持久化數據的需求,且想使用上面容器共享的/tmp/data目錄,那麼能夠運行下面的命令啓動一個容器:
docker run -t -i -rm -volumes-from container1 image2 bash
 
其中:container1爲第一個容器的ID,image2爲第二個容器運行image的名字。
 
11)WORKDIR(切換目錄)
設置指令,能夠屢次切換(至關於cd命令),對RUN,CMD,ENTRYPOINT生效。
 
格式:
WORKDIR /path/to/workdir 
 
# 在/p1/p2下執行vim a.txt 
WORKDIR /p1 WORKDIR p2 RUN vim a.txt 
 
12)ONBUILD(在子鏡像中執行)
 
格式:
ONBUILD <Dockerfile關鍵字> 
 
ONBUILD 指定的命令在構建鏡像時並不執行,而是在它的子鏡像中執行。


2、Dockerfile使用實例


1)利用dockerfile部署jdk1.7+tomcat7服務環境

1)查看docker宿主機鏡像
[root@localhost ~]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
docker.io/ubuntu               latest              0ef2e08ed3fa        6 weeks ago         130 MB
docker.io/centos               latest              67591570dd29        3 months ago        191.8 MB
docker.io/registry             2.2                 ad379b517aa6        14 months ago       224.5 MB
 
2)編寫Dockerfile
[root@localhost ~]# vim Dockerfile
# Pull base image 
FROM centos:latest

# Author Information
MAINTAINER docker dengaosky <dengaosky@qq.com>
   

# Install Basic env Soft
RUN yum install vim net-tools ntpdate wget initscripts -y

# Install JDK 8 
RUN mkdir -p /usr/java 
ADD jdk-8u92-linux-x64.tar.gz /usr/java/

#SET JAVA environment variable  
ENV JAVA_HOME /usr/java/jdk1.8.0_92
   
# Install tomcat8 
ADD apache-tomcat-8.0.15.tar.gz /usr/local/
#ADD tomcat-users.xml /usr/local/apache-tomcat-8.0.15/conf/tomcat-users.xml

# SET Tomcat environment variable  
ENV CATALINA_HOME /usr/local/apache-tomcat-8.0.15
ENV PATH $PATH:$CATALINA_HOME/bin 
 
# Create Tomcat Service Start Scripts 
ADD tomcat8.sh /etc/init.d/tomcat8 
RUN chmod 755 /etc/init.d/tomcat8
   
# Expose ports. 
EXPOSE 8080 
   
# Define default command. <三選一便可>
#CMD /usr/local/apache-tomcat-8.0.15/bin/catalina.sh run
#ENTRYPOINT service tomcat8 start && tail -f /usr/local/apache-tomcat-8.0.15/logs/catalina.out
ENTRYPOINT service tomcat8 start && tail -f /usr/local/apache-tomcat-8.0.15/logs/catalina.out

3)編寫tomcat8.sh
[root@localhost ~]# vim tomcat8.sh
#!/bin/bash

export JAVA_HOME=/usr/java/jdk1.8.0_92/
export TOMCAT_HOME=/usr/local/apache-tomcat-8.0.15
   
case $1 in 
start) 
  sh $TOMCAT_HOME/bin/startup.sh 
;; 
stop) 
  sh $TOMCAT_HOME/bin/shutdown.sh 
;; 
restart) 
  sh $TOMCAT_HOME/bin/shutdown.sh 
  sh $TOMCAT_HOME/bin/startup.sh 
;; 
esac 
 
4)構建鏡像
DOckerfile腳本寫好了,須要轉換成鏡像:
[root@localhost ~]# docker build -t dengaosky/jdk-tomcat --rm=true .
........
Removing intermediate container 6c54c575d743
Successfully built 1732044beee3
 
------------------------------------------------------------------------------------
其中:
-t    表示選擇指定生成鏡像的用戶名,倉庫名和tag
--rm=true    表示指定在生成鏡像過程當中刪除中間產生的臨時容器。
注意:上面構建命令中最後的.符號不要漏了,表示使用當前目錄下的Dockerfile構建鏡像
------------------------------------------------------------------------------------
 
以上構建命令執行後,能夠查看下鏡像是否構建成功
[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky/jdk-tomcat   latest              1732044beee3        2 minutes ago       741.6 MB
docker.io/centos       latest              ff426288ea90        3 weeks ago         207.2 MB
 
最後利用這個鏡像啓動容器
[root@localhost ~]# docker run -itd --name dengaosky-tomcat -p 8080:8080 dengaosky/jdk-tomcat /bin/bash
6bc4b44b5211497254efc2d90ac5f04ccc4b961377f5a96040ebff4a89fdd840
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
6bc4b44b5211        dengaosky/jdk-tomcat   "/bin/sh -c 'service "   6 seconds ago       Up 4 seconds        0.0.0.0:8080->8080/tcp   dengaosky-tomcat
 
進入容器,查看tomcat進程以及端口監聽狀態
[root@localhost ~]# docker exec -it dengaosky-tomcat /bin/bash 
[root@6bc4b44b5211 /]# ps -ef|grep tomcat
root         1     0  0 07:47 ?        00:00:00 /bin/sh -c service tomcat8 start && tail -f /usr/local/apache-tomcat-8.0.15/logs/catalina.out /bin/bash
root        23     1  3 07:47 ?        00:00:03 /usr/java/jdk1.8.0_92//bin/java -Djava.util.logging.config.file=/usr/local/apache-tomcat-8.0.15/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/apache-tomcat-8.0.15/endorsed -classpath /usr/local/apache-tomcat-8.0.15/bin/bootstrap.jar:/usr/local/apache-tomcat-8.0.15/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/apache-tomcat-8.0.15 -Dcatalina.home=/usr/local/apache-tomcat-8.0.15 -Djava.io.tmpdir=/usr/local/apache-tomcat-8.0.15/temp org.apache.catalina.startup.Bootstrap start
root        24     1  0 07:47 ?        00:00:00 tail -f /usr/local/apache-tomcat-8.0.15/logs/catalina.out
root        70    49  0 07:48 ?        00:00:00 grep --color=auto tomcat
[root@6bc4b44b5211 /]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      23/java             
tcp6       0      0 :::8009                 :::*                    LISTEN      23/java             
tcp6       0      0 :::8080                 :::*                    LISTEN      23/java             
[root@6bc4b44b5211 /]#

最後訪問http://本機ip:8080就能打開容器的tomcat頁面了

blob.png



Docker容器建立好以後,儘可能不要直接登錄容器內去修改。因此最好容器建立的時候進行目錄映射。這樣就能夠經過映射到宿主機上的文件或目錄去共享到容器內。

則上面的dengaosky-tomcat容器能夠以下調整操做:

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                    NAMES
c0812ad20bed        dengaosky/jdk-tomcat        "/bin/sh -c 'service "   7 seconds ago       Up 6 seconds        0.0.0.0:8899->8080/tcp   dengaosky-tomcat
 
[root@localhost ~]# docker cp dengaosky-tomcat:/usr/local/apache-tomcat-8.0.15/webapps /opt/  
 
[root@localhost ~]# docker run -itd --name dengaosky-tomcat -v /opt/webapps:/usr/local/apache-tomcat-8.0.15/webapps -p 8080:8080 dengaosky/jdk-tomcat /bin/bash
796b1e68b80e23443f674650a23c96291ba32ed51049ab7300113379c9e3b308
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
796b1e68b80e        dengaosky/jdk-tomcat   "/bin/sh -c 'service "   11 seconds ago      Up 10 seconds       0.0.0.0:8080->8080/tcp   dengaosky-tomcat
[root@localhost ~]# 
 
這樣讓須要修改dengaosky-tomcat容器的代碼或上線代碼時,只須要操做宿主機的/opt/webapps目錄便可。


------------------刪除docker images中爲none的鏡像----------------

常用Dockerfile製做鏡像,Docker build 命令執行後,因爲版本更新須要從新建立,那麼之前那個版本的鏡像就會成爲臨時鏡像,這就是none標籤的鏡像。,以下:
[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky/jdk-tomcat   latest              1732044beee3        19 minutes ago      741.6 MB
<none>                 <none>              85eb05c75724        29 minutes ago      207.2 MB
<none>                 <none>              73ce83c6b41d        27 minutes ago      207.2 MB
docker.io/centos       latest              ff426288ea90        3 weeks ago         207.2 MB
 
對於這些none標籤的images,能夠經過下面的腳本進行刪除(若是沒法刪除none的images,通常重啓docker服務後便可解決):
[root@localhost ~]# vim none_images_rm.sh
#!/bin/bash
docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop
docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm
docker images|grep none|awk '{print $3 }'|xargs docker rmi
 
[root@localhost ~]# sh none_images_rm.sh
 
[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky/jdk-tomcat   latest              1732044beee3        19 minutes ago      741.6 MB
docker.io/centos       latest              ff426288ea90        3 weeks ago         207.2 MB


2)再看一例tomcat容器鏡像的Dockerfile製做過程(centos爲base鏡像)

[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos       latest              ff426288ea90        3 weeks ago         207.2 MB
 
提早下載好tomcat和java安裝包,放在Docker宿主機的/usr/local/src目錄下:
[root@localhost src]# ls
apache-tomcat-8.5.16.tar.gz  Dockerfile  jdk-8u121-linux-x64.tar.gz
 
在/usr/local/src當前目錄下編輯Dockerfile。以下:
即將宿主機本地的tomcat和java安裝包拷貝到容器內,並自動解壓。
[root@localhost src]# vim Dockerfile
# Pull base image 
FROM centos:latest

# Author Information
MAINTAINER dengaosky <dengaosky@qq.com>

# Install Basic env Soft
RUN yum install vim net-tools ntpdate wget initscripts -y

# Install JDK 8 
ADD jdk-8u121-linux-x64.tar.gz /usr/local

# SET JAVA environment variable  
ENV JAVA_HOME /usr/local/jdk1.8.0_121
ENV PATH $JAVA_HOME/bin:$PATH
   
# Install tomcat8 
ADD apache-tomcat-8.5.16.tar.gz /usr/local
   
# Expose ports. 
EXPOSE 8080 
   
# Define default command. 
ENTRYPOINT /usr/local/apache-tomcat-8.5.16/bin/startup.sh  && tail -f /usr/local/apache-tomcat-8.5.16/logs/catalina.out
 
 
 
接着構建鏡像
[root@localhost src]# docker build -t dengaosky/jdk-tomcat --rm=true .
 
[root@localhost src]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky/jdk-tomcat   latest              f04c88789339        14 seconds ago      746.9 MB
docker.io/centos       latest              ff426288ea90        3 weeks ago         207.2 MB
 
根據製做的鏡像啓動tomcat容器
[root@localhost src]# docker run -itd --name tomcat-test -p 8080:8080 dengaosky/jdk-tomcat /bin/bash
36a1f47d662ec87280aa258737404a6f17e21da75f913d31c050f91af33ec277

[root@localhost src]# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
36a1f47d662e        dengaosky/jdk-tomcat   "/bin/sh -c '/usr/loc"   16 seconds ago      Up 14 seconds       0.0.0.0:8080->8080/tcp   tomcat-test
 
查看tomcat容器進程 
[root@localhost src]# docker exec -it tomcat-test /bin/bash
[root@36a1f47d662e /]# ps -ef|grep tomcat
root         1     0  0 08:46 ?        00:00:00 /bin/sh -c /usr/local/apache-tomcat-8.5.16/bin/startup.sh  && tail -f /usr/local/apache-tomcat-8.5.16/logs/catalina.out /bin/bash
root        13     1  7 08:46 ?        00:00:03 /usr/local/jdk1.8.0_121/bin/java -Djava.util.logging.config.file=/usr/local/apache-tomcat-8.5.16/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /usr/local/apache-tomcat-8.5.16/bin/bootstrap.jar:/usr/local/apache-tomcat-8.5.16/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/apache-tomcat-8.5.16 -Dcatalina.home=/usr/local/apache-tomcat-8.5.16 -Djava.io.tmpdir=/usr/local/apache-tomcat-8.5.16/temp org.apache.catalina.startup.Bootstrap start
root        14     1  0 08:46 ?        00:00:00 tail -f /usr/local/apache-tomcat-8.5.16/logs/catalina.out
root        78    61  0 08:47 ?        00:00:00 grep --color=auto tomcat


3)使用Dockerfile製做nginx鏡像

[root@localhost nginx]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos       latest              ff426288ea90        4 weeks ago         207.2 MB
 
製做Dockerfile
[root@localhost nginx]# vim Dockerfile
#Pull down centos image
FROM centos

#Author Informations
MAINTAINER dengaosky dengaosky@docker.com
 
#Install nginx
RUN yum install zlib zlib-devel pcre pcre-devel openssl openssl-devel gcc gcc+ wget vim net-tools -y 
RUN useradd www -M -s /sbin/nologin
RUN cd /usr/local/src && wget http://nginx.org/download/nginx-1.12.2.tar.gz && tar -zxvf nginx-1.12.2.tar.gz
RUN cd /usr/local/src/nginx-1.12.2 && ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module && make && make install

#Expose ports. 
EXPOSE 80
 
#Define defaults Command
ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log


---------------------------------------------------------------------------------------------------------------------

特別須要注意的:

在Docker daemon模式下,不管你是使用ENTRYPOINT,仍是CMD,最後的命令,必定要是當前進程須要一直運行的,纔可以防容器退出。

也就是說,上面Dockerfile腳本中最後一行:


如下無效方式:

ENTRYPOINT /usr/local/nginx/sbin/nginx             #運行幾秒鐘以後,容器就會退出

或者

CMD /usr/local/nginx/sbin/nginx             #運行幾秒鐘以後,容器就會退出


如下才是有效方式:

ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log     #確保容器內的進程一直運行

或者

CMD /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log       #確保容器內的進程一直運行


其餘應用程序鏡像建立的Dockerfile配置相似

------------------------------------------------------------------------------------------------------------------


Dockerfile寫好了,須要轉換成鏡像:

構建鏡像
[root@localhost nginx]# docker build -t dengaosky/nginx --rm=true .
 
[root@localhost nginx]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
dengaosky/nginx               latest              4f6014d3c971        3 minutes ago       442.8 MB
docker.io/centos              latest              ff426288ea90        4 weeks ago         207.2 MB
 
根據Dockerfile構建的鏡像啓動nginx容器
[root@localhost nginx]# docker run -ti -d --name test_nginx -p 80:80 dengaosky/nginx /bin/bash
e6b6d581b6a1ed0900b4be5d7c9fee7ae108d1f45b25357306b576fa9f84ca1a
[root@localhost nginx]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
e6b6d581b6a1        dengaosky/nginx     "/bin/sh -c '/usr/loc"   7 seconds ago       Up 6 seconds        0.0.0.0:80->80/tcp   test_nginx
 
進入容器,檢查容器內的nginx程序是否已啓動
[root@localhost nginx]# docker exec -ti test_nginx /bin/bash
[root@e6b6d581b6a1 /]# ps -ef|grep nginx
root         1     0  0 03:02 ?        00:00:00 /bin/sh -c /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log /bin/bash
root         6     1  0 03:02 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
www          7     6  0 03:02 ?        00:00:00 nginx: worker process
root         8     1  0 03:02 ?        00:00:00 tail -f /usr/local/nginx/logs/access.log
root        25     9  0 03:02 ?        00:00:00 grep --color=auto nginx
[root@e6b6d581b6a1 /]#


經過映射到Docker宿主機的端口80去訪問容器的nginx

blob.png


建立好的鏡像,能夠保存到索引倉庫中,便於下次使用(固然,咱們直接共享Dockerfile,是最簡單的事情,:)) ),但畢竟鏡像能夠作到開箱即用。

登錄https://hub.docker.com/  註冊一個帳號
  
而後登錄
[root@localhost nginx]# 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: dengao
Password: 
Login Succeeded
[root@localhost nginx]#
  
提交到Docker索引倉庫
注意下面提交的鏡像路徑,即"用戶名/鏡像",只有這樣才能成功提交。
因此在Dockerfile製做鏡像的時候,倉庫名最好用docker索引倉庫的用戶名,也即"用戶名/鏡像"
[root@localhost nginx]# docker push dengao/jdk-tomcat
The push refers to a repository [docker.io/dengao/jdk-tomcat]
7841a0719a03: Pushed 
c9ec27eb9aa1: Pushed 
dc40446c1078: Pushed 
e15afa4858b6: Pushed 
latest: digest: sha256:10433028d3ff2f1a7554c0465d1c703505e5aed86eb48baf37b605547649f68f size: 1165
[root@localhost nginx]# 
  
這樣下次想用的時候,能夠直接從Docker索引倉庫裏下載
docker pull dengao/jdk-tomcat

------------------------Dockerfile製做多應用程序鏡像的實例---------------------------------------------------------

能夠參考:http://dockerfile.github.io/


須要注意幾點:

1)Docker宿主機必需要有base鏡像以供Dockerfile文件使用

2)注意Dockerfile實例文件中的base鏡像,這個引用的base鏡像必定要是存在的

3)能夠切換到不一樣的目錄路徑下編寫Dockerfile,而後構建,構建的時候直接使用.表示在當前路徑下。

鏡像構建成功後,能夠放到本身的私有倉庫裏,而後Dockerfile文件能夠選擇刪除。

-----------------------------------------------------------------------------------------------------------------------

相關文章
相關標籤/搜索