# docker 筆記 https://www.youtube.com/watch?v=gAkwW2tuIqE https://www.youtube.com/watch?v=Gjnup-PuquQ docker 到 雲端 https://www.youtube.com/watch?v=3OP-q55hOUI ## 介紹 docker只是用來管理container container就是一個封裝的東西 裡面有規定的格式之類 你可以想成它是VM但不是實際安裝的 VM的取代品,讓不同電腦都能跑程式,一個內核安裝作業系統跟其他環境 他適用操作系統內的容器或模擬器容器去做的 ![](https://i.imgur.com/EpBfZt2.png) 然後會在上面用一個Docker Engine 三大部分 dockerfile image container dockfile會去規範如何做,然後跑image,image去跑container ## 自動升級更新執行中的 Docker 容器解決方案 - watchtower https://www.youtube.com/watch?v=u-ge5V6CN6w ## Docker Hub 用來託管image的 給開發人員共享的 可以看那些可以from下來的 ## Docker Composer 用來管理多容器用的 ## laravel 使用docker https://learnku.com/articles/24862 ## docker vs VM VM一樣是contrainer的概念 但她有個問題是會造成實際佔用空間 最簡單來說你有不同的VM一樣安裝Linux 但這樣重複Linux造成耗損 而且不能給別人用 所以每台都要重複 ![](https://i.imgur.com/KDxHRBK.png) ## 安裝 ![](https://i.imgur.com/tr6zOj3.png) mas 跟 windos一樣 linux不用 因為他本身就支援容器了 能符合規格就用desktop 不能就用tollBox 然後去vscode安裝 docker的docker的IDE(如果你有安裝這個,在你寫docker的文件時 會有提示,向你安裝ubuntu這個 就可以連去docker網站確認是不是這個) ## docker desktop 基本上可以選擇要不要開機啟動 不然就要手動安裝 windos 安裝之後要啟動 ### hper-v 虛擬機的 ![](https://i.imgur.com/q5u2ENX.png) Hyper-V,代號Viridian, 舊稱Windows Server Virtualization,是Microsoft的本機虛擬機器管理程式, ### 容器功能 ![](https://i.imgur.com/IQabKGV.png) docker只是管理容器的 要先啟用 ### wsl 要用手動安裝的 https://docs.microsoft.com/en-us/windows/wsl/install-manual 如果抱錯 他會帶你去官網看文黨 如果wsl指令不能用 就去網路找 比較注意的點是在 如果他抱錯 會帶你去官網 然後你會比對就好 小心BIOS的虛擬化沒開 ## docker ToolBox 舊的用法 不推薦 除非你電腦系統是舊的 ## 安裝後的一些總結 Docker Engine 是安裝在linux裡面的 Docker Desktop 可幫助您像在 Linux 上一樣在 Mac 和 Windows 上輕鬆構建、共享和運行容器。Docker 處理複雜的設置並允許您專注於編寫代碼 docker desktop只是來安裝 docker engine 跟一些令命用 ## dockerfile 他就像DNA告訴docker如何產生image ![](https://i.imgur.com/YyWKxQH.png) from來源 workdir 工作目錄 copy 複製文件 但如果dir不一樣 要在上面先寫workdir run 每次都會跑的 記住 這邊只能install之類的 不要跑serve image只是用來 當模板 不是寫你container要做的事情 cmd 用來寫container要做的事情(是array 第一個寫你的指令(ex php node) 第二個是他的指令要做的事情) expose 暴露的 因為容器是隔離的 所以它裡面的網路 跟外面的不一樣 所以你要 暴露port才能連到外面(做好記得 只是開放 所以你容器 run 要 -p 去連線 這只是告訴容器能外露 不是幫你連線了) ![](https://i.imgur.com/dlALrqt.png) 注意 npm install之前 先copy package.json到 前面 copy package.json . run npm install copy . ./app 這樣寫的原因在於它會緩存 所以如果一開始那寫法 copy 有改動 他會重新 install 他是掃描指令裡面的東西有沒有改動 這樣會快一點 ### run vs cmd run是給產生Image用 所以如果你用 run node serve.js 這樣等於每個contanier都要 跑 但cmd不一樣 他是你container執行才會跑 ## dot .的用意 https://stackoverflow.com/questions/55034727/what-does-mean-in-docker-does-it-mean-the-current-working-directory-of-the-im ## image 所有作業系統跟依賴的安裝環境 可以啟動多個contanier 可以上傳到雲端 然後給每個人拉下來 他就是藍圖的意思 他沒有name 但他有tag 不然id太長了 很麻煩 但其實tag 是由 name(你用ps 列出來 他會是 repository) 跟 tag和在一起的 ![](https://i.imgur.com/QgaBKqZ.png) ex node:14版本之類的 參數(在 build 跟 . 中間) --tag -t test:version1 之類的 --prune 全部刪掉(但有有一些使用過的不會刪除 不太清楚這邊)(可以加上 -a 把全部都刪除) ### 查看image的詳細資訊 docker image inspect ### image改名 雖然是改名稱 但其實是複製一個 docker tag 舊名稱 新名稱 ## container 映像的一個正在運行的進程 是多進程的可以一次很多個 ### docker build . 這的意思是會在當前目錄找 dockerFile 並產生image ### dokcer run(第一次)(有的話就用start 參數差不多) 如果本地沒有會自動幫你pull 但如果本地有 他會run 所以如果有新版本 他不會pull 要小心 build完成 會有imagr id 然後run 就會產稱contanier 每次run 的名稱都不同 可以用ps 跟destop看 這邊可以當成註冊container 之後啟動就能用destop用了 註冊如果有http街口 本地的 3000 port之類的 ![](https://i.imgur.com/8PpOaYP.png) -p (port) -P (大寫自動映射 就是2000 對上 2000) 用本地的3000 啟動 裡面的 3000 注意事項 如果run 的image本地沒有 會自動pull 如果本地有 並不會更新 #### 參數 用--help看看 --name 是用來創造名稱 -it 是 交互式 介面 加上 -i 加上 -t (命令提示terme) -d 分離模式 這個進程不會被堵賽 就是可以繼續用這個 但容器一樣是啟動的狀態 但這樣缺點看不到cli輸出的東西 要連回去用attch 或用logs docker logs 容器名稱(可以用-f fllow他 等於watch) -a attach 從分離模式回去交互模式 我都用分離 然要要看log在打 他會顯示全部的log 不會只有一個 -rm 當容器停止時 會自動刪除 ### docker ps(ps在linux裡面 指令是用來管理後台進程之類的 這邊container也算是相關的 ) 查看 當前啟動的container -a 可以看到全部 ### docker stop 啟動的container把它關閉 不能直接ctal + c關掉 要先找到名稱 然後 docker stop name ### docker cp 把容器內的複製出來 或把外面的複製進去容器內 ![](https://i.imgur.com/Xo85aAQ.png) 第一行是把外面的放進去 一樣兩個路徑 用空白隔開 (container內部的用: 選路徑) 第二行是把裡面的拿出來 用法跟上面一樣 不要把更動的丟進去這樣可能會毀 改動就用update的方法 最好的做法是 把裡面的log之類的拉出來 ## rm docker rm 可一次刪多個 空白間隔 更快速優雅的 因為容器都是image來的 所以docker images查看一下 不要的就刪除 docker rmi id(image的) 但注意圖像有備用道就不能刪除 不管他的contaniner是不是stop start 反正這邊你就用desktop ## 指令 **docker ps** 會列出所有系統上正在運行的容器列表 每個容器都有id 連到一個image ## docker 分享 可分為給dockerfile 跟 給image 給image比較方便 ![](https://i.imgur.com/sxgMFTF.png) push上去 pull下來 但除了docker hub 還有其他的供應商能使用 ![](https://i.imgur.com/RHrD1IK.png) 但如果是私人供應商的話 要加上 host:name(可以看供應商文件) ### push push的時候 名稱要跟遠端一樣 第二 不能隨便推 所以要先登入 docker login 登出用 docker logout 注意他推的時候不是把全部image推上去 那太大了 他會把你的image 所需要的做連結(ex 裡面有node 就跟node做連結) ## data ![](https://i.imgur.com/DZvRYgn.png) 第一種是環境 原始碼 code那種 唯獨 第二是種cache 那種 暫時 第三種是用戶註冊那種 要永久保存的 解決方法 用 volumes ## volumes ![](https://i.imgur.com/QY8qkGZ.png) 他是實際存在 你的host的 他會映射到 對應的容器 可以把他想成copy的感覺 但差異在 dockerfile的copy是快照 但volumnes是一直連接 ![](https://i.imgur.com/lWStkUp.png) 分成兩種 ### 匿名 在dokcerfil寫 volumnes是匿名的 匿名不能保存 因為他是給隨機名稱 ![](https://i.imgur.com/Qn4nBvI.png) ### 命名 在run的時候給 參數 綁在 對應的container 但他不是在容器裡面 所以容器關掉還會再 ![](https://i.imgur.com/RCByqJH.png) 記住記住 資料都不用編輯跟查看 因為兩種的資料你都沒有訪問許可權 ## bind mounts 請參閱https://docs.docker.com/docker-for-windows/ `文件共享選項卡僅在 Hyper-V 模式下可用,因為在 WSL 2 模式和 Windows 容器模式下,所有文件都由 Windows 自動共享。` 如何綁定 ![](https://i.imgur.com/CeOhbIK.png) 跟volumn很像 差別在這邊會自動跟你外部的連接 但volumn你沒有訪問權 你只知道有 但不能編輯跟查看 path是絕對路徑 可用"" 起來 ![](https://i.imgur.com/9Qd3jPm.png) 注意崩潰 ![](https://i.imgur.com/5mUkWsi.png) 很容易犯錯 ![](https://i.imgur.com/zNh1UQW.png) 因為你跑dokcerfile 然後install好了 然後對應到外面 但因為docker不會改動到外面的結構(bind mounts不會) 所以你檔案不會在外面有改動 <!-- 因為bind mounts是把外面印設進去的 --> 所以外面的改動到裡面 把packjson關掉了 所以run的時候 serve.js 的 express才掛掉 沒有node_moudel volumn是路徑越長 越贏 所以你先建立連結 然後你會把匿名卷的node給裡面用 ## node env 之類的 問題 如果你在其他對應的資料夾 Ex node.js 或 env那些 你改動外面的沒有一起改動到 因為你對應的是某個資料夾下 但你要重啟網路serve才會看到 node可以安裝這個 ![](https://i.imgur.com/flqqpwM.png) 會自動幫你restart ## 唯獨卷 ![](https://i.imgur.com/cfq6dSy.png) 加上ro 裡面檔案不能改到外面 只能外面對內部用到 記住如果要裡面的對外 可能會不能用 ## 管理volumn 這ls列出來 不會有mounts那種volumn 因為他不能管理你外面文件在對內改變的 ## gnore ![](https://i.imgur.com/sHk0kNq.png) 一樣 node vender之類的也不要 ## env ![](https://i.imgur.com/taEk02g.png) 可以在image建立時設立 也可以用container run的時候掛載 如果是在image dockerfile那邊 你env的 數字 下面port之類的要計算 要加上$字號 ## ARG image用的變數 ![](https://i.imgur.com/AvOceoY.png) 然後使用在dockfile裡面 ![](https://i.imgur.com/ykd4aZd.png) 在build的時候使用 ![](https://i.imgur.com/HHbq4rs.png) ## 網路跨容器通訊 有三種情況 容器打API 容器互相溝通 容器連結本地的database之類的 ## 容器打api ![](https://i.imgur.com/XXMuIpB.png) 是開箱就可以用到的 ## 容器連到本地的database locahost 域改成 docekr.internal ![](https://i.imgur.com/3J9eWB4.png) ## 容器之間互相溝通 最簡單等級一方法 ![](https://i.imgur.com/2DbW9SA.png) 檢查那個container 看裡面的networkSetting ![](https://i.imgur.com/ICFx5DY.png) 看id多少 連上去 但是但是 這每次都會不一樣所以 這方法不好 ## 容器網路 ![](https://i.imgur.com/uWr7a9I.png) ![](https://i.imgur.com/2eGtmI4.png) 把一些容器放在同一個網路裡面 只要連的時候寫容器名稱 docker會自動幫你做轉換 不用寫他的ip之類的 容器能互相通訊 而且不用-p 因為-p是容器要對外對到port的時候才要的 React之類的要小心 不能用容器名稱 就算在同一個網路內 因為他們執行是在網路 而不是容器裡面 ## laravel nginx ![](https://i.imgur.com/3YhMxkh.png) image stable穩定的 aplpine輕量化 ports ![](https://i.imgur.com/hDFCTcP.png) 官方文件有寫 volumn 後面路徑 官方有寫 :ro 是readonly ![](https://i.imgur.com/OXIwpEn.png) ###### tags: `Docker`