Docker
使用單一進(jìn)程容器胸墙,即一個(gè)容器只運(yùn)行一種服務(wù),而不是把所有服務(wù)放在一個(gè)容器的設(shè)計(jì)捆憎,讓PHP項(xiàng)目需要的Nginx舅柜、PHP、MySQL組件躲惰,分別運(yùn)行在各自鏡像創(chuàng)建出來(lái)的獨(dú)立容器中致份。
文章提到的完整腳本請(qǐng)移步docker-lnmp,內(nèi)輔詳細(xì)的注釋(歡迎大家關(guān)注4〔Α)氮块。
整個(gè)流程:
- 客戶端http請(qǐng)求服務(wù)器80端口,該端口被映射到Nginx容器80端口诡宗,進(jìn)入Nginx處理滔蝉。
- Nginx分析請(qǐng)求,如果是靜態(tài)資源塔沃,直接服務(wù)器讀取內(nèi)容蝠引;如果是PHP腳本,通過(guò)PHP容器調(diào)用服務(wù)器獲取腳本,然后FastCGI處理螃概。
- FastCGI解析PHP腳本边坤,必要時(shí)訪問(wèn)MySQL容器讀寫數(shù)據(jù)。
具體步驟
Dockerfile:
- MySQL鏡像
繼承自官方的MySQL5.7
鏡像谅年,相對(duì)獨(dú)立解耦的模塊茧痒,無(wú)其它額外處理,見(jiàn)mysql/Dockerfile融蹂。 - PHP鏡像
繼承自官方的centos7
鏡像旺订,PHP源碼按需編譯安裝,方便后續(xù)擴(kuò)展管理或者配置超燃。通過(guò)sed
修改php.in
監(jiān)聽(tīng)所有9000
端口(此處為關(guān)鍵G!因?yàn)樘峁㎞ignx容器訪問(wèn)支持PHP腳本意乓,PHP容器對(duì)于Nginx容器不是localhost
)樱调,完整見(jiàn)php7/Dockerfile。 - Nginx鏡像
繼承自官方的centos7
鏡像届良,Nginx源碼按需編譯安裝笆凌,方便后續(xù)更改或者配置。通過(guò)sed
修改nginx.conf
增加對(duì)PHP腳本的支持士葫,完整見(jiàn)nginx/Dockerfile乞而。
構(gòu)建鏡像:
docker build --tag addcn/mysql -f mysql/Dockerfile .
docker build --tag addcn/php7 -f php7/Dockerfile .
docker build --tag addcn/nginx -f nginx/Dockerfile .
啟動(dòng)容器:
整個(gè)流程可以看到,Nginx慢显、PHP爪模、MySQL三者的關(guān)系:
Nginx容器---->
PHP容器,PHP容器---->
MySQL容器荚藻。即容器之間是有關(guān)聯(lián)的屋灌,兩兩容器的數(shù)據(jù)通信通過(guò)容器啟動(dòng)命令docker run
加參數(shù)--link
解決。
docker run --name mysql -p 3306:3306 -v /root/bo/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -it addcn/mysql
docker run --name php7 -p 9000:9000 -v /var/www/html:/usr/local/nginx/html --link mysql:mysql -it addcn/php7
docker run --name nginx -p 80:80 -v /var/www/html:/usr/local/nginx/html --link php7:php7 -it addcn/nginx
測(cè)試 PHP & MySQL:
vi /var/www/html/test.php
<?php
//date
echo date("Y-m-d H:i:s")."<br />\\n";
//mysql
try {
$conn = new PDO('mysql:host=mysql;port=3306;dbname=mysql;charset=utf8', 'root', '123456');
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
//$conn->exec('set names utf8');
$sql = "SELECT * FROM `user` WHERE 1";
$result = $conn->query($sql);
while($rows = $result->fetch(PDO::FETCH_ASSOC)) {
echo $rows['Host'] . ' ' . $rows['User']."<br />\\n";
}
//phpinfo
phpinfo();
?>
客戶端瀏覽:
http://192.168.8.36/test.php
![Docker運(yùn)行PHP及輸出MySQL表][1]
[1]: https://raw.githubusercontent.com/addcn/docker-lnmp/master/docs/docker-lnmp.png
Q&A
- Nginx如何支持PHP腳本应狱?
Nginx容器啟動(dòng)時(shí)候共郭,通過(guò)--link php7:php7
參數(shù)共享PHP容器的網(wǎng)絡(luò),配置nginx.conf
文件(見(jiàn)nginx/Dockerfile)侦香,當(dāng)處理PHP腳本時(shí)落塑,轉(zhuǎn)給PHP容器解析:
location ~ \\.php$ {
root html;
fastcgi_pass php7:9000; #此處為關(guān)鍵!罐韩!其中php7為PHP容器的名稱憾赁,見(jiàn)啟動(dòng)PHP容器docker run --name指定的值
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; #關(guān)鍵!散吵!/usr/local/nginx/html為web目錄
include fastcgi_params;
}
- PHP如何讀取MySQL數(shù)據(jù)龙考?
PHP容器啟動(dòng)時(shí)候蟆肆,通過(guò)--link mysql:mysql
參數(shù),與MySQL容器共享網(wǎng)絡(luò)晦款,類似兩者處于同一臺(tái)機(jī)器炎功,因此PHP代碼連接的時(shí)候使用$conn = new PDO('mysql:host=mysql;port=3306;dbname=mysql;charset=utf8', 'root', '123456');
就可以連接上MySQL(其中host=mysql
的mysql
為MySQL容器的名稱,見(jiàn)啟動(dòng)MySQL容器docker run --name
指定的值)缓溅。
下一步蛇损?
- 單一容器部署LNMP
- Docker Compose使用
- PHP/MySQL/Nginx日志及配置文件掛載出容器外面
- 容器集群的自動(dòng)化部署擴(kuò)容及運(yùn)維開(kāi)源平臺(tái)kubernetes了解