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 的步驟執行,所以不用擔心執行結果不同。

參考資料