給 PHP 開發者的 Docker 文件(四)

leon0824

Leon

Posted on February 17, 2022

給 PHP 開發者的 Docker 文件(四)

(本文譯自〈Docker for PHP Developers〉)

來建個應用(Application)吧

說了一堆有的沒的(jibber-jibber),來搭個有 Nginx 網頁伺服器和與其通訊的 MySQL 資料庫的應用(application)吧!這不會是複雜到超出想像的應用,但是是個絕佳的機會來學習:

  • 如何組建 Docker 映像
  • 如何實例化(instantiate)Docker 容器(container)
  • 如何用 Docker 卷宗(volume)保存(persist)資料
  • 如何聚合(aggregate)容器輸出的紀錄檔(log)
  • 如何利用 Docker Compose 管理互相關聯的容器

首先,在你的電腦內建個專案目錄並切換到該目錄內,本文所有的指令都在這目錄之內下達。

遊戲計畫

在做之前,先讓我們規劃一下該怎麼玩,首先我們需要安裝 Docker,然後我們得決定(figure out)這個應用要怎麼拆解成不同的容器。這是個簡單的應用:有一個 Nginx 網頁伺服器、一個 PHP-FPM 應用伺服器、與一個 MySQL 資料庫伺服器,因此我們的這個應用需要三個 Docker 容器,分別從三個 Docker 映像實例化而來。我們也需要決定是否要自建 Docker 映像,還是從 Docker Hub 抓既有的來用就好。

我們也得決定用哪個基礎映像(base image)來作為共用的映像,在此所有的 Docker 映像都將擴展(extend)自該基礎映像。如果我們的 Docker 容器都擴展自同一個基礎映像,那麼可以節省磁碟空間並簡化 Docker 映像的相依(dependency)數量。在本教學中我們將以 Ubuntu 14.04 作為我們的基礎映像。

在建構或下載需要的 Docker 映像後,我們將會進行實例化並使用 Docker Compose 運行我們的應用的 Docker 容器。如果一切按照計畫,我們將會運行(up)起一個可依需求(on-demand)運用的 PHP 開發環境,而這僅僅只須 Bash 指令與幾秒的時間。

最後我們會討論如何聚合容器輸出的紀錄檔(log),記住,容器是免洗的(expendable),而且我們絕不可把資料存在容器內,相反地,我們將把紀錄檔重導(redirect)到各自容器內的標準輸出(standard output)與標準錯誤(standard error)檔案描述子(descriptor),如此一來 Docker Compose 即可收集並管理容器內的紀錄資料。

安裝 Docker

Docker 需要 Linux,並且它支援許多的 Linux 發行版:Ubuntu、Debian、CentOS、CRUX、Fedora、Gentoo、RedHat、與 SUSE,挑一個吧!(take your pick)。你的本地的 Linux 作業系統就是 Docker 母機(host),實例化以及運行 Docker 容器在其內。

許多人使用 Mac OS X或是 Windows,這不表示你完蛋了(out of luck),因為有個叫做 Boot2Docker 的東西,這工具可以建立一個微型的 Linux 虛擬機,並且這個虛擬機將會被做為 Docker 母機,而非你的本地的作業系統。別擔心,這個虛擬機真的超小而且開機只要約 5 秒。

裝好 Boot2Docker 後,可以雙擊 Boot2Docker 應用圖示,或者在終端機(terminal)執行這些 Bash 指令:

boot2docker init
boot2docker up
eval "$(boot2docker shellinit)"
Enter fullscreen mode Exit fullscreen mode

這三行指令會建立虛擬機(假使尚未有建立好了的虛擬機的話),啟動虛擬機,並輸出必要的環境變數(environment variables),如此你的本地作業系統就可以與 Docker 母機相互通訊。

如果你像我一樣不喜歡打字的話,你可以建立 Bash 替身(alias)。加入下面幾行到你的 ~/.bash_profile 檔案內:

alias dockup="boot2docker init && boot2docker up && eval \"\$(boot2docker shellinit)\""
boot2docker up
eval "$(boot2docker shellinit)"
Enter fullscreen mode Exit fullscreen mode

這會建立一個叫做 dockup(Docker up 的縮寫)的 Bash 替身,現在只要打簡單的 dockup 在新的終端機就可以建立、啟動、初始化你的 Docker 母虛擬機。

Nginx Docker 映像

首先我們來關注 Nginx 網頁伺服器,雖然可以確定在 Docker Hub 一定找得到自 Ubuntu 14.04 基礎映像擴展而來的而且合用的映像,但我們會利用這次機會來學習建構自己的 Docker 映像。建立目錄 images/nginx/,新增 Dockerfile 與 start.sh 到那個目錄內,此時你的專案目錄看起來應該是這樣:

