一、Dokcer簡介
官方介紹:
? Docker 是一個開源的應用容器引擎,基于Go 語言并遵從 Apache2.0 協議開源,
? Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的 Linux 機器上,也可以實作虛擬化,
? 容器是完全使用沙箱機制,相互之間不會有任何介面(類似 iPhone 的 app),更重要的是容器性能開銷極低,
? Docker的構想是要實作“Build, Ship and Run Any App, Anywhere”,即通過對應用的封裝(Packaging)、分發(Distribution)、部署(Deployment)、運行生命周期(Runtime)進行管理,達到應用組件級別的“一次封裝,到處運行”,
本人理解:
? 我們在開發到上線一個程式的時候需要接觸很多環境,比如:開發環境(一般是在自己電腦)、測驗環境、生產環境,在不同的環境中我們開發出的程式可能出現一些問題,可能在自己電腦上可以跑的程式,到了其它機器上就會因為環境不同而出現一些問題,而且換到不同的機器上我們就需要重新配置環境,例如下圖所示,所以我們就想,如果能把環境一起打包運行,那樣不就可以解決不同運行環境的問題了,使用Docker就可以解決這樣的問題,我們可以使用Docker將程式以及環境打包為一個鏡像,并上傳到遠程倉庫,當需要在其它機器上運行時,只需要將鏡像從遠程倉庫拉取下來直接運行即可,

? Docker是一個C/S架構的軟體,Docker會啟動一個守護行程用來接收客戶端的命令并執行相應的命令,比如:docker run 鏡像名,可以根據一個鏡像運行一個容器,
1、Docker中的名詞概念
鏡像(Image):
? Docker中的鏡像就像是一個只讀的模板,比如作業系統鏡像,我們可以使用作業系統鏡像來安裝一個作業系統;又像是面向物件中的類,通過類我們可以創建一個物件,鏡像是可以復用的,我們可以通過Docker運行一個鏡像實體,運行起來的鏡像就是一個容器,
容器(Container):
? Docker容器類似一個輕量級的沙箱,Docker利用容器技術來運行和隔離應用,容器是從鏡像創建的應用運行實體,它可以啟動、開始、停止、洗掉,而這些容器都是彼此相互隔離、互不可見的,
? 可以把容器看作一個簡易版的Linux系統環境(包括root用戶權限、行程空間、用戶空間和網路等)以及運行在其中的應用程式打包而成的盒子,
倉庫(Repository)
? Docker倉庫類似代碼倉庫,是Docker集中存放鏡像檔案的倉庫,倉庫分為私有倉庫和公有倉庫,可以通過Docker從倉庫中拉取一個鏡像,也可以上傳自己的鏡像,目前最大的公開倉庫是官方提供的Docker Hub,就像Github一樣,Docker Hub存放了很多官方的或者非官方的鏡像,例如:nginx鏡像、redis鏡像等,官網:https://hub.docker.com/
如下圖,下圖中包含了三部分,分別時Docker客戶端、Docker守護行程以及遠程倉庫,Docker客戶端可以接收命令并通知Docker守護行程來進行一系列的操作,比如拉取鏡像、運行容器等,Docker守護行程將會管理鏡像以及容器,遠程倉庫存放了很多種不同的鏡像,

Docker的安裝:Ubuntu20.04安裝Docker_Peerless__的博客-CSDN博客
二、Docker基本使用
在使用下面的命令時,可以加引數 --help 來查看幫助檔案,例如dokcer run --help:
下面顯示了docker run命令的使用方式以及其它的可選引數和其解釋,

1、鏡像
1.1 查看鏡像
docker images

使用docker images命令可以查看本機已經存在的鏡像,分別顯示了鏡像名、標簽(版本資訊)、鏡像ID、創建時間以及鏡像的大小,
除此之外,還有一些可選引數,可以通過docker images --help 命令來查看,下面兩個是比較常用的引數:
# -a引數,顯示所有的鏡像 docker images -a
-a, --all Show all images (default hides intermediate images)
# -q引數,只顯示鏡像ID
-q, --quiet Only show image IDs
1.2 給鏡像設定標簽
docker tag sourname:tag desname:tag
#例如:
docker tag ubuntu:18.04 myubuntu:lastest
1.3 搜索鏡像
docker search 鏡像名
#引數:
# 過濾輸出內容
-f, --filter filter Filter output based on conditions provided
# 限制輸出個數
--limit int Max number of search results (default 25)
# 例如
docker search --filter=is-official=true mysql # 搜索mysql官方鏡像
docker search --filter=stars=200 mysql # 搜索star大于200的mysql鏡像
docker search --limit 5 mysql # 只顯示5個輸出

