3、DockerFile 定製屬於本身的專屬鏡像

前言

上篇文章咱們知道了怎麼操做鏡像和容器,到基礎都是從已經存在的鏡像開始的,那咱們本身怎樣搭建一個鏡像並使用它呢?接下來就讓咱們學習使用dockerfile 建立屬於本身的鏡像吧。java

dockerfile

在這以前,咱們須要知道dockerfile ,由於咱們就是經過dockerfile 來建立鏡像的。那dockerfile 是什麼呢?
dockerfile 是一個文件,文件裏面是咱們寫的一條條的指令,而後經過docker build
命令來構建一個鏡像。
如今難就難在這個指令怎麼寫,因此接下讓咱們一塊兒看看dockfile 指令吧。linux

dockerfile 指令

讓咱們先來了解一些基本的 dockerfile 指令吧程序員

FROM

FROM <image>
FROM <image>:<tag>
#tag是可選的,默認會使用latest版本的基礎鏡像

from 指令是依賴的基礎鏡像,所謂的定製鏡像,是在其餘的鏡像上添加一些咱們本身東西,定製成咱們本身的鏡像。固然咱們也能夠不依賴任何鏡像,本身從頭開始搭建。那就使用
FROM scratch
scratch 其實也是一個docker 鏡像,可是這個鏡像比較難特殊,它是一個虛擬鏡像,裏面什麼都沒有,是一個空白的鏡像,因此若是想不依賴任何鏡像,能夠使用from scratchspring

那如今又有一個問題了,dockfile 文件中能夠出現多個From 麼?docker

在docker 17.05 版本以前是不支持出現多個From 的,一個dockefile只能有一個From 指令,且必須放在文件中的第一行。由於做爲基礎鏡像使用。在docker17.05 後支持多From 。表示構建的多重階段,不過最終生成的鏡像仍是以最後一個From 基礎鏡像爲基礎的。shell

RUN

run 指令 是表示在鏡像構建時運行的指令。
兩種格式:vim

#shell格式
run <命令>
eg: run apt-get update

#exec 格式
run ["可執行文件",「參數1」,「參數2」...]

COPY

複製文件的指令api

copy 源路徑  目標路徑
#支持通配符
eg:copy hom?.txt /mydir/

ADD

add 是更高級的複製。copy 有的功能它都用,它還能訪問網絡資源,源路徑能夠是一個URL。源路徑文件也能夠是一個壓縮文件,能夠直接解壓。
因此若是想要直接複製一個壓縮包進去的話,就要使用COPY 而不能只用ADD了。
官方建議是能使用COPY 的就使用COPY ,由於COPY 命令語義比較明確就是複製文件,而且ADD 指令會使得鏡像構建緩存失效,使得鏡像構建比較緩慢。瀏覽器

CMD

cmd 指令是表示在運行容器時執行的指令。緩存

#shell 格式
cmd  <命令>
eg:cmd echo $HOME

#exec 格式
cmd ["可執行文件",「參數1」,「參數2」]
eg: cmd ["sh","-c","echo $HOME"]

ENTRYPOINT

entrypoint 入口點

entrypoint <命令>

entrypoint ["可執行文件","參數1","參數2"]

entryPoint 指令和 cmd 指令功能相似,不過entrypoint 可讓鏡像變成像命令同樣使用,能夠作應用運行前的準備工做。這個具體的後面講。

ENV

env 是設置環境變量的指令,

env MY_VERSION 1.0.0

ARG

arg 用於構建時傳遞的參數

arg <參數名>[=<默認值>]

eg: 
arg version
arg myversion=1.0.0

VOLUME

定義匿名卷