images/
  nginx/
    Dockerfile
    start.sh
Enter fullscreen mode Exit fullscreen mode

用你常用的編輯器打開 Dockerfile 並加入這些內容:

FROM phusion/baseimage
MAINTAINER YOUR NAME <YOUR EMAIL>

CMD ["/sbin/my_init"]
RUN apt-get update && apt-get install -y python-software-properties
RUN add-apt-repository ppa:nginx/stable
RUN apt-get update && apt-get install -y nginx

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

RUN mkdir -p /etc/service/nginx
ADD start.sh /etc/service/nginx/run
RUN chmod +x /etc/service/nginx/run

EXPOSE 80

RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Enter fullscreen mode Exit fullscreen mode

利用定義在 Docker 文件內的指令寫入 Dockerfile 內以建構一個新的 Docker 映像。讓我們一行一行的看它們的作用分別是什麼。

  • Line 1FROM 開頭,用於標示父 Docker 映像的名稱,由該父映像擴展出我們的新映像。我們拿 phusion/baseimage 來擴展,因為它提供簡易的 Docker 容器操作工具。
  • Line 2MAINTAINER 開頭,用於標示你自己的名稱與電郵信箱。如果你把這個 Docker 映像分享到 Docker Hub,其他開發者就能夠知道是誰做出這個映像以及有問題要問誰。
  • Line 3 用於初始化 phusion/baseimage 基礎映像內建的家管(house-keeping)程序。
  • Line 4 - 6 用於從 Nginx 社群 PPA(personal package archive)安裝最新的穩定版的 Nginx。這個 PPA 提供最新的穩定的 Nginx,讓我們可以迅速地裝起來而不用從源碼編起。
  • ine 7 - 9 用於更新 Nginx 組態檔案,讓 Nginx 不要以常駐服務(daemonized)模式運作。這幾行也把 Nginx 的存取與錯誤紀錄連結(symlink)到容器的標準輸出與標準錯描述子,如此 Docker 就可以整合(aggregate)管理我們的應用的紀錄資料。我們從不保存(persist)任何資料在容器自身內。
  • Line 10 - 12 用於拷貝 start.sh 檔案進容器,phusion/baseimage 基礎映像會呼叫這個檔案來啟動 Nginx 伺服器程序。
  • Line 13 用於告訴 Docker 把所有實例化(instantiated)自這個映像的容器的 80 埠開放(expose)。我們需要開放 80 埠好讓連入(inbound)的HTTP要求(request)能被 Nginx 接收並做適當處理。
  • Line 15 用於執行 phusion/baseimage 基礎映像提供的家管程序。

接下來,開啟 start.sh 檔案並在最後加入這些內容:

#!/usr/bin/env bash
service nginx start
Enter fullscreen mode Exit fullscreen mode

這裡面的 Bash 指令用於啟動 Nginx 網頁伺服器程序。現在我們已經準備好建構我們的 Docker 映像了,移動到專案目錄 images/nginx/ 內並執行這個 Bash 指令:

docker build -t tutorial/nginx .
Enter fullscreen mode Exit fullscreen mode

docker build

根據先前的 Dockerfile 的內容,Docker 開始建構你的 Nginx Docker 映像,並且你會在終端機看到一些輸出內容。你也會看到 Docker 會從 Docker Hub 抓下來任何有相依性(dependency)的父映像(parent image)。完成後,你可以執行 docker images 指令,會輸出現有的 Docker 映像清單,你應該會看到 tutorial/nginx 在清單內。

docker images

恭喜啦!你搞定了你的第一個 Docker 映像。但請記得,這還只是個 Docker 映像,還得利用它去實例化出 Docker 容器,但在做實例化前,讓我們先把 PHP-FPM 和 MySQL 的 Docker 映像都搞定。

PHP-FPM Docker映像

接下來我們來看看 PHP-FPM,我們將不會自行建構這個 Docker 映像,相反地,我已經在 Docker Hub 分享了一個 nmcteam/php56 的映像,執行下面的 Bash 指令來把這個 PHP-FPM Docker 映像從 Docker Hub 抓回來。

docker pull nmcteam/php56
Enter fullscreen mode Exit fullscreen mode

MySQL Docker 映像

最後咱們來關注 MySQL,我在 Docker Hub 找到了擴展自 Ubuntu 14.04 基礎映像的 sameersbn/mysql,執行下面的 Bash 指令來把這個 MySQL Docker 映像從 Docker Hub 抓回來。

docker pull sameersbn/mysql
Enter fullscreen mode Exit fullscreen mode

(待續…)

💖 💪 🙅 🚩
leon0824
Leon

Posted on February 17, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related