使用docker search可以從遠程倉庫搜索鏡像,上面顯示了鏡像名、描述、stars、是否是官方鏡像等資訊,
1.4 拉取鏡像
docker pull 鏡像名
docker pull 鏡像名:tag
#例如
docker pull mysql # 不加tag,將會拉取最新版本
docker pull mysql:5.7 # 拉取5.7版本的mysql
在鏡像名后可以指定拉取的版本,如果不指定就會拉取最新版本,關于鏡像的版本可以到docker hup來搜索,網址:https://hub.docker.com/

1.5 洗掉鏡像
使用下面命令可以洗掉本機倉庫中的一個鏡像,rmi ==> remove image
docker rmi 鏡像名 或 鏡像ID
#例如 docker rmi centos 或 docker rmi 9f266d35e02c , 命令Docker images可以查看鏡像ID
引數:
# 強制洗掉,類似linux命令 rm -f
-f, --force Force removal of the image
# 如果要洗掉所有的鏡像可以使用以下命令, docker images -aq 會顯示所有鏡像的ID
docker rmi `docker images -aq` 或
docker rmi $(docker images -aq)
1.6 匯出和載入鏡像
Docker鏡像的save和load命令可以將鏡像匯出到本地以及加載本地鏡像到鏡像庫,使用save命令可以將鏡像匯出到本地,這樣就可以跟別人分享自己的鏡像,當然也可以提交到遠程倉庫,將在后面介紹,通過load命令則可以加載別人分享的鏡像,
docker save -o 生成的鏡像名 鏡像
# 例如
docker save -o mysql5_7.tar mysql:5.7
docker load -i 本地鏡像名 或者
docker load < 本地鏡像名
2、容器
2.1 運行容器
docker run 鏡像名
引數:
-d, --detach Run container in background and print container ID 后臺運行容器
-e, --env list Set environment variables 設定環境變數
--expose list Expose a port or a range of ports 暴露埠
-i, --interactive Keep STDIN open even if not attached 互動模式
--name string Assign a name to the container 給當前運行的容器指定名字
-p, --publish list Publish a container's port(s) to the host 指定埠映射
-P, --publish-all Publish all exposed ports to random ports 隨機指定暴露的埠映射
-t, --tty Allocate a pseudo-TTY 分配一個終端
-v, --volume list Bind mount a volume 掛載資料卷
--volumes-from list Mount volumes from the specified container(s) 從一個資料卷容器掛載目錄
-w, --workdir string Working directory inside the container 指定容器中的作業目錄
我們可以使用互動模式來運行一個容器,例如下面命令:
docker run -it --name c1 centos /bin/bash

-t選項讓Docker分配一個偽終端并系結到容器的標準輸入上,-i則讓容器的標準輸入保持打開,–name給容器指定名字,centos為創建容器使用的鏡像,/bin/bash為容器中運行的終端,如果鏡像不存在,Docker會從遠程倉庫拉取,然后再運行,如下圖,運行容器后發現終端發生了變化,說明我們已經進入了容器,用戶為root用戶,@后的一串字符為當前容器的ID,可以使用ls命令來查看當前目錄下的檔案,

輸入exit命令可以退出當前容器,
使用docker ps -a來查看所有容器,發現剛剛運行的容器在退出后就停止運行了,對于所創建的bash容器,當用戶使用exit命令退出bash行程后,容器也會自動退出,這是因為對于容器來說,當其中的應用退出后,容器的使命完成,也就沒有運行的必要了,

使用 Ctrl + p + q來退出容器可以讓容器在后臺繼續運行,
我們可以在啟動時讓容器在后臺運行,這樣在退出容器后,容器會繼續運行,
docker run -id --name c2 centos