volume <路徑>
volume ["<路徑1>",["<路徑2>"...]

eg: volume  /etc/docker/log

EXPOSE

申明端口

expose <端口1>  [<端口2>...]

這裏須要注意的是,expose 是申明容器應用端口,可是容器運行是並不必定就是開啓這個端口提供服務。在dockerfile 中寫入端口申明有兩個好處,一是當作鏡像服務的守護端口,方便映射,二是在運行時使用隨機端口映射時,就會映射的expose設置的端口上。

好了,指令固然不止這些,更多的想了解的查看:

https://docs.docker.com/engine/reference/builder/

簡單測試

以前這篇文章寫到一半放下了,由於中間docker出了一點問題,下載鏡像一直提示超時,而後設置了國內加速,才弄好。
上面咱們瞭解了Dockerfile 指令,接下來就讓咱們先作一個簡單的測試吧。
咱們穿件一個springboot項目。建立一個HelloController 類。

@RestController
public class HelloController {
    @RequestMapping("/")
    public String hello(){
        return "hello docke 個人簡單測試 ";
    }
}

而後打成jar 包。放到咱們服務器的文件夾下。
而且在文件下建立Dockerfile文件

vim Dcokerfile

#文件內容
FROM java:8
VOLUME /tmp
ADD hello-1.0.0.jar hello-1.0.0.jar
ENTRYPOINT ["java","-jar","/hello-1.0.0.jar"]

能夠看到用到的命令都是咱們上面介紹的。java8做爲基礎鏡像,/tmp做爲數據卷, add 將本地jar包添加到鏡像中,entrypoint 運行咱們的jar包。

file

在該目錄下構建鏡像如今,最後面的點別忘記了。

docker build -t helle:v1 .

file
能夠看到咱們的鏡像分4不構建,也就是構建四個鏡像,由於咱們Dockerfile 中有四條指令。前面說了後一條指令是在前一條指令的基礎上構建鏡像的。因此這四個鏡像中前面三個就是中間鏡像了。

咱們如今看看咱們建立的鏡像。
file

咱們接下來啓動鏡像

docker run -d -p 8090:8080 hello:v1

file
其中 -d 是後臺啓動,-p 是映射端口,前面的是咱們設置的端口,後面是項目運行的端口。
啓動後咱們在瀏覽器上訪問下。

http://192.168.252.53:8090

file

這樣咱們經過docker 構建咱們springboot 的項目,建立屬於咱們本身的鏡像就完成了。

配置docker遠程訪問

咱們如今要作的是,直接經過idea打包生成docker鏡像。因此,第一步開啓docker的遠程訪問,個人docker 是安裝到服務器上的。我先在本地檢測一下,服務器上的docker 是否開啓的遠程訪問。

docker -H 192.168.252.53 info

file
說明是沒有開啓docker的遠程服務的。因此進入服務器。
執行以下操做,在docker.service. 文件夾下建立一個http-proxy.conf文件.

sudo mkdir /etc/systemd/system/docker.service.d
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf

文件內容

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

而後重啓daemon和docker

sudo systemctl daemon-reload
sudo systemctl restart docker

而後咱們再 在本地測試一下。說明docker 的遠程訪問已經配置好了。
file

idea配置

咱們打開咱們的hello 項目,在pom.xml 中增長配置

<properties>
        <java.version>1.8</java.version>
        <docker.image.prefix>quellanan</docker.image.prefix>
</properties>

在build 中增長。

<!-- Docker -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!-- 將插件綁定在某個phase執行 -->
                <executions>
                    <execution>
                        <id>build-image</id>
                        <!-- 用戶只需執行mvn package ,就會自動執行mvn docker:build -->
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- 指定生成的鏡像名 -->
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <!-- 指定標籤 -->
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                    </imageTags>
                    <!-- 指定 Dockerfile 路徑 -->
                    <dockerDirectory>src/main/docker</dockerDirectory>
                    <!-- 指定遠程 docker api地址 -->
                    <dockerHost>http://192.168.252.53:2375</dockerHost>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <!-- jar包所在的路徑此處配置的對應target目錄 -->
                            <directory>${project.build.directory}</directory>
                            <!-- 須要包含的jar包,這裏對應的是Dockerfile中添加的文件名 -->
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

在src/main/docker 中建立Dockerfile 文件,文件內容上面Dockerfile 內容同樣

FROM java:8
VOLUME /tmp
ADD hello-1.0.0.jar hello-1.0.0.jar
ENTRYPOINT ["java","-jar","/hello-1.0.0.jar"]

file

mvn package

由於咱們配置在構建的時候就會進行docker 打包。因此咱們知己運行mvn package

file
控制檯查看是打包成功的。
咱們去服務器上看下,有沒有
file
能夠看到已經成功了。

番外

這篇總算寫完啦算是,中間本身親自試驗,踩了一路坑,也算是初步弄好了。之後咱們項目不用將jar 包放到服務器上再來建立鏡像了,能夠直接在咱們項目中打包構建鏡像就想構建jar 包同樣簡單。仍是能夠的吧。

好了,就說這麼多啦

後續加油♡

歡迎你們關注我的公衆號 "程序員愛酸奶"

分享各類學習資料,包含java,linux,大數據等。資料包含視頻文檔以及源碼,同時分享本人及投遞的優質技術博文。

若是你們喜歡記得關注和分享喲❤

file

相關文章
相關標籤/搜索