# Docker ## Introduction 三個概念: * Image * Container * Repository ### Image Image 包含了要執行的所有東西,例如完整的 ubuntu,或者 Python 以及需要的套件等等。 可以在 shell 下 `dokcer images -a` 來顯示當前系統有什麼 imageGot permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Delete "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/8329955d3214": dial unix /var/run/docker.sock: connect: permission denied ```shell $ docker images -a ```  我們在建立 image 時,常常因為一些小錯誤會建立失敗(例如版本不合),這時候建立失敗的 image 使用 `dokcer images -a` 顯示出來的 TAG 都會是 `none` ,這種時候我們必須得移除這些 `none`,我們可以透過剛剛下的 `dokcer images -a` 來找到這些 none 的 image ID, 然後使用 `docker rmi [OPTIONS] IMAGE [IMAGE...]` 來移除。 ```shell $ docker rmi [OPTIONS] IMAGE [IMAGE...] ``` 這些失敗的 image 是無法使用的,建立失敗後請記得隨手清掉,不然很佔空間的~~ 這裡需要特別注意的是,如果 image 已經掛載在 container 上,則 image 會沒有辦法順利被刪除,必須先刪掉對應的 container 後才可以再刪除 image。 ### Repository 這個不用特別管,除非你想上傳自己的 image,多數時候我們都是從 [Dokcer hub](https://hub.docker.com/),把別人已經製作好的 image 給 pull 下來,類似 github 的 `pull` 機制,也可以透過 `push` 把自己的 image 上傳到倉庫中。 ### Dockerfile `Dockerfile` 是一個可以自動幫我們把 image build 起來的檔案,通常我們都是以一個已經存在的 image 做為基底 (e.g. python/ ubuntu),然後下去做些許改動。 注意到,在 docker build 的時候,Docker 預設會尋找當前目錄底下的 `Dockerfile`檔案,所以通常約定俗成都會把這個文字檔命名為 `Dockerfile` 如下:  通常我們都會拿別人寫好的 image 下去做魔改,以下是一個 Dockerfile 的範例:  語法: * FROM * 必須以 `FROM` 開頭 * FROM 指的是要從哪個基底 image 下去做修改 * WORKDIR * 設置當前目錄,Docker 會將指定的目錄設定為當前的工作目錄,只後如果執行任何指令(e.g. RUN、CMD、ENTRYPOINT、COPY…) 都會在這個目錄下進行。 * COPY * `COPY [--chown=<user>:<group>] <source path>... <dist path>` * 複製「來源文件\目錄」到的 Image 中的「文件\目錄」中。 * 這裡的 `COPY ./app .` 的意思就是把 build 環境下的 `/app` 資料夾複製到 container 的 WORKDIR 路徑下 * 注意到如果要包起來的東西不多的話,可以考慮直接下 `COPY . .` 。 * RUN * 用來執行 Shell 指令,例如 `apt-get install` 之類的。 `Dockerfile` 寫完之後,執行 `docker build -t [YOUR IMAGE NAME] .` 就可以把 image 建起來了,`-t` 是幫你的 image 加一個標籤。 ### Container Container 是把 Image 跑起來的 **容器**,它可以被啟動、開始、停止、刪除 每個容器都是相互隔離的、保證安全的平台。 可以透過下列指令,搭配已經存在的 image 來創立 container ```shell $ docker create --name [conainer name] [iamge] ``` 我們可以在創建 container 時給他一個名子,以後要啟動這個 container 可以透過這個名子跟他互動,沒有給的話 docker 會隨機給他一個名子 ```shell $ docker ps -a // 列出所有 container (包含停止的) $ docker run [OPTIONS] IMAGE [COMMAND] [ARG...] // run container $ docker stop [OPTIONS] CONTAINER [CONTAINER...] // stop container $ docker kill [OPTIONS] CONTAINER [CONTAINER...] // kill container $ docker restart [OPTIONS] CONTAINER [CONTAINER...] // restart container $ docker rm [OPTIONS] CONTAINER [CONTAINER...] // rm container $ docker logs [OPTIONS] CONTAINER // check containers log ``` `stop` 跟 `kill` 的差別在於: stop 屬於 `graceful shutdown`,而 kill 會直接停止 注意到移除 contaier 是使用 `rm`,而移除 image 是 `rmi (i: image)` `docker run [OPTION] IMAGE` 可以加上很多選項,如下 - `-i` : 保持 stdin 開啟 - `-t` : 賦予終端介面 - `-v` : volume - `-p` : port - `-d` : detach, 背景執行 - `-e` : 設定環境變數 - `--name` : 幫 container 取名字 ### Docker volume 如果我們把 container 刪掉的話,存放在該 container 的資料也會被刪除掉,那這時候我們可以透過把 container 跟實體路徑綁定起來,把不想要被刪除掉的資料存放在實體機器上,避免資料不見的問題。 有兩種方式: 1. 執行 docker run 指令時加上 -v 參數,使得 Container 裡面的檔案路徑Mapping 到實體主機的檔案路徑。 2. 在撰寫 Dockerfile 時,加入 VOLUME 指令,做到把資料存放在實體的主機上。使用這種方法需要搭配 docker inspect 指令,才能查詢到實體主機檔案的存放路徑在哪。 這邊我只會教使用 `-v` 的方式 在使用 docker run 指令時,指定 -v 參數,使得實體主機的資料夾路徑 Mapping 到 Container 的資料夾路徑,指令如下 ```shell $ docker run -it --name Computer_Organization -v $PWD/app:/app linux_latest ``` * Container Volumes: * Volumes provide the ability to connect specific filesystem paths of the container back to the host machine. * -t: attach時Container的螢幕會接到原來的螢幕上 * -i: Container stays interactive * -v: volume, `absolute path which you want to mount local folder into container`: `container folder you want to mount with` 也就是說 `$PWD/app:/app` 這邊 * : 前面的是你想要 mount 的實體路徑,需要注意的是,我這邊用 `$PWD` 不是一個很好的方法,建議使用 absolute path。 * : 後面的是 container 內的路徑 建議各位在包 docker 的時候,隨手寫一個 README,這樣以後要重啟重下指令都比較方便。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up