1. 程式人生 > >PHP專案Docker化指南

PHP專案Docker化指南

作者介紹

王劍清

希雲資深工程師,長期在專案開發和測試部署中使用Docker,熟悉各種CI/CD流程和工具。

文章亮點

  1. 將PHP應用及其依賴的服務容器化步驟

  2. 如何將應用容器映象的構建自動化

  3. 應用容器如何快速部署到測試環境和生產環境中

快速上手

PHP官方在 hub.docker.com 上維護了官方的PHP Docker映象,包含了從PHP 5.5到7.0的多種不同版本的映象。


我們將以PHP官方的Docker映象為基礎,介紹如何將一個簡單的PHP應用Docker化。

  • 建立一個新目錄 php-quickstart,作為我們的專案目錄

  • 在專案目錄下建立檔案 app.php

<?php
  echo “Hello Docker!”
?>
  • 在專案目錄下建立檔案 Dockerfile

FROM php:5.6-cli

COPY . /project
WORKDIR /project
CMD ["php", "./app.php"]

上述 Dockerfile 中,通過 FROM 指令,我們將官方的 php-5.6-cli 作為我們的基礎映象。

通過 COPY 指令,我們把當前目錄下的檔案,複製到映象的 /project 目錄

CMD 指令設定了映象預設執行的命令,WORKDIR 則是設定了映象執行命令時的目錄

  • 構建映象

docker build -t php-app .

這將會生成一個名為 php-app 的映象

  • 執行容器

docker run php-app

這時候,容器將會執行我們之前建立的 app.php, 並輸出:

Hello Docker!

PHP + MySQL 的Docker化示例

接下來,我們通過一個 PHP + MySQL 的例子,介紹 PHP 應用 Docker 化之後,如何連線資料庫。

  • 建立一個新的目錄 php-mysql 作為我們的專案目錄

<?php
 $mysql = new mysqli('db', 'root', $_ENV['MYSQL_ROOT_PASSWORD']);
 echo 'Connected to mysql: '.$mysql->host_info;
?>

在 index.php 中,我們的 PHP 應用將會通過主機名稱 db 連線到 mysql 資料庫,同時使用使用者名稱 root, 以及環境變數中的 MYSQL_ROOT_PASSWORD對資料庫進行連線。這裡簡單地通過echo 連線資訊來確認 MySQL 連線是否正常。

  • 在專案目錄下建立 Dockerfile

FROM php:5.6-apache
RUN docker-php-ext-install mysqli
COPY . /var/www/html

這裡我們使用的是官方的 php:5.6-apache 映象,因為我們這一次希望可以直接從瀏覽器訪問這個 PHP 應用。

另外我們通過 RUN 指令執行 docker-php-ext-install mysqli 額外安裝了PHP的mysqli擴充套件

  • 構建映象

docker build -t php-mysql-app .
  • 建立 MySQL 容器

docker run --name db -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.6

我們在這裡使用官方的 mysql:5.6 映象建立了一個 MySQL 的容器

--name 引數將容器命名為 db

-e MYSQL_ROOT_PASSWORD=secret 通過環境變數,我們將 MySQL 的 root 使用者密碼設定為 secret

-d 引數將這個容器設定為後臺執行

  • 啟動 PHP 容器,並將其連線到 MySQL 容器

docker run --link db -e MYSQL_ROOT_PASSWORD=secret -p 8080:80 php-mysql-app

我們運行了之前構建的 php-mysql-app 映象,並將上一步建立的 mysql-instance 這個MySQL容器和它連線,同時我們把MySQL的root密碼通過環境變數MYSQL_ROOT_PASSWORD 傳到容器內部-p 8080:80 將容器的 80 埠對映到了主機的 8080 埠

Connected to mysql: db via TCP/IP

我們將從瀏覽器得到 index.php 的執行結果。

基於cSphere 私有Docker Registry的映象自動構建

在一個Docker化的專案中,專案的Docker映象成為了專案交付的最終元件。因此在專案的持續整合和持續交付環節中,映象的自動構建是必不可少的一個環節。

這裡介紹如何利用cSphere的私有映象倉庫配置映象自動構建,實現在程式碼Push到倉庫之後,自動構建Docker映象。

  • 建立私有Docker Registry

    在通過cSphere的映象倉庫頁面,點選新建映象倉庫按鈕,根據提示即可成功建立一個私有的映象倉庫.


  • 配置專案

    進入上一步建立的映象倉庫頁面,點選新增自動構建按鈕,填寫專案的 Git 倉庫地址和Dockerfile路徑:


然後根據提示,設定映象構建後,在映象倉庫的存放位置,和需要進行自動構建的分支:


  • 設定專案的Web Hook和 Deploy key