運行后,輸出了運行的容器的ID,使用docker ps -a命令來查看所有容器,發現剛剛啟動的容器還在運行
可以使用下面的命令進入容器:
docker exec -it c2 /bin/bash 或
docker exec -it 29f35e8928c5 /bin/bash

在進入容器并退出后發現,c2容器依然在運行,
當利用docker run來創建并啟動容器時,docker在后臺運行的標準操作包括:
- 檢查本地是否存在指定的鏡像,不存在就從遠程倉庫下載;
- 利用鏡像創建一個容器,并啟動該容器;
- 分配一個檔案系統給容器,并在只讀的鏡像層外面掛載一層可讀寫層;
- 從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去;
- 從網橋的地址池配置一個IP地址給容器;
- 執行用戶指定的應用程式;
- 執行完畢后容器被自動終止,
2.2 查看容器
docker ps
引數:
# 查看所有容器
-a, --all Show all containers (default shows just running)
# 只顯示容器ID
-q, --quiet Only display container IDs
使用docker ps可以查看容器,類似linux的ps命令查看行程,不加引數只會顯示當前正在運行的容器,-a引數可以顯示所有容器,-q只顯示容器ID,如果要洗掉所有容器就可以使用該引數了,類似洗掉全部鏡像,
2.3 停止容器
1)暫停容器
# 暫停容器
docker pause 容器名 或 ID
# 繼續運行暫停的容器
docker unpause 容器名 或 ID
2)終止容器
docker stop 容器名 或 ID

該命令會首先向容器發送SIGTERM信號,等待一段超時時間后(默認為10s),再發送SIGKILL信號來終止容器,
2.4 啟動容器
docker start 容器名 或 ID

# 重啟容器,先終止再啟動
docker restart 容器名 或 ID
2.5 洗掉容器
docker rm 容器名 或 ID
引數:
#強制洗掉容器
-f, --force Force the removal of a running container (uses SIGKILL)
容器在運行時使用docker rm無法洗掉,需要加-f引數才可,
如果要洗掉所有容器,也可以使用類似洗掉所有鏡像的命令:
docker rm `docker ps -aq` 或
docker rm $(docker ps -aq)
2.6 匯入和匯出容器
某些時候,需要將容器從一個系統遷移到另外一個系統,此時可以使用Docker的匯入和匯出功能,
1)匯出容器
匯出容器是指,匯出一個已經創建的容器到另一個檔案,不管這個容器是否處于運行狀態,
docker export -o exportname 容器名 或
docker export 容器名 > exportname
# 例如
docker export -o test_for_run.tar ce1
docker export ce1 > test_for_run
之后,可將匯出的tar檔案傳輸到其它機器上,然后通過匯入命令匯入到系統中,實作容器的遷移,
2)匯入容器
docker import filename
2.7 查看容器的相關資訊
使用docker inspect可以查看容器的具體資訊,會以json格式回傳容器ID、創建時間、路徑、狀態、鏡像、配置在內的各項資訊,
docker inspect 容器名 或 ID
# 同樣使用docker inspect 鏡像名 或 鏡像ID 也可以查看鏡像的相關資訊

里面有很多引數,在這里只展示了一部分,
使用下面的命令可以查看docker容器中的行程資訊,
docker top 容器名 或 ID
2.8 運行容器時的其它引數
設定環境變數
-e, --env list Set environment variables 設定環境變數
使用-e命令可以給運行的容器設定環境變數

暴露埠
--expose list Expose a port or a range of ports 暴露埠
例如,運行nginx時可以將容器的80埠進行暴露,
埠映射
我們在外部機器是無法直接通過網路與容器進行通信的,但是宿主機是可以和容器直接通信的,因此我們可以借助宿主機來和容器進行通信,
例如下圖,在容器中運行了一個埠為3306的mysql資料庫,在外部機器中是無法直接訪問容器中的mysql的,因此可以配置一個埠映射,容器中的3306埠映射到宿主機的3307埠(也可以是其它埠),這樣我們可以直接通過宿主機的IP以及埠來訪問容器中的資料庫,

