怎么進(jìn)行網(wǎng)站維護(hù)大地seo視頻
目錄
Docker概述
效果呈現(xiàn)?
鏡像 &?鏡像倉庫?&?容器
鏡像
DockerHub
配置國內(nèi)源加速?
容器
簡單的命令解讀?
Docker基礎(chǔ)
常用命令
案例演示
數(shù)據(jù)卷?
什么是數(shù)據(jù)卷
數(shù)據(jù)卷命令
演示環(huán)節(jié)
匿名數(shù)據(jù)卷
案例演示
自定義掛載位置
案例演示
自定義鏡像
鏡像結(jié)構(gòu)?
Dockerfile?
案例演示
網(wǎng)絡(luò)
自定義網(wǎng)絡(luò)?
實(shí)現(xiàn)原理
案例演示
完整微服務(wù)項(xiàng)目部署【前后端兼具】
部署Java項(xiàng)目
部署前端
??編輯
進(jìn)階:DockerCompose?
基本語法
案例演示?
基礎(chǔ)命令
案例演示?
學(xué)習(xí)完啦!加油噢!?
Docker概述
快速構(gòu)建、運(yùn)行、管理應(yīng)用的工具
隨身運(yùn)維老Baby給你安排環(huán)境,讓你可以直接安心寫屎山
Docker是一個(gè)快速交付應(yīng)用、運(yùn)行應(yīng)用的技術(shù):
- 可以將程序及其依賴、運(yùn)行環(huán)境一起打包為一個(gè)鏡像,可以遷移到任意Linux操作系統(tǒng)
- 運(yùn)行時(shí)利用沙箱機(jī)制形成隔離容器,各個(gè)應(yīng)用互不干擾
- 啟動(dòng)、移除都可以通過一行命令完成,方便快捷
Docker如何解決大型項(xiàng)目依賴關(guān)系復(fù)雜,不同組件依賴的兼容性問題?
- Docker允許開發(fā)中將應(yīng)用、依賴、函數(shù)庫、配置一起打包,形成可移植鏡像
- Docker應(yīng)用運(yùn)行在容器中,使用沙箱機(jī)制,相互隔離
Docker如何解決開發(fā)、測試、生產(chǎn)環(huán)境有差異的問題?
- Docker鏡像中包含完整運(yùn)行環(huán)境,包括系統(tǒng)函數(shù)庫,僅依賴系統(tǒng)的Linux內(nèi)核,因此可以在任意Linux操作系統(tǒng)上運(yùn)行
效果呈現(xiàn)?
首先,我們利用Docker來安裝一個(gè)MySQL軟件,大家可以對比一下之前傳統(tǒng)的安裝方式,看看哪個(gè)效率更高一些。
如果是利用傳統(tǒng)方式部署MySQL,大概的步驟有:
搜索并下載MySQL安裝包
上傳至Linux環(huán)境
編譯和配置環(huán)境
安裝
而使用Docker安裝,僅僅需要一步即可,在命令行輸入下面的命令(建議采用CV大法):
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \mysql
運(yùn)行效果如圖:
MySQL安裝完畢!通過任意客戶端工具即可連接到MySQL.
可以發(fā)現(xiàn),當(dāng)我們執(zhí)行命令后,Docker做的第一件事情,是去自動(dòng)搜索并下載了MySQL,然后會(huì)自動(dòng)運(yùn)行MySQL,我們完全不用插手,是不是非常方便。
而且,這種安裝方式你完全不用考慮運(yùn)行的操作系統(tǒng)環(huán)境,它不僅僅在CentOS系統(tǒng)是這樣,在Ubuntu系統(tǒng)、macOS系統(tǒng)、甚至是裝了WSL的Windows下,都可以使用這條命令來安裝MySQL。
要知道,不同操作系統(tǒng)下其安裝包、運(yùn)行環(huán)境是都不相同的!如果是手動(dòng)安裝,必須手動(dòng)解決安裝包不同、環(huán)境不同的、配置不同的問題!
而使用Docker,這些完全不用考慮。就是因?yàn)镈ocker會(huì)自動(dòng)搜索并下載MySQL。注意:這里下載的不是安裝包,而是鏡像。鏡像中不僅包含了MySQL本身,還包含了其運(yùn)行所需要的環(huán)境、配置、系統(tǒng)級函數(shù)庫。因此它在運(yùn)行時(shí)就有自己獨(dú)立的環(huán)境,就可以跨系統(tǒng)運(yùn)行,也不需要手動(dòng)再次配置環(huán)境了。這套獨(dú)立運(yùn)行的隔離環(huán)境我們稱為容器。
鏡像 &?鏡像倉庫?&?容器
鏡像
- 鏡像(Image):Docker將應(yīng)用程序及其所需的依賴、函數(shù)庫、環(huán)境、配置等文件打包在一起,稱為鏡像。
說人話就是,鏡像相當(dāng)于拿來就能用的應(yīng)用程序,不用你下載安裝,不用你配置環(huán)境,直接在遠(yuǎn)程拉下來就能用,有點(diǎn)類似于Maven的依賴,但是比Maven的更牛點(diǎn),因?yàn)樗S開隨關(guān),不用關(guān)心版本沖突等等?
DockerHub
????Docker官方提供了一個(gè)專門管理、存儲(chǔ)鏡像的網(wǎng)站,并對外開放了鏡像上傳、下載的權(quán)利。Docker官方提供了一些基礎(chǔ)鏡像,然后各大軟件公司又在基礎(chǔ)鏡像基礎(chǔ)上,制作了自家軟件的鏡像,全部都存放在這個(gè)網(wǎng)站。這個(gè)網(wǎng)站就成了Docker鏡像交流的社區(qū):
DockerHub官網(wǎng)https://hub.docker.com/
基本上我們常用的各種軟件都能在這個(gè)網(wǎng)站上找到,我們甚至可以自己制作鏡像上傳上去。
像這種提供存儲(chǔ)、管理Docker鏡像的服務(wù)器,被稱為DockerRegistry,可以翻譯為鏡像倉庫。DockerHub網(wǎng)站是官方倉庫,阿里云、華為云會(huì)提供一些第三方倉庫,我們也可以自己搭建私有的鏡像倉庫。
官方倉庫在國外,下載速度較慢,一般我們都會(huì)使用第三方倉庫提供的鏡像加速功能,提高下載速度。而企業(yè)內(nèi)部的機(jī)密項(xiàng)目,往往會(huì)采用私有鏡像倉庫。
總之,鏡像的來源有兩種:
基于官方基礎(chǔ)鏡像自己制作
直接去DockerRegistry下載
配置國內(nèi)源加速?
下面以 Ubunut16.04 和 Docker20.10.2 為例演示 Docker 配置國內(nèi)源加速的過程。
1. 修改配置文件
Docker 的配置文件為 /etc/docker/daemon.json,編輯該文件(沒有的話先手動(dòng)創(chuàng)建)加入國內(nèi)鏡像源:
- DockerProxy:https://dockerproxy.com;
- 網(wǎng)易源:https://hub-mirror.c.163.com;
- 百度源:https://mirror.baidubce.com;
- 騰訊源:https://ccr.ccs.tencentyun.com;
# 編輯 Docker 配置文件
$ sudo vim /etc/docker/daemon.json
# 加入以下配置項(xiàng)
{"registry-mirrors": ["https://dockerproxy.com","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://ccr.ccs.tencentyun.com"]
}
# 方法一,采用 systemctl 來重啟,推薦
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker# 方法二,采用 service 來重啟
$ sudo service docker restart
# 查看 Docker 信息
$ sudo docker info# 出現(xiàn)以下字段代表配置成功
Registry Mirrors:https://dockerproxy.com/https://hub-mirror.c.163.com/https://mirror.baidubce.com/https://ccr.ccs.tencentyun.com/
容器
- 容器(Container):鏡像中的應(yīng)用程序運(yùn)行后形成的進(jìn)程就是容器,只是Docker會(huì)給容器做隔離,對外不可見。
注意:容器如果接收到停止命令,就會(huì)將當(dāng)前進(jìn)程殺死,如果停止到運(yùn)行,實(shí)際上是新開的一個(gè)新進(jìn)程
由于容器是對外隔離的,所以說,你不能在外擺你直接發(fā)請求到容器內(nèi)部,那么我們只能通過宿主機(jī)端口和容器端口進(jìn)行一個(gè)映射,外界發(fā)送請求給宿主機(jī)的映射端口,宿主機(jī)就會(huì)將該請求映射到容器的銀蛇端口上,相當(dāng)于一次正向代理的過程
簡單的命令解讀?
?
利用Docker快速的安裝了MySQL,非常的方便,不過我們執(zhí)行的命令到底是什么意思呢??
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \mysql
Docker基礎(chǔ)
接下來,一起來學(xué)習(xí)Docker使用的一些基礎(chǔ)知識,為將來部署項(xiàng)目打下基礎(chǔ)。具體用法可以參考Docker官方文檔:
Docker官網(wǎng)https://docs.docker.com/
首先我們來學(xué)習(xí)Docker中的常見命令,可以參考官方文檔:
Docker常用命令https://docs.docker.com/engine/reference/commandline/cli/
常用命令
命令 | 說明 | 文檔地址 |
---|---|---|
docker pull 鏡像名? ? /? ? ?docker pull 鏡像名:Tag | 拉取鏡像 | docker pull |
docker push?鏡像名/鏡像ID | 推送鏡像到DockerRegistry | docker push |
docker images? | 查看本地鏡像 | docker images |
docker rmi?鏡像名/鏡像ID | 刪除本地鏡像 | docker rmi |
docker run? | 創(chuàng)建并運(yùn)行容器(不能重復(fù)創(chuàng)建) | docker run |
docker stop?容器名 / 容器id | 停止指定容器 | docker stop |
docker start?容器名 / 容器id | 啟動(dòng)指定容器 | docker start |
docker restart?容器名 / 容器id | 重新啟動(dòng)容器 | docker restart |
docker rm?容器名 / 容器id | 刪除指定容器 | docs.docker.com |
docker ps(docker ps -a) | 查看啟動(dòng)中的容器(列出所有狀態(tài)的容器) | docker ps |
docker logs | 查看容器運(yùn)行日志 | docker logs |
docker exec | 進(jìn)入容器 | docker exec |
docker save?鏡像名/鏡像ID -o?鏡像保存位置與名字 | 保存鏡像到本地壓縮文件 | docker save |
docker load -i 鏡像保存的文件位置 | 加載本地壓縮文件到鏡像 | docker load |
docker inspect | 查看容器詳細(xì)信息 | docker inspect |
docker ps --help | 查看容器的幫助 |
用一副圖來表示這些命令的關(guān)系
補(bǔ)充:
默認(rèn)情況下,每次重啟虛擬機(jī)我們都需要手動(dòng)啟動(dòng)Docker和Docker中的容器。通過命令可以實(shí)現(xiàn)開機(jī)自啟:
# Docker開機(jī)自啟
systemctl enable docker# Docker容器開機(jī)自啟
docker update --restart=always [容器名/容器id]
案例演示
以Nginx為例給大家演示上述命令。
# 第1步,去DockerHub查看nginx鏡像倉庫及相關(guān)信息(看有沒有先麻)
---------------------------------------------------------------------------------------# 第2步,拉取Nginx鏡像(不標(biāo)版本號我就默認(rèn)最新款了噢)
docker pull nginx
---------------------------------------------------------------------------------------# 第3步,查看鏡像
docker images
# 結(jié)果如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB
---------------------------------------------------------------------------------------# 第4步,開啟一個(gè)Nginx容器,第一個(gè)nginx是容器名,第二個(gè)nginx是鏡像名,以80端口映射80端口
docker run -d --name nginx -p 80:80 nginx
---------------------------------------------------------------------------------------# 第5步,查看運(yùn)行中容器(注意噢,這里只能看到運(yùn)行中的容器,如果你想看所有的容器就加 “-a”)
docker ps
# 也可以加格式化方式訪問,格式會(huì)更加清爽(直接CV吧,啥好人記得住這么長)
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
---------------------------------------------------------------------------------------# 第6步,訪問網(wǎng)頁,地址:http://虛擬機(jī)地址(喲吼!有了!)
---------------------------------------------------------------------------------------# 第7步,停止容器
docker stop nginx
---------------------------------------------------------------------------------------# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
---------------------------------------------------------------------------------------# 第9步,再次啟動(dòng)nginx容器
docker start nginx
---------------------------------------------------------------------------------------# 第10步,再次查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
---------------------------------------------------------------------------------------# 第11步,查看容器詳細(xì)信息
docker inspect nginx
---------------------------------------------------------------------------------------# 第12步,進(jìn)入容器,查看容器內(nèi)目錄(這個(gè)不用管,去Linux改多麻煩,別急,后面咱兒在window下改才爽)
docker exec -it nginx bash
# 或者,可以進(jìn)入MySQL
docker exec -it mysql mysql -uroot -p
---------------------------------------------------------------------------------------# 第13步,刪除容器
docker rm nginx
# 發(fā)現(xiàn)無法刪除,因?yàn)槿萜鬟\(yùn)行中,強(qiáng)制刪除容器
docker rm -f nginx
通過上面內(nèi)容的學(xué)習(xí),相信大家已經(jīng)大概了解了Docker是個(gè)啥并且能實(shí)現(xiàn)簡單的部署運(yùn)用了,但是在平時(shí)的環(huán)境部署中,尤其是一些中間件,它們不僅在下載安裝的時(shí)候折騰人,在實(shí)際運(yùn)用的時(shí)候還要在容器內(nèi)的配置文件上改來改去的,做這些真的會(huì)枯萎V^V......直接在Linux中操作容器內(nèi)部的目錄多方便......你猜怎么著?還真有!
數(shù)據(jù)卷?
容器是隔離環(huán)境,容器內(nèi)程序的文件、配置、運(yùn)行時(shí)產(chǎn)生的容器都在容器內(nèi)部,我們要讀寫容器內(nèi)的文件非常不方便。大家思考幾個(gè)問題:
-
如果要升級MySQL版本,需要銷毀舊容器,那么數(shù)據(jù)豈不是跟著被銷毀了?
-
MySQL、Nginx容器運(yùn)行后,如果我要修改其中的某些配置該怎么辦?
-
我想要讓Nginx代理我的靜態(tài)資源怎么辦?
因此,容器提供程序的運(yùn)行環(huán)境,但是程序運(yùn)行產(chǎn)生的數(shù)據(jù)、程序運(yùn)行依賴的配置都應(yīng)該與容器解耦。
什么是數(shù)據(jù)卷
數(shù)據(jù)卷(volume)是一個(gè)虛擬目錄,是容器內(nèi)目錄與宿主機(jī)目錄之間映射的橋梁。
(說人話就是,我在Linux中對一個(gè)目錄操作,能直接影響到docker中的那個(gè)應(yīng)用的目錄)
以Nginx為例,我們知道Nginx中有兩個(gè)關(guān)鍵的目錄:
-
html
:放置一些靜態(tài)資源 -
conf
:放置配置文件
如果我們要讓Nginx代理我們的靜態(tài)資源,最好是放到html
目錄;如果我們要修改Nginx的配置,最好是找到conf
下的nginx.conf
文件。
但遺憾的是,容器運(yùn)行的Nginx所有的文件都在容器內(nèi)部。所以我們必須利用數(shù)據(jù)卷將兩個(gè)目錄與宿主機(jī)目錄關(guān)聯(lián),方便我們操作。如圖:
在上圖中:
-
我們創(chuàng)建了兩個(gè)數(shù)據(jù)卷:
conf
、html
-
Nginx容器內(nèi)部的
conf
目錄和html
目錄分別與兩個(gè)數(shù)據(jù)卷關(guān)聯(lián)。 -
而數(shù)據(jù)卷conf和html分別指向了宿主機(jī)的
/var/lib/docker/volumes/conf/_data
目錄和/var/lib/docker/volumes/html/_data
目錄
這樣以來,容器內(nèi)的conf
和html
目錄就 與宿主機(jī)的conf
和html
目錄關(guān)聯(lián)起來,我們稱為掛載。此時(shí),我們操作宿主機(jī)的/var/lib/docker/volumes/html/_data
就是在操作容器內(nèi)的/usr/share/nginx/html/_data
目錄。只要我們將靜態(tài)資源放入宿主機(jī)對應(yīng)目錄,就可以被Nginx代理了。
當(dāng)你容器要進(jìn)行升級操作,只需要把容器鏡像刪了新拉一個(gè)高版本的就好,反正數(shù)據(jù)在數(shù)據(jù)卷中保存的好好的,你刪了也沒事,因?yàn)閿?shù)據(jù)卷只是掛載在該容器下,你刪了容器,不會(huì)影響數(shù)據(jù)卷
數(shù)據(jù)卷命令
命令 | 說明 | 文檔地址 |
---|---|---|
docker volume create | 創(chuàng)建數(shù)據(jù)卷 | docker volume create |
docker volume ls | 查看所有數(shù)據(jù)卷 | docs.docker.com |
docker volume rm | 刪除指定數(shù)據(jù)卷 | docs.docker.com |
docker volume inspect | 查看某個(gè)數(shù)據(jù)卷的詳情 | docs.docker.com |
docker volume prune | 清除數(shù)據(jù)卷 | docker volume prune |
注意:容器與數(shù)據(jù)卷的掛載要在創(chuàng)建容器時(shí)配置,對于創(chuàng)建好的容器,是不能設(shè)置數(shù)據(jù)卷的。而且創(chuàng)建容器的過程中,數(shù)據(jù)卷會(huì)自動(dòng)創(chuàng)建。
演示環(huán)節(jié)
????????演示一下nginx的html目錄掛載
# 1.首先創(chuàng)建容器并指定數(shù)據(jù)卷,注意通過 -v 參數(shù)來指定數(shù)據(jù)卷 【數(shù)據(jù)卷名:被映射的容器文件位置】
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
---------------------------------------------------------------------------------------# 2.然后查看數(shù)據(jù)卷
docker volume ls
# 結(jié)果
DRIVER VOLUME NAME
local 29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local html
---------------------------------------------------------------------------------------# 3.查看數(shù)據(jù)卷詳情 (就看Mountpoint就行啦,那個(gè)就是數(shù)據(jù)卷在宿主機(jī)的目錄位置)
docker volume inspect html
# 結(jié)果
[{"CreatedAt": "2024-05-17T19:57:08+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/html/_data","Name": "html","Options": null,"Scope": "local"}
]
---------------------------------------------------------------------------------------# 4.直接在Linux命令行中查看/var/lib/docker/volumes/html/_data目錄
ll /var/lib/docker/volumes/html/_data
# 可以看到與nginx的html目錄內(nèi)容一樣,結(jié)果如下:
總用量 8
-rw-r--r--. 1 root root 497 12月 28 2021 50x.html
-rw-r--r--. 1 root root 615 12月 28 2021 index.html
---------------------------------------------------------------------------------------# 5.進(jìn)入該目錄,并隨意修改index.html內(nèi)容
cd /var/lib/docker/volumes/html/_data
vi index.html
---------------------------------------------------------------------------------------# 6.打開頁面,查看效果
---------------------------------------------------------------------------------------# 7.進(jìn)入容器內(nèi)部,查看/usr/share/nginx/html目錄內(nèi)的文件是否變化
docker exec -it nginx bash
---------------------------------------------------------------------------------------# 變啦~~~
匿名數(shù)據(jù)卷
????????在Docker中,匿名數(shù)據(jù)卷是一種特殊類型的數(shù)據(jù)卷,用于在容器之間共享數(shù)據(jù)。與具名數(shù)據(jù)卷不同,匿名數(shù)據(jù)卷不指定名稱,在容器中創(chuàng)建時(shí)只需指定掛載點(diǎn)即可。
匿名數(shù)據(jù)卷的主要特點(diǎn)如下:
- 自動(dòng)創(chuàng)建:當(dāng)你在Docker中創(chuàng)建一個(gè)匿名數(shù)據(jù)卷時(shí),Docker會(huì)自動(dòng)為其分配一個(gè)唯一的名稱。
- 自動(dòng)掛載:在容器中使用匿名數(shù)據(jù)卷時(shí),可以通過指定掛載點(diǎn)將數(shù)據(jù)卷掛載到容器的指定路徑上。
- 臨時(shí)性:匿名數(shù)據(jù)卷的生命周期與容器的生命周期綁定。當(dāng)容器被刪除時(shí),匿名數(shù)據(jù)卷也會(huì)被刪除,因此匿名數(shù)據(jù)卷適用于臨時(shí)存儲(chǔ)或臨時(shí)共享數(shù)據(jù)的場景。
使用匿名數(shù)據(jù)卷的方式如下:
- 在運(yùn)行容器時(shí)使用
-v
或--volume
選項(xiàng),不指定數(shù)據(jù)卷的名稱,只指定掛載點(diǎn)。例如:docker run -v /path/in/container image:tag
- 在Dockerfile中使用
VOLUME
命令來聲明匿名數(shù)據(jù)卷。例如:VOLUME /path/in/container
使用匿名數(shù)據(jù)卷可以方便地實(shí)現(xiàn)容器之間的數(shù)據(jù)共享,同時(shí)又不需要關(guān)心數(shù)據(jù)卷的具體名稱,提高了容器的可移植性和靈活性。
案例演示
演示一下MySQL的匿名數(shù)據(jù)卷
# 1.查看MySQL容器詳細(xì)信息
docker inspect mysql
# 關(guān)注其中.Config.Volumes部分和.Mounts部分
我們關(guān)注兩部分內(nèi)容,第一是.Config.Volumes
部分:
{"Config": {// ... 略"Volumes": {"/var/lib/mysql": {}}// ... 略}
}
可以發(fā)現(xiàn)這個(gè)容器聲明了一個(gè)本地目錄,需要掛載數(shù)據(jù)卷,但是數(shù)據(jù)卷未定義。這就是匿名卷。
然后,我們再看結(jié)果中的.Mounts
部分:
{"Mounts": [{"Type": "volume","Name": "29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f","Source": "/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data","Destination": "/var/lib/mysql","Driver": "local",}]
}
可以發(fā)現(xiàn),其中有幾個(gè)關(guān)鍵屬性:
-
Name:數(shù)據(jù)卷名稱。由于定義容器未設(shè)置容器名,這里的就是匿名卷自動(dòng)生成的名字,一串hash值。
-
Source:宿主機(jī)目錄
-
Destination : 容器內(nèi)的目錄
上述配置是將容器內(nèi)的/var/lib/mysql
這個(gè)目錄,與數(shù)據(jù)卷29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
掛載。于是在宿主機(jī)中就有了/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data
這個(gè)目錄。這就是匿名數(shù)據(jù)卷對應(yīng)的目錄,其使用方式與普通數(shù)據(jù)卷沒有差別。
接下來,可以查看該目錄下的MySQL的data文件:
ls -l /var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data
注意:每一個(gè)不同的鏡像,將來創(chuàng)建容器后內(nèi)部有哪些目錄可以掛載,可以參考DockerHub對應(yīng)的頁面
自定義掛載位置
可以發(fā)現(xiàn),數(shù)據(jù)卷的目錄結(jié)構(gòu)較深,如果我們?nèi)ゲ僮鲾?shù)據(jù)卷目錄會(huì)不太方便。在很多情況下,我們會(huì)直接將容器目錄與宿主機(jī)指定目錄掛載。掛載語法與數(shù)據(jù)卷類似:(其實(shí)就是把聲明數(shù)據(jù)卷的名字改為了一個(gè)路徑)
# 掛載本地目錄
-v 本地目錄:容器內(nèi)目錄# 掛載本地文件
-v 本地文件:容器內(nèi)文件
?注意:本地目錄或文件必須以
/
或./
開頭,如果直接以名字開頭,會(huì)被識別為數(shù)據(jù)卷名而非本地目錄名。
例如:
-v mysql:/var/lib/mysql # 會(huì)被識別為一個(gè)數(shù)據(jù)卷叫mysql,運(yùn)行時(shí)會(huì)自動(dòng)創(chuàng)建這個(gè)數(shù)據(jù)卷-v ./mysql:/var/lib/mysql # 會(huì)被識別為當(dāng)前目錄下的mysql目錄,運(yùn)行時(shí)如果不存在會(huì)創(chuàng)建目錄
案例演示
刪除并重新創(chuàng)建mysql容器,并完成本地準(zhǔn)備好的目錄對新容器掛載(相當(dāng)于對該容器進(jìn)行初始化操作)
-
掛載
/root/mysql/data
到容器內(nèi)的/var/lib/mysql
目錄 -
掛載
/root/mysql/init
到容器內(nèi)的/docker-entrypoint-initdb.d
目錄(初始化的SQL腳本目錄) -
掛載
/root/mysql/conf
到容器內(nèi)的/etc/mysql/conf.d
目錄(這個(gè)是MySQL配置文件目錄)
?首先準(zhǔn)備好了mysql的init
目錄和conf
目錄:
以及對應(yīng)的初始化SQL腳本和配置文件:
其中,hm.cnf主要是配置了MySQL的默認(rèn)編碼,改為utf8mb4;而hmall.sql則是后面我們要用到的項(xiàng)目的初始化SQL腳本。
我們直接將整個(gè)mysql目錄上傳至虛擬機(jī)的/root
目錄下:
?接下來,我們演示本地目錄掛載:
# 1.刪除原來的MySQL容器
docker rm -f mysql
----------------------------------------------------------------------------------------# 2.進(jìn)入root目錄
cd ~
----------------------------------------------------------------------------------------# 3.創(chuàng)建并運(yùn)行新mysql容器,掛載本地目錄
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \-v ./mysql/data:/var/lib/mysql \-v ./mysql/conf:/etc/mysql/conf.d \-v ./mysql/init:/docker-entrypoint-initdb.d \mysql
----------------------------------------------------------------------------------------# 4.查看root目錄,可以發(fā)現(xiàn)~/mysql/data目錄已經(jīng)自動(dòng)創(chuàng)建好了
ls -l mysql
# 結(jié)果:
總用量 4
drwxr-xr-x. 2 root root 20 5月 19 15:11 conf
drwxr-xr-x. 7 polkitd root 4096 5月 19 15:11 data
drwxr-xr-x. 2 root root 23 5月 19 15:11 init# 查看data目錄,會(huì)發(fā)現(xiàn)里面有大量數(shù)據(jù)庫數(shù)據(jù),說明數(shù)據(jù)庫完成了初始化
ls -l data
----------------------------------------------------------------------------------------# 5.查看MySQL容器內(nèi)數(shù)據(jù)
# 5.1.進(jìn)入MySQL
docker exec -it mysql mysql -uroot -p123# 5.2.查看編碼表
show variables like "%char%";# 5.3.結(jié)果,發(fā)現(xiàn)編碼是utf8mb4沒有問題
+--------------------------+--------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
----------------------------------------------------------------------------------------# 6.查看數(shù)據(jù)
# 6.1.查看數(shù)據(jù)庫
show databases;
# 結(jié)果,hmall是黑馬商城數(shù)據(jù)庫
+--------------------+
| Database |
+--------------------+
| hmall |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)# 6.2.切換到hmall數(shù)據(jù)庫
use hmall;# 6.3.查看表
show tables;
# 結(jié)果:
+-----------------+
| Tables_in_hmall |
+-----------------+
| address |
| cart |
| item |
| order |
| order_detail |
| order_logistics |
| pay_order |
| user |
+-----------------+# 6.4.查看address表數(shù)據(jù)
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
| id | user_id | province | city | town | mobile | street | contact | is_default | notes |
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
| 59 | 1 | 北京 | 北京 | 朝陽區(qū) | 13900112222 | 金燕龍辦公樓 | 李佳誠 | 0 | NULL |
| 60 | 1 | 北京 | 北京 | 朝陽區(qū) | 13700221122 | 修正大廈 | 李佳紅 | 0 | NULL |
| 61 | 1 | 上海 | 上海 | 浦東新區(qū) | 13301212233 | 航頭鎮(zhèn)航頭路 | 李佳星 | 1 | NULL |
| 63 | 1 | 廣東 | 佛山 | 永春 | 13301212233 | 永春武館 | 李曉龍 | 0 | NULL |
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
4 rows in set (0.00 sec)
前面我們一直在使用別人準(zhǔn)備好的鏡像,那如果我要部署一個(gè)Java項(xiàng)目,把它打包為一個(gè)鏡像該怎么做呢??
自定義鏡像
之前我們說過,鏡像之所以能讓我們快速跨操作系統(tǒng)部署應(yīng)用而忽略其運(yùn)行環(huán)境、配置,就是因?yàn)殓R像中包含了程序運(yùn)行需要的系統(tǒng)函數(shù)庫、環(huán)境、配置、依賴。
因此,自定義鏡像本質(zhì)就是依次準(zhǔn)備好程序運(yùn)行的基礎(chǔ)環(huán)境、依賴、應(yīng)用本身、運(yùn)行配置等文件,并且打包而成。
鏡像結(jié)構(gòu)?
上述步驟中的每一次操作其實(shí)都是在生產(chǎn)一些文件(系統(tǒng)運(yùn)行環(huán)境、函數(shù)庫、配置最終都是磁盤文件),所以鏡像就是一堆文件的集合。
但需要注意的是,鏡像文件不是隨意堆放的,而是按照操作的步驟分層疊加而成,每一層形成的文件都會(huì)單獨(dú)打包并標(biāo)記一個(gè)唯一id,稱為Layer(層)。這樣,如果我們構(gòu)建時(shí)用到的某些層其他人已經(jīng)制作過,就可以直接拷貝使用這些層,而不用重復(fù)制作。
例如,第一步中需要的Linux運(yùn)行環(huán)境,通用性就很強(qiáng),所以Docker官方就制作了這樣的只包含Linux運(yùn)行環(huán)境的鏡像。我們在制作java鏡像時(shí),就無需重復(fù)制作,直接使用Docker官方提供的CentOS或Ubuntu鏡像作為基礎(chǔ)鏡像。然后再搭建其它層即可,這樣逐層搭建,最終整個(gè)Java項(xiàng)目的鏡像結(jié)構(gòu)如圖所示:
Dockerfile?
由于制作鏡像的過程中,需要逐層處理和打包,比較復(fù)雜,所以Docker就提供了自動(dòng)打包鏡像的功能。我們只需要將打包的過程,每一層要做的事情用固定的語法寫下來,交給Docker去執(zhí)行即可。
而這種記錄鏡像結(jié)構(gòu)的文件就稱為Dockerfile,其對應(yīng)的語法可以參考官方文檔:
捕捉到一個(gè)官方文檔https://docs.docker.com/engine/reference/builder/
其中的語法比較多,比較常用的有:
指令 | 說明 | 示例 |
---|---|---|
FROM | 指定基礎(chǔ)鏡像 |
|
ENV | 設(shè)置環(huán)境變量,可在后面指令使用 |
|
COPY | 拷貝本地文件到鏡像的指定目錄 |
|
RUN | 執(zhí)行Linux的shell命令,一般是安裝過程的命令 |
|
EXPOSE | 指定容器運(yùn)行時(shí)監(jiān)聽的端口,是給鏡像使用者看的 | EXPOSE 8080 |
ENTRYPOINT | 鏡像中應(yīng)用的啟動(dòng)命令,容器運(yùn)行時(shí)調(diào)用 | ENTRYPOINT java -jar xx.jar |
例如,要基于Ubuntu鏡像來構(gòu)建一個(gè)Java應(yīng)用,其Dockerfile內(nèi)容如下:?
# 基礎(chǔ)鏡像
FROM openjdk:11.0-jre-buster# 設(shè)定時(shí)區(qū)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# 拷貝jar包
COPY docker-demo.jar /app.jar# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
案例演示
寫好一個(gè)Dockerfile文件
# 基礎(chǔ)鏡像
FROM openjdk:11.0-jre-buster# 設(shè)定時(shí)區(qū)(如果不設(shè)置的話,時(shí)區(qū)就和中國不一樣了噢)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# 拷貝jar包(將名為docker-demo.jar的文件復(fù)制到當(dāng)前工作目錄下,并將其重命名為app.jar)
COPY docker-demo.jar /app.jar# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
當(dāng)Dockerfile文件寫好以后,就可以利用命令來構(gòu)建鏡像了。
在課前資料中,我們準(zhǔn)備好了一個(gè)demo項(xiàng)目及對應(yīng)的Dockerfile:
首先,我們將課前資料提供的docker-demo.jar
包以及Dockerfile
拷貝到虛擬機(jī)的/root/demo
目錄:
然后,執(zhí)行命令,構(gòu)建鏡像:
# 進(jìn)入鏡像目錄
cd /root/demo# 開始構(gòu)建
docker build -t docker-demo:1.0 .
?結(jié)果:
查看鏡像列表:
# 查看鏡像列表:
docker images# 結(jié)果
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-demo 1.0 d6ab0b9e64b9 27 minutes ago 327MB
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB
?然后嘗試運(yùn)行該鏡像:
# 1.創(chuàng)建并運(yùn)行容器
docker run -d --name dd -p 8090:8090 docker-demo:1.0# 2.查看容器
dps# 結(jié)果
CONTAINER ID IMAGE PORTS STATUS NAMES
78a000447b49 docker-demo:1.0 0.0.0.0:8080->8080/tcp, :::8090->8090/tcp Up 2 seconds dd
f63cfead8502 mysql 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp Up 2 hours mysql# 3.訪問
curl localhost:8080/hello/count
# 結(jié)果:
<h5>歡迎訪問黑馬商城, 這是您第1次訪問<h5>
網(wǎng)絡(luò)
上節(jié)課我們創(chuàng)建了一個(gè)Java項(xiàng)目的容器,而Java項(xiàng)目往往需要訪問其它各種中間件,例如MySQL、Redis等。現(xiàn)在,我們的容器之間能否互相訪問呢?我們來測試一下
首先,我們查看下MySQL容器的詳細(xì)信息,重點(diǎn)關(guān)注其中的網(wǎng)絡(luò)IP地址:
發(fā)現(xiàn)可以互聯(lián),沒有問題。
但是,容器的網(wǎng)絡(luò)IP其實(shí)是一個(gè)虛擬的IP,其值并不固定與某一個(gè)容器綁定,如果我們在開發(fā)時(shí)寫死某個(gè)IP,而在部署時(shí)很可能MySQL容器的IP會(huì)發(fā)生變化,連接會(huì)失敗。
所以,我們必須借助于docker的網(wǎng)絡(luò)功能來解決這個(gè)問題,官方文檔:
Docker文檔——網(wǎng)絡(luò)部分https://docs.docker.com/engine/reference/commandline/network/
加入自定義網(wǎng)絡(luò)的容器才可以通過容器名互相訪問(不需要通過動(dòng)態(tài)虛擬IP啦~鎖定你啦),Docker的網(wǎng)絡(luò)操作命令如下
命令 | 說明 | 文檔地址 |
---|---|---|
docker network create | 創(chuàng)建一個(gè)網(wǎng)絡(luò) | docker network create |
docker network ls | 查看所有網(wǎng)絡(luò) | docs.docker.com |
docker network rm | 刪除指定網(wǎng)絡(luò) | docs.docker.com |
docker network prune | 清除未使用的網(wǎng)絡(luò) | docs.docker.com |
docker network connect | 使指定容器連接加入某網(wǎng)絡(luò) | docs.docker.com |
docker network disconnect | 使指定容器連接離開某網(wǎng)絡(luò) | docker network disconnect |
docker network inspect | 查看網(wǎng)絡(luò)詳細(xì)信息 | docker network inspect |
自定義網(wǎng)絡(luò)?
????????在Docker中,自定義網(wǎng)絡(luò)是一種創(chuàng)建和管理容器間通信的方式。它的主要目的是提供一個(gè)隔離的網(wǎng)絡(luò)環(huán)境,使容器之間能夠相互通信,而與宿主機(jī)網(wǎng)絡(luò)和其他容器網(wǎng)絡(luò)相互隔離
實(shí)現(xiàn)原理
- Docker自定義網(wǎng)絡(luò)是通過Linux內(nèi)核的網(wǎng)絡(luò)命名空間和虛擬以太網(wǎng)橋技術(shù)來實(shí)現(xiàn)的。
- 每個(gè)自定義網(wǎng)絡(luò)都有一個(gè)唯一的網(wǎng)絡(luò)命名空間,容器會(huì)加入到該命名空間中。這樣,每個(gè)自定義網(wǎng)絡(luò)都有自己獨(dú)立的網(wǎng)絡(luò)配置,包括IP地址段、網(wǎng)關(guān)等。
- 當(dāng)一個(gè)容器連接到一個(gè)自定義網(wǎng)絡(luò)時(shí),Docker會(huì)在宿主機(jī)上創(chuàng)建一個(gè)虛擬以太網(wǎng)橋,連接到宿主機(jī)網(wǎng)絡(luò)接口和自定義網(wǎng)絡(luò)的命名空間。容器的網(wǎng)絡(luò)流量會(huì)通過橋接技術(shù)通過虛擬橋轉(zhuǎn)發(fā)到宿主機(jī)網(wǎng)絡(luò)接口。
其實(shí)你就這樣子記,加入同一個(gè)自定義網(wǎng)絡(luò)就是加入了同一個(gè)網(wǎng)橋,只有同一個(gè)網(wǎng)橋的人才能進(jìn)行通信。這樣,不同自定義網(wǎng)絡(luò)中的容器可以通過虛擬橋進(jìn)行通信,而與宿主機(jī)網(wǎng)絡(luò)和其他自定義網(wǎng)絡(luò)隔離開。
案例演示
# 1.首先通過命令創(chuàng)建一個(gè)網(wǎng)絡(luò)
docker network create hmall# 2.然后查看網(wǎng)絡(luò)
docker network ls# 結(jié)果:
NETWORK ID NAME DRIVER SCOPE
639bc44d0a87 bridge bridge local
403f16ec62a2 hmall bridge local
0dc0f72a0fbb host host local
cd8d3e8df47b none null local
# 其中,除了hmall以外,其它都是默認(rèn)的網(wǎng)絡(luò)# 3.讓dd和mysql都加入該網(wǎng)絡(luò),注意,在加入網(wǎng)絡(luò)時(shí)可以通過--alias給容器起別名
# 這樣該網(wǎng)絡(luò)內(nèi)的其它容器可以用別名互相訪問!# 3.1.mysql容器,指定別名為db,另外每一個(gè)容器都有一個(gè)別名是容器名
docker network connect hmall mysql --alias db# 3.2.db容器,也就是我們的java項(xiàng)目
docker network connect hmall dd# 4.進(jìn)入dd容器,嘗試?yán)脛e名訪問db
# 4.1.進(jìn)入容器
docker exec -it dd bash# 4.2.用db別名訪問
ping db# 結(jié)果
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms# 4.3.用容器名訪問
ping mysql
# 結(jié)果:
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms
OK,現(xiàn)在無需記住IP地址也可以實(shí)現(xiàn)容器互聯(lián)了。
總結(jié):
-
在自定義網(wǎng)絡(luò)中,可以給容器起多個(gè)別名,默認(rèn)的別名是容器名本身
-
在同一個(gè)自定義網(wǎng)絡(luò)中的容器,可以通過別名互相訪問
完整微服務(wù)項(xiàng)目部署【前后端兼具】
項(xiàng)目說明:
-
hmall:商城的后端代碼
-
hmall-portal:商城用戶端的前端代碼
-
hmall-admin:商城管理端的前端代碼
部署的容器及端口說明:
項(xiàng)目 | 容器名 | 端口 | 備注 |
---|---|---|---|
hmall | hmall | 8080 | 黑馬商城后端API入口 |
hmall-portal | nginx | 18080 | 黑馬商城用戶端入口 |
hmall-admin | 18081 | 黑馬商城管理端入口 | |
mysql | mysql | 3306 | 數(shù)據(jù)庫 |
在正式部署前,我們先刪除之前的nginx、dd兩個(gè)容器:
docker rm -f nginx dd
mysql容器中已經(jīng)準(zhǔn)備好了商城的數(shù)據(jù),所以就不再刪除了。
部署Java項(xiàng)目
?hmall
項(xiàng)目是一個(gè)maven聚合項(xiàng)目,使用IDEA打開hmall
項(xiàng)目,查看項(xiàng)目結(jié)構(gòu)如圖:
我們要部署的就是其中的hm-service
,其中的配置文件采用了多環(huán)境的方式:
其中的application-dev.yaml
是部署到開發(fā)環(huán)境的配置,application-local.yaml
是本地運(yùn)行時(shí)的配置。
查看application.yaml,你會(huì)發(fā)現(xiàn)其中的JDBC地址并未寫死,而是讀取變量:
這兩個(gè)變量在
application-dev.yaml
和application-local.yaml
中并不相同:
在dev開發(fā)環(huán)境(也就是Docker部署時(shí))采用了mysql作為地址,剛好是我們的mysql容器名,只要兩者在一個(gè)網(wǎng)絡(luò),就一定能互相訪問。
我們將項(xiàng)目打包:
結(jié)果:
?將hm-service
目錄下的Dockerfile
和hm-service/target
目錄下的hm-service.jar
一起上傳到虛擬機(jī)的root
目錄:
?部署項(xiàng)目:
測試,通過瀏覽器訪問:http://你的虛擬機(jī)地址:8080/search/list? ? ? ? ? OK!~
部署前端
hmall-portal
和hmall-admin
是前端代碼,需要基于nginx部署。在課前資料中已經(jīng)給大家提供了nginx的部署目錄:
其中:
-
html
是靜態(tài)資源目錄,我們需要把hmall-portal
以及hmall-admin
都復(fù)制進(jìn)去 -
nginx.conf
是nginx的配置文件,主要是完成對html
下的兩個(gè)靜態(tài)資源目錄做代理
我們現(xiàn)在要做的就是把整個(gè)nginx目錄上傳到虛擬機(jī)的/root
目錄下:
然后創(chuàng)建nginx容器并完成兩個(gè)掛載:
-
把
/root/nginx/nginx.conf
掛載到/etc/nginx/nginx.conf
-
把
/root/nginx/html
掛載到/usr/share/nginx/html
由于需要讓nginx同時(shí)代理hmall-portal和hmall-admin兩套前端資源,因此我們需要暴露兩個(gè)端口:
-
18080:對應(yīng)hmall-portal
-
18081:對應(yīng)hmall-admin
命令如下:
?
測試,通過瀏覽器訪問:http://你的虛擬機(jī)ip:18080? ? ? ? ? ?OK!~
進(jìn)階:DockerCompose?
大家可以看到,我們部署一個(gè)簡單的java項(xiàng)目,其中包含3個(gè)容器:
MySQL
Nginx
Java項(xiàng)目
而稍微復(fù)雜的項(xiàng)目,其中還會(huì)有各種各樣的其它中間件,需要部署的東西遠(yuǎn)不止3個(gè)。如果還像之前那樣手動(dòng)的逐一部署,就太麻煩了。
????????Docker Compose可以幫助我們實(shí)現(xiàn)多個(gè)相互關(guān)聯(lián)的Docker容器的快速部署。它允許用戶通過一個(gè)單獨(dú)的 docker-compose.yml 模板文件(YAML 格式)來定義一組相關(guān)聯(lián)的應(yīng)用容器。?
?
基本語法
docker-compose.yml文件的基本語法可以參考官方文檔:
DockerCompose官方文檔https://docs.docker.com/compose/compose-file/compose-file-v3/
一般一個(gè)完整的項(xiàng)目(包含前后端)可以整理為一個(gè)docker-compose.yml文件,然后在文件內(nèi)部依次聲明服務(wù)(容器)
docker run 參數(shù) | docker compose 指令 | 說明 |
---|---|---|
--name | container_name | 容器名稱 |
-p | ports | 端口映射 |
-e | environment | 環(huán)境變量 |
-v | volumes | 數(shù)據(jù)卷配置 |
--network | networks | 網(wǎng)絡(luò) |
案例演示?
這里直接就是把上面我們部署的那個(gè)微服務(wù)完整項(xiàng)目的docker-compose.yml文件寫一下
version: "3.8"services:mysql:image: mysqlcontainer_name: mysqlports:- "3306:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- "./mysql/conf:/etc/mysql/conf.d"- "./mysql/data:/var/lib/mysql"- "./mysql/init:/docker-entrypoint-initdb.d"networks:- hm-nethmall:build: context: .dockerfile: Dockerfilecontainer_name: hmallports:- "8080:8080"networks:- hm-netdepends_on:- mysqlnginx:image: nginxcontainer_name: nginxports:- "18080:18080"- "18081:18081"volumes:- "./nginx/nginx.conf:/etc/nginx/nginx.conf"- "./nginx/html:/usr/share/nginx/html"depends_on:- hmallnetworks:- hm-net
networks:hm-net:name: hmall
基礎(chǔ)命令
編寫好docker-compose.yml文件,就可以部署項(xiàng)目了。常見的命令:
DockerCompose基礎(chǔ)命令文檔https://docs.docker.com/compose/reference/其中,OPTIONS和COMMAND都是可選參數(shù),比較常見的有:
類型 | 參數(shù)或指令 | 說明 |
---|---|---|
Options | -f | 指定compose文件的路徑和名稱 |
-p | 指定project名稱。project就是當(dāng)前compose文件中設(shè)置的多個(gè)service的集合,是邏輯概念 | |
Commands | up | 創(chuàng)建并啟動(dòng)所有service容器 |
down | 停止并移除所有容器、網(wǎng)絡(luò) | |
ps | 列出所有啟動(dòng)的容器 | |
logs | 查看指定容器的日志 | |
stop | 停止容器 | |
start | 啟動(dòng)容器 | |
restart | 重啟容器 | |
top | 查看運(yùn)行的進(jìn)程 | |
exec | 在指定的運(yùn)行中容器中執(zhí)行命令 |
案例演示?
打開瀏覽器,訪問:http://yourIp:8080?