Docker 系列 - 04 - 解疑 & Docker 指令

jsliang發表於2022-03-11

一、前文回顧 & 前言

經過前文的講解,想必小夥伴們可以起 Nginx 容器和 Node 容器並對一些簡單的概念和指令有所瞭解了。

那麼本篇將講解 Docker 中新人需要知道的一些指令和操作。

  • 映象(Image)指令
  • 容器(Container)指令
  • Shell 指令
  • 宿主機和容器程式碼同步
  • 隔離 Hosts
  • 修改容器時間

二、映象(Image)指令

  • 建立映象:docker image build ./ -t hello-docker:1.0.0
  • 檢視映象清單:docker image ls

Docker-demo-14.png

  • 刪除單個映象:docker rmi <image id>
  • 刪除所有映象:docker rmi $(docker images -q)
  • 強制刪除全部映象:docker rmi -f $(docker images -q)

三、容器(Container)指令

  • 建立容器:docker container create -p 2333:80 hello-docker:1.0.0
  • 執行容器(其中那一長串字元,為建立容器得到的結果):docker container start 4a4d2ac6bf3977ee7c5b4a15562bab17d59b4c61531908fd52632fb0c989f430
  • 建立並執行即時容器(退出則關閉並刪除容器):docker run -it --rm --name hello-docker -p 2333:80 hello-docker:1.0.0
  • 檢視容器清單:docker ps -a

Docker-demo-15.png

  • 進入指定容器:docker exec -it 7961990657ef bash

    • bash:根據不同映象來變化,例如 alpine 則需要變成 /bin/sh

Docker-demo-16.png

進入容器(Container)之後,切換 Shell 指令使用(本質上同 VS Code 編輯器終端、Windows 的 cmd 等)
  • 退出容器:exit
  • 啟動/停止/重啟容器:docker start/stop/restart CONTAINER_ID
  • 刪除單個容器:docker rm CONTAINER_ID
  • 強制刪除單個容器:docker rm -f CONTAINER_ID
  • 停止所有容器:docker stop $(docker ps -a -q) 或者 docker stop $(docker ps -aq)
  • 刪除所有容器:docker rm $(docker ps -a -q) 或者 docker rm $(docker ps -aq)

三、Shell 指令

  • 檢視當前資料夾:ls

Docker-demo-17.png

  • 開啟指定資料夾:cd html

Docker-demo-18.png

  • 檢視指定檔案內容(帶行號):cat -n index.html

Docker-demo-19.png

四、程式碼同步

在我們起本地 Docker 服務的時候,很容易就就將程式碼修改了。

但是!該死的程式碼並不會同步到容器中,這時候如果刪除容器這樣操作,也太 low 了吧,所以就需要進行程式碼同步~

下面我們以 Node.js 那個 Demo 為例,操作下如何同步程式碼。

程式碼倉庫地址:https://github.com/LiangJunro...
  • 將宿主機程式碼複製到容器:
docker cp "E:/MyWeb/036-Docker for Node/README.md" 8e1910aa2a12:/usr/src/app/README.md
docker cp 宿主機的路徑                                          容器名|容器 ID:容器中的檔案路徑
注 1:如果是 Windows,且目錄包含空格的話,最好通過 "路徑" 包裹
注 2:目錄的話最好後退一層,例如 docker cp E:/MyWeb/036-Docker for Node/src /usr/src/app/
注 3:cpcopy,拷貝的意思
  • 將容器程式碼複製到宿主機:
docker cp 8e1910aa2a12:/usr/src/app/tsconfig.json E:\MyWeb\all-for-one
docker cp 容器名       :容器中的檔案路徑            宿主機的路徑
  • 讓容器程式碼實時同步宿主機程式碼:
docker run -d -v E:\MyWeb\all-for-one\src:/usr/src/app/src docker-node:1.0.0
docker run -d -v 容器中檔案路徑            :宿主機檔案路徑   容器名      :版本號

我們需要知道的是:

  1. -d:後臺執行
  2. -v A:B:將宿主機 A 路徑的檔案/資料夾掛載到容器 B 的路徑上面(兩者都是絕對路徑)
  3. docker-node:1.0.0:即 docker image ls 檢視到的 REPOSITORYTAG

五、隔離 Hosts

進入容器後,我們可以通過 cat /etc/hosts 檢視到容器的 Hosts

Docker-demo-20.jpg

順帶我們們改了下本地 Hosts 檔案,將百度改成了 127.127.127.127,在容器中 ping baidu.com,我們可以看到 Hosts 跟隨宿主機變化了。

那麼,怎樣才能讓它有自己想法,別亂動呢?

首先,我們找到專案目錄,新增 2 個檔案:

hosts
127.0.0.1       localhost
resolv.conf
nameserver 114.114.114.114

這 2 個檔案,1 個是修改 Hosts,一個是修改 DNS 埠,即我們想法子,讓容器開啟的時候,使用的是獨立的 Hosts 和 DNS 埠。

接著,我們執行指令:

  • docker run -d -v E:\MyWeb\all-for-one\hosts:/etc/hosts -v E:\MyWeb\all-for-one\resolv.conf:/etc/resolv.conf docker-node:1.0.0

Docker-demo-21.jpg

這樣建立的容器,就能起到隔離的效果。

最後,我們進入新容器並 ping baidu.com 即可:

Docker-demo-22.jpg

可以發現,我們成功修改了容器的 Hosts!

六、修改容器時間

正常情況下,Docker 容器的時間,和我們機器的時候是不同的,因為它預設設定的時區問題:

  • 查詢機器時間:date

Docker-demo-23.jpg

可以看到,上面容器的時間,是 UTC,和下面宿主機的完全不一致。

但是,在我們的程式碼中,有些是需要儲存正確的時間的,這就不得不修改一下了。

而修改它們非常簡單,只需要設定下 Dockerfile 就可以了:

Dockerfile
# 設定 Docker 容器時區
RUN apk add --no-cache tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo Asia/Shanghai > /etc/timezone

我們們還是以 Node.js 那個服務舉例,來嘗試統一宿主機和容器的時間。

程式碼倉庫地址:https://github.com/LiangJunro...

我們們按照倉庫的 README.md,建立映象並執行容器:

Docker-demo-24.jpg

進入容器後檢視 date

Docker-demo-25.jpg

可以看到時間正常了!

七、小結

本章我們將一些常見的內容都進行了整理,小夥伴們在第一次看到那麼多指令的時候可能有點懵逼,其實 jsliang 也是一點一點敲起來熟練起來的。

所以這些只能多敲多熟悉,我之前嘗試過幾天沒敲,回頭就忘了,所以整理成這篇文章方便自己和大家回顧。

敬請期待下篇:06 - 入門 & Puppeteer 服務


不折騰的前端,和鹹魚有什麼區別!

覺得文章不錯的小夥伴歡迎點贊/點 Star。

如果小夥伴需要聯絡 jsliang

個人聯絡方式存放在 Github 首頁,歡迎一起折騰~

爭取打造自己成為一個充滿探索欲,喜歡折騰,樂於擴充套件自己知識面的終身學習斜槓程式設計師。

jsliang 的文件庫由 樑峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。<br/>基於 https://github.com/LiangJunrong/document-library 上的作品創作。<br/>本許可協議授權之外的使用許可權可以從 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 處獲得。

相關文章