-p, --publish list Publish a container's port(s) to the host 指定埠映射
-P, --publish-all Publish all exposed ports to random ports 隨機指定暴露的埠映射
例如在運行nginx時,可以將容器內的80埠映射為宿主機的8080埠,我們就可以在瀏覽器中通過8080埠來訪問容器中的nginx,-p自己指定映射的埠,


-P讓docker來隨機指定映射的埠,


可以使用docker inspect來查看映射的埠:

指定作業目錄
-w, --workdir string Working directory inside the container 指定容器中的作業目錄

可以通過-w命令來指定容器中的作業目錄,運行容器后,容器就在指定的作業目錄,
2.9 資料管理
在生產環境中使用Docker,往往需要對資料進行持久化,或者需要在多個容器直接進行資料共享,這必然涉及容器的資料管理操作,容器中的管理資料主要有兩種方式:
- 資料卷(Data Volumes):容器內資料直接映射到本地主機環境;
- 資料卷容器(Data Volume Containers):使用特定容器維護資料卷,
掛載資料卷
資料卷是一個可供容器使用的特殊目錄,它將主機作業系統目錄直接映射進容器,類似Linux中的mount行為,
資料卷可以提供很多有用的特性:
- 資料卷可以在容器間共享和重用,容器間傳遞資料將變得高效與方便;
- 對資料卷內資料的修改會立馬生效,無論是容器內操作還是本地操作;
- 對資料卷的更新不會影響鏡像,解耦開應用和資料;
- 卷會一直存在,直到沒有容器使用,可以安全地卸載它(即使容器被洗掉了,本地資料卷也不會被洗掉),
-v, --volume list Bind mount a volume 掛載資料卷
# 使用: -v 宿主機目錄:容器目錄
當容器在洗掉后,容器中的資料也就隨之被洗掉了,如果我們運行了一個mysql的容器,當容器被洗掉后,我們不希望mysql中的資料也被洗掉,因此我們可以將容器中的資料與宿主機的一個目錄建立一個映射,這兩個目錄中的資料會被同步,

如上圖所示,運行了一個名字為c6的centos的容器,并指定了宿主機的/home/mgh/data與容器/usr/local/data的映射(如果路徑中的檔案夾不存在,則會創建),在容器的/usr/local/data目錄中創建了hello.txt并寫入內容,然后退出容器,在宿主機的/home/mgh/data目錄中發現也有這樣一個檔案,同時在宿主機中創建了world.txt檔案,進入容器后也可以看到該檔案,
我們也可以將多個容器中的一個目錄掛載在宿主機的同一個目錄下,這樣就可以在容器間共享資料了,

資料卷容器
多個容器共享資料,我們可以將它們掛載在同一個目錄,如果創建比較多的容器的話,這種方式操作還是比較麻煩的,另一種方法就是創建一個資料卷容器,在運行這個容器時將目錄掛載在宿主機上,在啟動其它容器時我們可以使用–volumes-from并指定資料卷容器來共享資料,
--volumes-from list Mount volumes from the specified container(s) 從一個特殊的容器中掛載資料卷
# 例如 也可以指定多個目錄
docker run -id --name volume-container -v /home/data:/usr/local/data centos
docker run -id --name volume-des1 --volumes-from volume-container centos

如上圖所示,先使用命令創建了一個資料卷容器,將容器中/usr/local/data掛載到宿主機的/home/data中,然后創建了三個容器并指定了資料卷容器,可以看到在資料卷容器的/usr/local/data目錄下創建檔案,其它幾個容器都是可以共享資料的,
如果洗掉了掛載地容器,資料卷并不會被自動洗掉,如果要洗掉一個資料卷,必須在洗掉最后一個還掛載它的容器時顯式使用docker rm -v命令來指定同時洗掉關聯地容器,
三、應用部署
1、部署mysql
步驟如下:
-
搜索mysql鏡像
docker search mysql -
拉取mysql鏡像
docker pull mysql:5.7 -
運行容器設定埠映射
# 創建mysql目錄用于存盤mysql資料 mkdir ~/mysql cd ~/mysqldocker run -id \ -p 3307:3306 \ --name c_mysql \ -v ~/mysql/conf:/etc/mysql/conf.d \ -v ~/mysql/logs:/logs \ -v ~/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:5.7引數說明:
-p 3307:3306 將容器的3306埠映射到宿主機的3307埠,
-v 掛載目錄
-e MYSQL_ROOT_PASSWORD=123456 初始化root密碼
運行容器后,可以進入容器使用mysql客戶端連接mysql查看,
docker exec -it 容器ID /bin/bash
mysql -uroot -p

