###### tags: `mynote` # Docker Intro [TOC] ## Image Image 包裝了一個執行特定環境所需要的資源。 每個 image 都有獨一無二的 digest,這是從 image 內容做 sha256 產生的。這個設計能讓 image 無法隨意改變內容,維持資料一致性。 雖然 image 裡有必要的資源,但它無法獨立執行,必須要靠 container 間接執行。 ## Container 基於 image 可以建立出 Container。 它的概念像是建立一個可讀寫內容的外層,架在 image 上。實際存取 container 會經過可讀寫層與 image,因此看到的內容會是兩者合併後的結果。 Container 特性跟 image 不一樣,因為有可讀寫層,所以 container 可以讀寫,也可以拿來執行。 :::info container可以儲存資料, 如果重新創建container,就會變為一個全新的os ::: ## Repository Repository 是存放 image 的空間。 Docker 設計類似分散式版本控制的方法來存放各種 image。而分散式架構就會有類似 git 的 pull / push 行為,實際做的事也跟 git 類似:為了要跟遠端的 repository 同步。 另一個與 repository 很像,但容易混用的名詞為 Registry,後者涵蓋範圍更廣,包含了更多 repository 與身分驗證功能等,通常比較常討論的也是 registry。 目前 Docker 預設的 registry 為 DockerHub,大多數程式或服務的 image 都能在上面找得到。 Image、container、repository 之間的關係就像光碟一樣:早期世紀帝國等光碟遊戲,會需要搭配其他可讀寫空間(如硬碟),才有辦法執行。 Image 像光碟片一樣,唯讀且不能獨立執行 Container 像硬碟一樣,可讀可寫可執行 Repository 則是光碟盒,而 Registry 則是像光碟零售商 # `docker run image_name` ==docker run的行為如下== 1. 前景建立並執行 container 2. 等待執行程式結束(exit)後,會回到前景的命令提示字元 3. 該 container 會被標記成結束狀態 # `docker ps` 列出所有 Docker 容器 ![](https://i.imgur.com/k64bJL0.png) # `docker run -d -p 8080:80 httpd` -p 後面參數 8080:80 的意思代表:當連線到 host 的 8080 port 會轉接到 container 的 80 port。以上面的指令為例,只要輸入 http://localhost:8080/ 即可接到 container 所啟動的 HTTP 服務。 ![](https://i.imgur.com/dMnWeW2.png) # `docker exec -it container_name bash` 進入container內部 # `docker logs -f web` 即時顯示docker內部狀態 ![](https://i.imgur.com/IviePvY.png) ## how to choose base image ![](https://i.imgur.com/kv1NM67.png) ## image layer image需要搭配container才能使用 因為container會創建一個R/W layer user才可以對image做讀寫 :::info 選擇正確的base image, 因之後安裝其它套件可能造成layer增加而佔用空間 所以建議在dockerfile就建置好image所需要的套件 ::: ![](https://i.imgur.com/LgQe960.png) ## `docker image history image_name` show all history of the image ![](https://i.imgur.com/zEzTAnt.png) :::info 很多image都是用alpine linux來製作的 alpine linux是輕量版linux ::: ## 如何製作image 1. crete a folder and name a file `dockerfile` 2. write down your config in dockerfile ```dockerfile= From nginx:1.19.6-alpine maintainer dennis huang copy index.html /usr/share/nginx/html/ #copy file to image CMD ["nginx","-g","daemon off;"] ``` ![](https://i.imgur.com/0pXHrEe.png) 3. build image ```shell= docker build -t myfirstimage2 . ``` 4. run image ```shell= docker run -p 8080:80 -d myfirstimage2 ``` 5. check the results ```shell= curl http:\\localhost:8080 ``` ![](https://i.imgur.com/88cJQeP.png) # Docker with VSCODE ## deploy 1. open a folder for project ![](https://i.imgur.com/hCh9IaF.png) 3. 選取 Remote-Containers: Add Development Container Configuration Files ![](https://i.imgur.com/9UHByvU.png) 3. set devcontainer.json ![](https://i.imgur.com/2ZG4OSw.png) 4. open folder in container ![](https://i.imgur.com/yDKazkk.png) 5. 確定已經進入container ![](https://i.imgur.com/7lhV4Kg.png) 6. 如果想要加修改devcontainer.json,例如預載extension - 找到extension ID ![](https://i.imgur.com/YKN2a4a.png) -加入devcontainer.json ![](https://i.imgur.com/8Bg0pE6.png) - rebuild container ==需要在container內部執行此動作== ![](https://i.imgur.com/ZgmWkM3.png) ## Install heoku in docker ```shell= sudo curl https://cli-assets.heroku.com/install-ubuntu.sh | sh ``` # FAQ ## container內的git出現一堆modified文件怎麼辦? A: 增加一個.gitattributes file 並加入如下內容 ``` * text=auto eol=lf *.{cmd,[cC][mM][dD]} text eol=crlf *.{bat,[bB][aA][tT]} text eol=crlf ``` ![](https://i.imgur.com/FoGIzQu.png)