0%

[Docker] 安裝及使用 Docker

Docker

簡介

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
2
3
4
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

Install Docker CE

Update:

1
$ sudo apt-get update

Install:

1
$ sudo apt-get install docker-ce

裝好之後,確認一下是否安裝成功:

1
docker version

正常運作的話,可以看到以下畫面:

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

search

下載 image:

1
$ docker pull ubuntu

pull

查看所有 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
2
3
4
5
6
application/
├── Dockerfile
├── README.md
├── app.js
├── node_modules/
└── package.json

選定 Base image

Docker 的 image 是一層一層疊加,所以我們需要先從 Docker Hub 上找到適合的 base image, 再慢慢加上我們需要的東西。

Docker

因為我們的專案是用 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
2
3
4
5
6
# Ignore files
node_modules
.git
.circleci
test
*.txt

然後在 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, 有以下幾種方式:

  1. 將 image 傳到遠端 server
  2. 將 Dockerfile 和所有程式碼放在 git repo, 直接在遠端 pull repo 之後 build image
  3. 將自己的 image push 到 Docker Hub

第一點要將 image 傳到遠端 server 有點麻煩,第三點因為 Docker Hub 的 private repository 只能有一個,而 image 又包含自己的程式碼或是一些重要的 key, 不能把它設為 public repository, 所以建議用第二個方法,在遠端 server 重新 build image, 因為都是依照 Dockerfile 的步驟執行,所以不用擔心執行結果不同。

參考資料