也可以使用navicat等工具來連接mysql:

2、部署tomcat
步驟如下:
-
搜索tomcat鏡像
docker search tomcat -
拉取mysql鏡像
docker pull tomcat # 直接拉取最新版 -
運行容器設定埠映射
# 創建tomcat目錄用于存盤tomcat資料資訊 mkdir ~/tomcat cd ~/tomcatdocker run -id --name c_tomcat \ -p 8080:8080 \ -v ~/tomcat:/usr/local/tomcat/webapps \ tomcat
3、部署nginx
-
拉取mysql鏡像
docker pull nginx # 直接拉取最新版 -
運行容器設定埠映射
mkdir -p ~/nginx/conf cd ~/nginx/conf vim nginx.conf # 在~/nginx/conf下創建nginx.conf組態檔,將下面的內容黏貼到nginx.conf中 ---------------------------------------------------------------- user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }docker run -id --name=c_nginx \ -p 80:80 \ -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ -v ~/nginx/conf/logs:/var/log/nginx \ -v ~/nginx/conf/html:/usr/share/nginx/html \ nginx
4、部署redis
步驟如下:
-
拉取redis鏡像
docker pull redis # 直接拉取最新版 -
運行容器設定埠映射
docker run -id --name c_redis -p 6379:6379 redis -
使用外部機器連接redis
redis-cli -h 宿主機ip -p 6379
四、構建自己的鏡像
常用地創建鏡像的方式有兩種,分別是:將容器提交為一個鏡像、使用Dockerfile創建鏡像,
1、Docker鏡像原理
首先先思考幾個問題:
- Docker 鏡像本質是什么?
- Docker 中一個centos鏡像為什么只有200MB,而一個centos作業系統的iso檔案要幾個個G?
- Docker 中一個tomcat鏡像為什么有500MB,而一個tomcat安裝包只有70多MB
作業系統的組成部分:
- 行程調度子系統
- 行程通信子系統
- 記憶體管理子系統
- 設備管理子系統
- 檔案管理子系統
- 網路通信子系統
- 作業控制子系統
Linux檔案系統由bootfs和rootfs兩部分組成
- bootfs:包含bootloader(引導加載程式)和 kernel(內核)
- rootfs: root檔案系統,包含的就是典型 Linux 系統中的/dev,/proc,/bin,/etc等標準目錄和檔案
不同的linux發行版,bootfs基本一樣,而rootfs不同,如ubuntu,centos等,

Docker鏡像是由特殊的檔案系統疊加而成,最底端是 bootfs,并使用宿主機的bootfs ,第二層是 root檔案系統rootfs,稱為base image,然后再往上可以疊加其他的鏡像檔案,
聯合檔案系統(Union File System)技術能夠將不同的層整合成一個檔案系統,為這些層提供了一個統一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個檔案系統,
一個鏡像可以放在另一個鏡像的上面,位于下面的鏡像稱為父鏡像,最底部的鏡像成為基礎鏡像,當從一個鏡像啟動容器時,Docker會在最頂層加載一個讀寫檔案系統作為容器

因此上面思考的答案是:
Docker 鏡像本質是什么?
? :是一個分層的檔案系統
Docker 中一個centos鏡像為什么只有200MB,而一個centos作業系統的iso檔案要幾個個G?
? : Centos的iso鏡像檔案包含bootfs和rootfs,而docker的centos鏡像復用作業系統的bootfs,只有rootfs和其他鏡像層
Docker 中一個tomcat鏡像為什么有500MB,而一個tomcat安裝包只有70多MB
? : 由于docker中鏡像是分層的,tomcat雖然只有70多MB,但他需要依賴于父鏡像和基礎鏡像,所有整個對外暴露的tomcat鏡像大小500多MB
2、提交容器為鏡像
我們可以將一個容器轉為一個鏡像,也可以將一個鏡像生成一個本地的壓縮檔案,在1.6節已經介紹,

我們從遠程倉庫拉取的官方的ubuntu系統是很純凈的,里面去除了很多不必要的軟體,甚至連sudo命令的沒有,我們可以運行一個從官網拉取的鏡像,并在容器中安裝vim、GCC、make等工具,然后將該容器提交為一個鏡像,那么之后根據這個鏡像運行新的容器時,容器中就會有這些工具了,
docker commit 容器名 或 ID 生成的鏡像標簽
# 例如
docker commit ubuntu1 myubuntu:lastest
3、使用Dockerfile創建鏡像
Dockerfile是一個文本格式的組態檔,用戶可以使用Dockerfile來快速創建自定義的鏡像,Dockerfile一般由一行行指令組成,并且支持以#開頭的注釋行;每一條指令構建一層,基于基礎鏡像,最終構建出一個新的鏡像;對于開發人員:可以為開發團隊提供一個完全一致的開發環境;對于測驗人員:可以直接拿開發時所構建的鏡像或者通過Dockerfile檔案構建一個新的鏡像開始作業了;對于運維人員:在部署時,可以實作應用的無縫移植;
一般而言,Dockerfile主體內容分為四部分:基礎鏡像資訊、維護者資訊、鏡像操作指令和容器啟動時執行指令,

Dockerfile相關命令:
| 關鍵字 | 作用 | 備注 |
|---|---|---|
| FROM | 指定父鏡像 | 指定dockerfile基于哪個image構建 |
| MAINTAINER | 作者資訊 | 用來標明這個dockerfile誰寫的 |
| LABEL | 標簽 | 用來標明dockerfile的標簽 可以使用Label代替Maintainer 最終都是在docker image基本資訊中可以查看 |
| RUN | 執行命令 | 執行一段命令 默認是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”],RUN命令是在鏡像構建時執行的, |
| CMD | 容器啟動命令 | 提供啟動容器時候的默認命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”],CMD命令是在容器啟動時執行的, |
| ENTRYPOINT | 入口 | 一般在制作一些執行就關閉的容器中會使用 |
| COPY | 復制檔案 | build的時候復制檔案到image中 |
| ADD | 添加檔案 | build的時候添加檔案到image中 不僅僅局限于當前build背景關系 可以來源于遠程服務,添加壓縮檔案時會自動解壓, |
| ENV | 環境變數 | 指定build時候的環境變數 可以在啟動的容器的時候 通過-e覆寫 格式ENV name=value |
| ARG | 構建引數 | 構建引數 只在構建的時候使用的引數 如果有ENV 那么ENV的相同名字的值始終覆寫arg的引數 |
| VOLUME | 定義外部可以掛載的資料卷 | 指定build的image那些目錄可以啟動的時候掛載到檔案系統中 啟動容器的時候使用 -v 系結 格式 VOLUME [“目錄”] |
| EXPOSE | 暴露埠 | 定義容器運行的時候監聽的埠 啟動容器的使用-p來系結暴露埠 格式: EXPOSE 8080 或者 EXPOSE 8080/udp |
| WORKDIR | 作業目錄 | 指定容器內部的作業目錄 如果沒有創建則自動創建 如果指定/ 使用的是絕對地址 如果不是/開頭那么是在上一條workdir的路徑的相對路徑 |
| USER | 指定執行用戶 | 指定build或者啟動的時候 用戶 在RUN CMD ENTRYPONT執行的時候的用戶 |
| HEALTHCHECK | 健康檢查 | 指定監測當前容器的健康監測的命令 基本上沒用 因為很多時候 應用本身有健康監測機制 |
| ONBUILD | 觸發器 | 當存在ONBUILD關鍵字的鏡像作為基礎鏡像的時候 當執行FROM完成之后 會執行 ONBUILD的命令 但是不影響當前鏡像 用處也不怎么大 |
| STOPSIGNAL | 發送信號到宿主機 | 該STOPSIGNAL指令設定將發送到容器的系統呼叫信號以退出, |
| SHELL | 指定執行腳本的shell | 指定RUN CMD ENTRYPOINT 執行命令的時候 使用的shell |
Dockerfile構建命令:
docker build -f ./Dockerfile -t myimage .
# -f 引數用于指定dockerfile的位置,如果在當前目錄下切名字為Dockerfile,也可以不指定
# -t target 用于指定生成的鏡像名
# .為構建的目錄
例1:構建Springboot專案的鏡像:
寫了一個簡單的springboot程式:

