# 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的取代品,讓不同電腦都能跑程式,一個內核安裝作業系統跟其他環境
他適用操作系統內的容器或模擬器容器去做的

然後會在上面用一個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造成耗損
而且不能給別人用
所以每台都要重複

## 安裝

mas 跟 windos一樣
linux不用
因為他本身就支援容器了
能符合規格就用desktop
不能就用tollBox
然後去vscode安裝 docker的docker的IDE(如果你有安裝這個,在你寫docker的文件時 會有提示,向你安裝ubuntu這個 就可以連去docker網站確認是不是這個)
## docker desktop
基本上可以選擇要不要開機啟動
不然就要手動安裝
windos
安裝之後要啟動
### hper-v 虛擬機的

Hyper-V,代號Viridian, 舊稱Windows Server Virtualization,是Microsoft的本機虛擬機器管理程式,
### 容器功能

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

from來源
workdir 工作目錄
copy 複製文件 但如果dir不一樣 要在上面先寫workdir
run 每次都會跑的
記住 這邊只能install之類的
不要跑serve
image只是用來 當模板 不是寫你container要做的事情
cmd 用來寫container要做的事情(是array 第一個寫你的指令(ex php node) 第二個是他的指令要做的事情)
expose 暴露的 因為容器是隔離的 所以它裡面的網路 跟外面的不一樣
所以你要 暴露port才能連到外面(做好記得 只是開放 所以你容器 run 要 -p 去連線 這只是告訴容器能外露 不是幫你連線了)

注意
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和在一起的

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之類的

-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
把容器內的複製出來
或把外面的複製進去容器內

第一行是把外面的放進去 一樣兩個路徑 用空白隔開 (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比較方便

push上去
pull下來
但除了docker hub 還有其他的供應商能使用

但如果是私人供應商的話 要加上 host:name(可以看供應商文件)
### push
push的時候 名稱要跟遠端一樣
第二 不能隨便推
所以要先登入
docker login
登出用
docker logout
注意他推的時候不是把全部image推上去
那太大了
他會把你的image 所需要的做連結(ex 裡面有node 就跟node做連結)
## data

第一種是環境 原始碼 code那種 唯獨
第二是種cache 那種 暫時
第三種是用戶註冊那種 要永久保存的
解決方法 用 volumes
## volumes

他是實際存在 你的host的 他會映射到 對應的容器
可以把他想成copy的感覺 但差異在 dockerfile的copy是快照
但volumnes是一直連接

分成兩種
### 匿名
在dokcerfil寫 volumnes是匿名的 匿名不能保存 因為他是給隨機名稱

### 命名
在run的時候給 參數 綁在 對應的container 但他不是在容器裡面
所以容器關掉還會再

記住記住
資料都不用編輯跟查看
因為兩種的資料你都沒有訪問許可權
## bind mounts
請參閱https://docs.docker.com/docker-for-windows/
`文件共享選項卡僅在 Hyper-V 模式下可用,因為在 WSL 2 模式和 Windows 容器模式下,所有文件都由 Windows 自動共享。`
如何綁定

跟volumn很像
差別在這邊會自動跟你外部的連接
但volumn你沒有訪問權 你只知道有 但不能編輯跟查看
path是絕對路徑
可用"" 起來

注意崩潰

很容易犯錯

因為你跑dokcerfile 然後install好了
然後對應到外面
但因為docker不會改動到外面的結構(bind mounts不會)
所以你檔案不會在外面有改動
<!-- 因為bind mounts是把外面印設進去的 -->
所以外面的改動到裡面 把packjson關掉了
所以run的時候 serve.js 的 express才掛掉
沒有node_moudel
volumn是路徑越長 越贏
所以你先建立連結 然後你會把匿名卷的node給裡面用
## node env 之類的 問題
如果你在其他對應的資料夾 Ex node.js 或 env那些
你改動外面的沒有一起改動到
因為你對應的是某個資料夾下
但你要重啟網路serve才會看到
node可以安裝這個

會自動幫你restart
## 唯獨卷

加上ro
裡面檔案不能改到外面
只能外面對內部用到
記住如果要裡面的對外 可能會不能用
## 管理volumn
這ls列出來 不會有mounts那種volumn
因為他不能管理你外面文件在對內改變的
## gnore

一樣 node vender之類的也不要
## env

可以在image建立時設立 也可以用container run的時候掛載
如果是在image dockerfile那邊 你env的 數字
下面port之類的要計算 要加上$字號
## ARG
image用的變數

然後使用在dockfile裡面

在build的時候使用

## 網路跨容器通訊
有三種情況
容器打API
容器互相溝通
容器連結本地的database之類的
## 容器打api

是開箱就可以用到的
## 容器連到本地的database
locahost 域改成 docekr.internal

## 容器之間互相溝通
最簡單等級一方法

檢查那個container
看裡面的networkSetting

看id多少 連上去
但是但是 這每次都會不一樣所以 這方法不好
## 容器網路


把一些容器放在同一個網路裡面 只要連的時候寫容器名稱
docker會自動幫你做轉換 不用寫他的ip之類的
容器能互相通訊 而且不用-p
因為-p是容器要對外對到port的時候才要的
React之類的要小心 不能用容器名稱 就算在同一個網路內
因為他們執行是在網路 而不是容器裡面
## laravel
nginx

image stable穩定的 aplpine輕量化
ports

官方文件有寫
volumn
後面路徑 官方有寫 :ro 是readonly

###### tags: `Docker`