--- tags: AEWIN study --- (ノ◕ヮ◕)ノ*:・゚✧ --- ###### tags: `docker` [TOC] # [Study note][1] Docker note 避免環境衝突和程式的相依性,所以需要透過 docker 來產生專屬的 container... ## 安裝教學 :::info 以下安裝步驟環境為透過 VirtualBox 上已經安裝好的 Ubuntu 18.04 來執行 Docker ::: > 參考資料 > + [Ubuntu Linux 安裝 Docker 步驟與使用教學](https://blog.gtwang.org/virtualization/ubuntu-linux-install-docker-tutorial/) > + [docker docs - Install Docker Engine on CentOS](https://docs.docker.com/engine/install/centos/#install-using-the-repository) + 安裝 Docker ```shell $ sudo apt-get install docker.io ``` + 確認 Docker 版本 ```shell $ docker version` ``` ![](https://i.imgur.com/cENq4mW.png) + 將自己的使用者帳號加入至 Docker 群組: ```shell $ sudo usermod -aG docker $(USER_NAME) ``` ![](https://i.imgur.com/ntUdF4o.png) + 啟動 Docker 服務 ```shell $ sudo docker service docker start ``` **!! 完成後登出再重新登入** ## Create Dockerfile to build image > 參考資料 > + [Day5: 實作撰寫第一個 Dockerfile](https://ithelp.ithome.com.tw/articles/10191016) > - 怎麼把 volume 寫入 Dockerfile 中 : > [Day18:使用 Docker Volume 的功能 (二)](https://ithelp.ithome.com.tw/articles/10192703) > + command reference > [docker docs - docker build](https://docs.docker.com/engine/reference/commandline/build/) > + Dockerdile sample > [docker docs - Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) > [Dockerfile sample - CentOS](https://hub.docker.com/_/centos) + 建立測試資料夾 ```shell $ mkdir $(FOLDER_NAME) ``` + 進入測試資料夾 ```shell $ cd $(FOLDER_NAME) ``` + 建立 Dockerfile(打包 image 的指令檔) ```shell $ vim Dockerfile ``` + 在 Dockerfile 中依序列下環境需要的更新和安裝 (image 剛建立時, 就像剛裝好的 OS 一樣),在打包 image 時會自動將這些步驟加入打包過程中 ![](https://i.imgur.com/09SHpYY.png) + 建立 docker image (如遇到權限問題請再前面加上 `sudo`) ```shell $ docker build -t $(IMAGE_NAME) . --no-cache ``` ![](https://i.imgur.com/e5HThki.png) . . . ![](https://i.imgur.com/g47TUbB.png) ## 執行 image 到 container 中 > 參考資料 > + command reference > [docker docs - docker run reference](https://docs.docker.com/engine/reference/run/) + 檢查目前有什麼 image ```shell $ docker images ``` ![](https://i.imgur.com/tzLc4X4.png) + 下載 docker server 上的 image (i.e. ubuntu 16.04) ```shell $ docker pull ubuntu:16.04 ``` + 透過 run 命令執行 image 到 container 中 ```shell $ docker run -it $(IMAGE_NAME) ``` ![](https://i.imgur.com/SD2igjp.png) **可以看到 user name 已經從原本的使用者 prince 變成 root, 表示我們已經切換到 container 中了** + 如何檢查 container 掛載的 volume 在 host OS 上的實際位置 由於我們在 Dockerfile 中有寫到 volume 的設定, 所以在開啟 image 到 container 中時已經從 host OS 中自動掛載一個目錄到 container 下, 要透過下列步驟來取得實際路徑 - 取得 container ID ```shell $ docker ps -a ``` ![](https://i.imgur.com/Y8qBCej.png) - 透過 container ID 來取得掛載到 host OS 中的實際位置 ```shell $ docker inspect -f '{{.Mounts}}' $(CONTAINER_ID) ``` ![](https://i.imgur.com/4NtDdbq.png) **實際存取該位置時需要切換到 root 權限** + 在 container 中測試編譯 - 把程式和 makefile 複製到 host OS 中對應到 volume 的位置 - 測試編譯 ![](https://i.imgur.com/v9jLTmt.png) + 如果 container 停止了,可以透過下面命令重新執行,如果執行 run 重新啟動,其實是重新開啟一個 container 和重新掛載一個新 volume 位置 - 重新啟動 container ```shell $ docker start $(CONTAINER_NAME)` ``` - 執行 container ```shell $ docker exec -it $(CONTAINER_NAME) /bin/bash ``` ![](https://i.imgur.com/iAgcdDR.png) ## Docker 相關指令 ### 顯示目前所有 container 狀況 ```shell $ docker container ls -a ``` ### 刪除指定 container ```shell $ docker container rm $(CONTAINER_NAME) ``` ### 檢查所有 image ```shell $ docker images ``` ### 刪除指定的 image ```shell $ docker rmi $(IMAGE_ID) ``` ## 實用小功能 ### 當做好 Docker image 後發現有些操作 Dockerfile 漏掉了,該怎麼辦? - 請參考:[How To Commit Changes To A Docker Image With Examples](https://phoenixnap.com/kb/how-to-commit-changes-to-docker-image) - 在 container 中將想要的修改完成 - 退出 container ```shell $ exit ``` - 取得想要修改的 container 資訊 ```shell $ sudo docker ps -a ``` ![](https://i.imgur.com/ipOOE13.png) - 透過指令來提交想要的 image(如果名稱相同將會覆蓋原來的 image) ```shell $ sudo docker commit [CONTAINER_ID] [new_image_name] ``` ![](https://i.imgur.com/QkMIV2A.png) - 檢查 image 清單,發現 image 已經變更成功 ![](https://i.imgur.com/YJp5UzY.png) - 雖然已經完成 image 更新,但要記得再把需要更動的部分同步到Dockerfile 中,這樣需要透過 Dockerfile 打包新的 image 時才不會出現沒同步到的問題 ### 如何匯出已經在使用的 image > 參考資料:[docker docs - docker save](https://docs.docker.com/engine/reference/commandline/save/) + 列出目前的 image ```shell $ docker images ``` + 將選擇的 image 打包成 gz 檔 ```shell $ docker save $(IMAGE_NAME) | gzip > $(NEW_IMAGE_NAME).tar.gz ``` ![](https://i.imgur.com/AUR1SSR.png) ### 如何匯入打包好的 image > 參考資料:[ > [Docker] 比較 save, export 對於映象檔操作差異](https://blog.hinablue.me/docker-bi-jiao-save-export-dui-yu-ying-xiang-dang-cao-zuo-chai-yi/) > [Lsmod and modprobe not found](https://forums.docker.com/t/lsmod-and-modprobe-not-found/17558/6) + 複製打包好的 image 到 client 上 + 透過下列命令把打包好的 image 匯入 client docker 上 ```shell $ docker load < $(NEW_IMAGE_NAME) ``` + 匯入的 image 如果需要執行像 modprobe 的命令,請在啟動 container 時加上 `--privileged` 命令 ex. ```shell $ docker run -it --privileged $(IMAGE_NAME) $ docker exec -it --privileged $(IMAGE_NAME) /bin/bash ``` + 當 export image 的 OS 和 import image 的 OS 差異過大時,建議先將落後的版本升級上來 > 查詢發行版本 `$ cat /etc/*release` , 查詢核心版本 `$ uname -r` + 以我在工作的環境中 export OS : Ubuntu 18.04 (Kernel:5.3.0-62-generic) import OS : CentOS 7.8.2003 (Kernel 3.10.0-1227) 由於版本差距過大,所以需要把 CentOS Kernel 升級到 v5.7,升級教學可以參考 [](https://) ### 如何備份正在使用中的 container 成為新的 images > 參考資料: > [Docker 容器備份及還原](https://www.opencli.com/linux/docker-container-backup-restore) > [docker docs - docker commit](https://docs.docker.com/engine/reference/commandline/commit/) ```shell $ docker commit -p $(CONTAINER_NAMES) $(TARGET_IMAGE_NAME) ``` --- 參考資料: [1. 用30天來介紹和使用 Docker](https://ithelp.ithome.com.tw/users/20103456/ironman/1320) [2. 圖解Docker教學-前端學習Docker的4大原因 feat. 六角學院 |入門|程式|科技|開發](https://www.youtube.com/watch?v=0fFO2ez1dWA)