可以在瀏覽器中訪問的到:

構建步驟:
1.將專案打包為jar檔案,并上傳到linux的一個目錄下,例如/home/mgh/docker_springboot檔案下:
mkdir ~/docker_springboot
2.創建Dokcerfile檔案:
vim Dockerfile
3.寫Dockerfile:
dockerfile 內容如下
# 由于springboot專案依賴java jdk,因此需要有jdk的環境,也可以是ubuntu或centos,但是其中沒有java環境,還需要安裝
FROM java:8
# 作者資訊,也可以不要
MAINTAINER author<author@hdu.edu.cn>
# 將當前目錄下的jar包添加到鏡像中,并命名為app.jar
ADD springboot_test-0.0.1-SNAPSHOT.jar app.jar
# 運行springboot專案 也可以是CMD ["java", "-jar", "app.jar"]
CMD java -jar app.jar
4.構建鏡像:
docker build -t springboot_test .
5.構建成功

6.運行容器
docker run -id -p 8080:8080 springboot_test
7.在瀏覽器中訪問

例2:構建C++程式
1.創建目錄、寫一個helloworld程式
mkdir ~/cpp_docker
vim hello.cpp
程式如下,每隔一秒列印一次hello,world
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
while(1)
{
cout << "hello,world!" << endl;
sleep(1);
}
return 0;
}
2.創建Dockerfile檔案并寫入
vim Dockerfile
# 內容如下:
# 基礎鏡像
FROM ubuntu:18.04
MAINTAINER author<author@hdu.edu.cn>
# 設定環境變數
ENV MYPATH /usr/local/test
# 設定作業目錄,設定作業目錄后,啟動容器,容器所在目錄就是作業目錄
WORKDIR $MYPATH
# 將當前檔案夾下的cpp檔案拷貝到作業目錄
COPY hello.cpp $MYPATH
# 安裝g++ 以及 編譯cpp檔案,也可以將這三個命令分開寫成三條,但是會生成三層,所以不建議
# 在安裝軟體的時候,系統可能會讓你輸入y或n來同意或拒絕安裝,使用-y引數就是同意安裝,不然可能會失敗,
RUN apt-get update && \
apt-get -y install g++ && \
g++ hello.cpp -o hello
# 容器啟動時執行的命令
CMD ["./hello"]
3.構建鏡像
docker build -t cpp_test .
4.運行容器
docker run -it cpp_test

可以看到容器中在列印hello,world,但是退出不了了,可以使用docker stop將這個容停止,
例3:構建Golang程式
將使用gin框架的一個web程式構建為docker鏡像:
1.golang代碼:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
engine := gin.Default()
engine.GET("/jige", func(context *gin.Context) {
data := map[string]interface{}{
"name" : "kunkun",
"age" : 23,
"hobby" : "sing jump rap",
}
context.JSON(http.StatusOK, data)
})
engine.Run("0.0.0.0:8080")
}
go.mod
go mod init
go mod tidy
2.將程式打包上傳到linux的一個檔案中
mkdir ~/docker_golang
#程式檔案名 gin_json
3.創建Dockerfile
vim Dockerfile
# dockerfile內容如下
# 基礎鏡像
FROM golang
MAINTAINER author <author@hdu.edu.cn>
# 設定環境變數
ENV GO111MODULE on
# 設定golang代理否則下載gin框架很可能會失敗
ENV GOPROXY https://goproxy.cn
# 設定作業目錄
WORKDIR /go/src/gin_json/
# 把當前目錄下所以檔案拷貝到容器的作業目錄
COPY . .
# 安裝gin框架依賴
RUN go mod tidy
# 容器啟動運行程式
CMD go run main.go
4.構建鏡像
docker build -t gotest .
5.運行容器
docker run -id -p 9090:8080 gotest
6.瀏覽器訪問頁面

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/340610.html
標籤:其他
下一篇:初識JVM,JVM自動記憶體管理