根據提示,為專案設定好Webhook和Deploy Key. 這樣當專案有新的程式碼push到上一步中設定的分支之後,私有Docker Registry就會進行映象的自動構建, 在構建成功之後,自動將映象Push到映象倉庫的指定位置


使用cSphere部署和管理PHP應用

在實現了自動構建專案的映象之後,接下來我們來看如何通過cSphere快速將會專案部署到各種環境中。

  • 建立應用模板

    進入cSphere的應用模板頁面,點選建立新模板按鈕,根據提示新建一個應用模板


  • 新增MySQL服務

    在之前的PHP + MySQL 專案Docker化示例中,我們通過以下的命令啟動了MySQL容器:

docker run --name db -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.6

這時我們把上述命令配置成應用模板中的一個服務:db


同時設定好環境變數


  • 新增PHP服務

    在 PHP + MySQL 專案Docker化示例中,我們通過以下的命令啟動了PHP容器:

docker run --link db -e MYSQL_ROOT_PASSWORD=secret -p 8080:80 php-mysql-app

同時,我們在自動構建映象中,設定了自動構建映象為 192.168.1.130/tsing/php-mysql-app:latest
 這裡我們把上述資訊配置成應用模板的另一服務:php


設定PHP程式碼中使用的環境變數值


--link db 這個引數無需在應用模板中設定,因為cSphere應用管理會自動根據服務的名稱,自動處理不同容器的連線關係。
 -p 埠對映也不需要設定,因為cSphere應用管理建立的容器都有獨立的IP,不再需要把容器的埠對映到主機上

  • 儲存模板


  • 部署應用

    點選上一步剛剛建立成功的模板版本,最右邊的部署按鈕,便可以開始進行部署。


在這個介面中,你可以選擇將應用部署到哪一個主機分組中, 可以根據需要,把應用部署到開發、測試、生產不同環境的主機上。當然,也可以在一個環境部署多個例項, 這些例項之間是互相隔離的。


  • 應用模板管理

    在應用模板頁面,你可以對應用模板進行修改,每次模板的修改都會產生一個新的版本,方便進行升級和回滾。


  • 應用管理

    在應用例項的頁面,你可以對應用例項進行管理, 對應用的服務進行擴容,重啟


    點選升級 · 回滾按鈕,可以快速將應用更新至指定版本的模板


應用部署自動化

當映象重新構建之後,可以在 cSphere 面板上點選服務的重新部署按鈕來升級服務, 也可以直接使用 cSphere 的 API 來實現自動化升級。

在呼叫cSphere的API前,請先在cSphere的設定頁面生成一個API Key:

呼叫以下 API,即可實現自動升級應用

curl -H 'cSphere-Api-Key: 6bbdc50dd0561b47ca8186f8ac29acde70bc65b3' \
-X PUT http://192.168.1.130/api/instances/php-mysql-example/redeploy

希雲cSphere平臺目前已經非常成熟,歡迎大家去官網申請試用。同時希望本文為大家使用Docker來改進專案開發、測試和交付流程有所幫助和借鑑意義。

Q&A

Q1 mysql的資料檔案應該是從實體機中掛載進容器的吧,那不同docker例項是共享一個mysql後端呢還是每個不同環境的docker例項有自己一套單獨的mysql後端?


A1 因為這個分享主要是開發和測試的實踐救命,所以MySQL 只是單容器的版本。如果是線上使用,MySQL 可以使用我們的編排系統來進行復雜的編排。


Q2  謝謝分享,感覺這個流程只適合大專案,中小專案用這個流程感覺複雜了很多。php是指令碼語言,可直接修改測試更新上線。請問php容器穩定了嗎?會不會在壓力大的情況下出現記憶體異常自動退出啊?有沒有監控自動啟動容器的方法呢?


A2 PHP容器很穩定,希雲內建了健康檢查功能,可以實現PHP異常的時候自動重啟容器,或者建立新的容器來保證整體服務的穩定。


Q3 php+mysql單臺能夠跑起來,那叢集部署能通過csphere實現麼?另外,docker容器之間的互連互通在csphere上是如何實現的呢?通過共用模板部署了不同的開發、測試環境例項,不同例項之間的版本控制是如何實現的?


A3 叢集部署可以通過cSphere實現,cSphere通過一些獨特的功能,比如配置檔案,內建模板變數使得可以實現很複雜的叢集編排。可以參考我們之前關於 redis 叢集和 mongo 叢集的分享。共用模板,部署不同環境的例項,可以通過提取變數,在不同環境部署時填寫對應的變數來實現例項個性化部署。也可以通過我們的模板tag 來使不同環境使用不同的模板。

聯絡希雲

電話  010-62249349

郵箱  [email protected]

官網  http://csphere.cn

熱文推薦: