Docker 實戰系列(一):一步一步帶你 dockerize 你的應用

Docker 實戰系列(一):一步一步帶你 dockerize 你的應用

想像一個情況,當你在本機開發完準備要部屬到自己的 server 上時,你發現 server 的系統不是你熟悉的 Ubuntu 而是 CentOS,除此之外你還需要自己安裝 php7、設定 MySQL 的帳號密碼跟架設 Apache,光想到要設定這些環境頭都痛了,這時候你就需要 Docker 了

Docker 可以幫你把 Ubuntu + php7 + MySQL + Apache 的環境跟你的程式碼打包起來,整包丟到 CentOS的 server 上去跑,不用很勉強的在不熟悉的 CentOS 上配置環境,弄個不好說不定還會影響到其他正在跑的程式

img

Docker 是什麼

Docker 是個輕量級的虛擬化技術,底層使用 cgroup、chroot、namespace 實作,可以把你的應用程式連同環境一起打包,部屬的時候就不用再擔心環境的問題

下圖的例子就是使用 Docker 將三個已經打包起來的程式跑在不同的 container(容器)中,每個 container 都是一個獨立的環境,可以跑不同的系統跟安裝不同的資料庫、編譯器等等,意思就是說你可以 A 專案用 php5.3,另外一個用 php7,完全不會衝突

img

Dockerize

所謂的 dockerize 就是把你的應用程式 Docker 化,把你的程式跟環境包成一個 image,部屬的時候就直接使用這個 image 不需要額外安裝其他東西

事前準備

你可以使用自己最近在做的 side project,也許是一個用 Django 寫的 api server,或是用 Node.js 寫的爬蟲等等,手邊沒有 side project 的話我有寫一個簡單的 simple-express-server,他會啟動一個 server 監聽 8080 port,到 127.0.0.1:8080 就可以看到 Hello World!

安裝 Docker

目前 Docker 有支援 Linux、Mac 跟 Windows,到 Docker Store 找到適合自己的版本,安裝完之後跑 docker version,有跑出版本就代表安裝成功了~

img

從 Docker Hub 上 pull image

Docker Hub 上有很多官方的 image 可以直接拿來用,所謂的 image 就是一個已經打包好的環境,譬如說 Debian 或是 Ubuntu + Node.js 等等,需要這個環境時就可以直接把這個 image pull 下來用。

使用 docker pull ubuntu 拿到最新的 ubuntu image,pull 的過程中會看到進度條

img

完成後跑 docker image ls 可以看到有一個 ubuntu 的 image

REPOSITORY    TAG        IMAGE ID         CREATED         SIZE
ubuntu        latest     20c44cd7596f     2 weeks ago     123MB

接著 docker run -it ubuntu bash把 ubuntu 的 image 跑起來變成 container,-it 是為了讓我們進到這個 container 的 shell 下指令,進到 container 後跑跑看 cat /etc/*release,我這邊的版本是 *16.04.3 LTS*

到目前為止,我們已經可以在任何系統上用 Docker 跑 ubuntu 的環境了

img

很多人看到這裡可能會有點搞混 image 跟 container,說明一下,image 指的是已經打包好的環境,但是還沒有跑起來,就是一堆檔案而已,而 container 則是把 image 跑起來之後產生的 instance,他們之間的關係就像程式碼跟跑起來的程式,程式碼不跑就只是一堆檔案,但跑起來之後他就會變成一個真的在跑 process

開始 dockerize 你的應用程式

我們的終極目標是要把你的程式碼跟想要的環境打包起來,變成一個 image,之後不管到哪一台機器上,只要有裝 Docker 而且有這個 image 就可以把你的程式跑起來

雖然程式有千百種,dockerize 的過程也不盡相同,但大致上可以分成這 6 個步驟,接下來會以上面提供的 simple-express-server 作為範例,大家可以視情況調整成適合自己應用的樣子

step 0 : 新增 Dockerfile

為了把環境跟程式碼包成一個 image,我們需要一個 Dockerfile 把打包的步驟寫在裡面,先在專案目錄下新增一個空檔案叫做 Dockerfile

simple-express-server
├── Dockerfile   <--   這裡
├── README.md
├── index.js
├── node_modules
└── package.json

step 1 : 找到適合的 base image

Docker 的 image 是一層一層疊加上去的,所以我們需要先在 Docker Hub 上選擇一個 base image,然後再慢慢把它加工成我們要的樣子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xgSQ3Qi-1645194673979)(https://miro.medium.com/max/786/1*bKRHfz7unRA35WHd9SBOCA.png)]

因為我這個專案是用 Node.js 寫的,所以我需要一個已經裝好 Node.js 的環境,有兩個選擇:

  1. 直接用 node 作為我的 base image,裡面就已經有 Node.js 環境了
  2. ubuntu 當 base image,再參考 Installing 把 node 裝在 ubuntu 上

因為第一種作法比較簡單,這邊就直接使用 node,如果你是 python, golang 等等其他語言也都可以找到相對應的 image,決定 base image 後就在 Dockerfile 的第一行寫 FROM node:9.2.09.2.0 指的是我們使用的 node image 版本,如果想要最新版的的話也可以指定 node:latest

step 2 : copy 原始碼

有了 Node.js 環境之後要把 code 也包進去,這邊使用 COPY 指令,把 index.jspackage.json 複製到 /app 資料夾裡面

img

step 3 : 安裝 dependencies

現在環境都配置好了,code 也已經在裡面了,我們要做的事情就是切換到 /app 這個目錄安裝 dependencies

使用 WORKDIR 切換到 /app 目錄,再用 RUNnpm install && npm cache clean --force,清 npm cache 是為了讓 build 出來的 image 不要包含這些 cache,這樣 image 會小一點

如果是其他語言就把 npm install … 換成其他指令就可以了,像 python 可能就是 pip install …,有 cache 的話記得要清一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u1WxhoNA-1645194673981)(https://miro.medium.com/max/1400/1*99L5tL38VLdYXrgpnnkxDQ.png)]

step 4 : 設定 initial command

現在環境、程式碼、dependencies 都準備好了,只剩把程式跑起來,這裡會用到 CMD 設定這個 image 被跑起來時的預設指令,對我這個程式來說要跑起來就是 node index.js,這樣就完成了 Dockerfile

img

step 5 : build

完成後就可以開始 build image,在專案目錄下跑 docker build -t simple-express-server . 就會根據 Dockerfile build 出你的 image

img

build 完跑 docker image ls 可以看到多出一個 simple-express-server,這就是剛剛 build 出來的 image,裡面包含 node 的環境、程式碼還有 dependencies 跟預設啟動指令

REPOSITORY             TAG      IMAGE ID       CREATED        SIZE
simple-express-server  latest   dd05512eea91   2 minutes ago  677MB
ubuntu                 latest   20c44cd7596f   2 weeks ago    123MB

把 image 跑起來

有了 image 後可以 docker run -p 3000:8080 simple-express-server 把 image 跑起來,在 container 內跑的就是剛剛設定的預設指令 node index.js-p 3000:8080 則是把 container 內的 8080 port 跟外部的 3000 port 接通,如此一來只要用瀏覽器到 127.0.0.1:3000 就可以看到 Hello World!,這樣就完成 dockerize 了,現在你的電腦即便什麼都沒有只裝 docker 也可以把這個程式跑起來

跑在背景

如果照上面跑 docker run -p 3000:8080 <image> 的話會把終端機卡住,所以部屬的時候都會跑在背景,要跑在背景只要加一個 -d 就可以了,變成 docker run -d <image>,下指令後會得到一個 container ID,要看 log 的話可以跑 docker logs <container ID>

server 上沒有這個 image 怎麼辦

因為現在是在本機 build,遠端的 server 還沒有這個 image,如果要部屬必須先把 image 傳到遠端的機器,但這樣很麻煩,比較好的方式是把 Dockerfile 跟所有原始碼放在 git repo 裡面,直接在 server 上 build image,因為都是照 Dockerfile 裡面的內容跑,所以不管是在自己電腦還是 server 上 build 結果都是一樣的

總結

這篇從最基礎的概念講到 dockerize 一個簡單的應用,Docker 指令講的不多,想看更多可以參考 base command,關於 Dockerfile 中的指令也可以看看 Dockerfile reference

ngine/reference/commandline/docker/),關於 Dockerfile 中的指令也可以看看 Dockerfile reference

這是 Docker 系列文的第一篇,之後會慢慢寫到 docker-compose、docker swarm 跟 kubernetes,想學 Docker 的人可以 follow 我,就可以在文章發佈的第一時間收到通知,謝謝大家~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值