簡介
Docker 是一種虛擬化技術,透過 container 的方式將應用程式和所需執行環境打包起來,方便佈署到其他伺服器上,避免因為系統環境不同而無法正確執行,也可以節省建立環境的繁瑣步驟。此外,Docker 也可以用來模擬不同環境下,程式是否能正確執行。
和 Virtual Machine 相比,Docker 的利用率更高,容量小、高效能、啟動速度快,一台伺服器上(Host)可以執行多個 container, 而每個 container 是獨立的,互不影響。
接下來紀錄一下如何在 Linux 環境上安裝及使用 Docker,並且使用 Docker 將我們的應用程式及執行環境打包。
安裝
這裡我們使用的系統環境是: Ubuntu 16.04
設定 Repository
Update:
1 | $ sudo apt-get update |
安裝所需套件:
1 | $ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common |
新增 Docker GPG key:
1 | $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
Add repository:
1 | $ sudo add-apt-repository \ |
Install Docker CE
Update:
1 | $ sudo apt-get update |
Install:
1 | $ sudo apt-get install docker-ce |
裝好之後,確認一下是否安裝成功:
1 | docker version |
正常運作的話,可以看到以下畫面:
如果有出現 Permission denied
的錯誤訊息,將當前使用者加入 docker
群組即可解決:
1 | $ sudo gpasswd -a ${USER} docker |
設定好之後,記得要重新登入才會生效。
基本概念
Image
映像檔,可以透過 Docker 將應用程式和執行環境打包成 image, 方便之後直接安裝到其他伺服器上。
Container
Container 是利用 image 建立出來的,一個 Image 可以 create 多個 container, 每個 container 是獨立的,互不影響。
基本使用
搜尋及下載 Image
在 Docker Hub 上有許多公開的 image, 可以使用以下指令來搜尋所需要的 image:
1 | $ docker search ubuntu |
下載 image:
1 | $ docker pull ubuntu |
查看所有 Image
1 | $ docker images |
刪除 Image
1 | $ docker rmi [options] <image> |
建立並啟動 Container
下載好 image 之後,執行以下指令就可以建立並啟動 container:
1 | $ docker run -it --name <container_name> <image> bash |
-it
是可以進入這個 container 的 shell 進行操作,如果要離開 container, 使用 exit
指令即可。
--name
設定 container 名稱。
查看 Container
查看目前運行的 container:
1 | $ docker ps |
查看所有 container
1 | $ docker ps -a |
進入 Container
1 | $ docker exec -it <container_id> bash |
停止 Container
1 | $ docker stop [options] <container_id> |
重新啟動 Container
1 | $ docker restart [options] <container_id> |
刪除 Container
1 | $ docker rm [options] <container_id> |
Dockerize 應用程式
了解基本概念以及簡單的操作指令之後,我們就可以將應用程式和執行環境打包,產生一個 image, 方便之後佈署到其他機器上。
建立並撰寫 Dockerfile
Dockerfile 是用來記錄打包的步驟,我們先在專案目錄底下建立 Dockerfile
,專案目錄架構如下:
1 | application/ |
選定 Base image
Docker 的 image 是一層一層疊加,所以我們需要先從 Docker Hub 上找到適合的 base image, 再慢慢加上我們需要的東西。
因為我們的專案是用 Node.js 寫的,所以這裡我們選擇 node 作為 base image,如果是 Python 或其他語言也可以找到對應的 image 作為 base image.
使用 FROM
設定 base image:
1 | FROM node:12.2.0 |
指定 node 版本為 12.2.0,如果要用最新版也可以寫成 node:latest
.
設定 Working directory
1 | WORKDIR /app |
Copy code
使用 copy 指令將程式碼複製到 WORKDIR
, 這裡我們假設 WORKDIR
是 /app/
:
1 | COPY app.js package.json /app/ |
如果想要複製所有檔案,只排除特定檔案,可以建立 .dockerignore
,裡面寫要排除檔案:
1 | # Ignore files |
然後在 Dockerfile
就可以直接寫:
1 | COPY . /app/ |
安裝所需套件
使用 RUN
執行安裝指令,清理 npm cache 是為了讓 build 出來的 image 小一點。
1 | RUN npm i && npm cache clean --force |
設定 Port
設定 container 開放的 port:
1 | EXPOSE 8080 |
設定環境變數
1 | ENV NAME HelloWord |
設定 Initial command
最後就是執行程式的指令,使用 CMD
來設定這個 image run 起來之後要執行的預設指令:
1 | CMD node app.js |
Build
完成 Dockerfile 之後就可以開始建立 image, 執行:
1 | $ docker build -t <image_name>[:tag] <path> |
建立完之後,執行 docker images
就可以看到多了剛才建立的 image 囉!
執行打包的應用程式
直接使用 docker run <image>
就可以啟動應用程式,並且預設會執行 CMD
設定的指令,這樣就成功了!
如果想要在背景執行,可以加上 -d
參數,讓 container 在背景執行,如果想要看 log, 可以執行 docker logs <container_id>
.
另外可以使用 -p
將外部 Host 的 port 轉到 container 的 port, 例如: 將伺服器的 8080 port 轉到 container 的 8080 port:
1 | docker run -d -p 8080:8080 <image> |
佈署到遠端 server
如果想要佈署到遠端 server, 有以下幾種方式:
- 將 image 傳到遠端 server
- 將 Dockerfile 和所有程式碼放在 git repo, 直接在遠端 pull repo 之後 build image
- 將自己的 image push 到 Docker Hub
第一點要將 image 傳到遠端 server 有點麻煩,第三點因為 Docker Hub 的 private repository 只能有一個,而 image 又包含自己的程式碼或是一些重要的 key, 不能把它設為 public repository, 所以建議用第二個方法,在遠端 server 重新 build image, 因為都是依照 Dockerfile 的步驟執行,所以不用擔心執行結果不同。