Docker之MNMP配置PHP Web開發(fā)環(huán)境

Docker 安裝珊肃,參考Docker之開始

相關(guān)文件

?  www tree -L 2
.
├── default.conf
├── html
│   ├── connect_mysql.php
│   └── index.php
├── mysql
├── php.ini
└── www.conf

這里的目錄與文件,會(huì)在下文中都有介紹,先不用手動(dòng)創(chuàng)建

mysql

Docker Hub 中拉取鏡像

docker pull mysql:5.7 

最新版本的mysql 8.0 會(huì)有一些新特性毁欣,與最新的php-fpm 配合需要一些特殊處理,這里采用 mysql:5.7 先做上手岳掐。

實(shí)例容器凭疮,啟動(dòng)數(shù)據(jù)庫

docker run -p 3306:3306 --name mysql -v ~/www/mysql/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d --privileged=true mysql

說明:

  • -p 3306:3306:將容器的3306端口映射到主機(jī)的3306端口
  • -v ~/www/mysql/:/var/lib/mysql:將主機(jī)當(dāng)前用戶目錄下的mysql文件夾掛載到容器的/var/lib/mysql 下,在mysql容器中產(chǎn)生的數(shù)據(jù)就會(huì)保存在本機(jī)mysql目錄下
  • -e MYSQL_ROOT_PASSWORD=123456:初始化root用戶的密碼
  • -d 后臺(tái)運(yùn)行容器
  • --name 給容器指定別名
  • --privileged=true 可能會(huì)碰到權(quán)限問題串述,需要加參數(shù)执解;否則的話 訪問 mysql 會(huì)提示無訪問權(quán)限

php-fpm

拉取鏡像

docker pull php:7.2-fpm

實(shí)例容器,啟動(dòng)PHP

docker run --name php-fpm -p 9000:9000 -d php:7.2-fpm

復(fù)制配置文件至本地

docker cp php-fpm:/usr/local/etc/php-fpm.d/www.conf www.conf
docker cp php-fpm:/usr/src/php/php.ini-production php.ini

這里要特別注意一下,php-fpm:/usr/src/php/php.ini-production,在實(shí)例出的容器中,不一定是路徑src/php,拉取的php:fpm版本鏡像不同,php.ini路徑不同纲酗。

可以這樣查看php.ini路徑

# 先進(jìn)入容器
$ docker exec -it php-fpm bash
$ cd /usr/src/ && ls
# 有以下兩個(gè)文件
php.tar.xz   php.tar.xz.asc
# 這里我們需要解壓php.tar.xz文件,因?yàn)閜hp.ini-production就在其中
//先解壓xz
 xz -d php.tar.xz  
//再解壓tar
# tar -xvf  php.tar

解壓完畢后, php.ini-production便出現(xiàn)了衰腌,我當(dāng)時(shí)的路徑是/usr/src/php-7.1.9/php.ini-production逝淹。

即,前文中的
$ docker cp php-fpm:/usr/src/php/php.ini-production php.ini
改為
$ docker cp php-fpm:/usr/src/php-7.1.9/php.ini-production php.ini

==在本地服務(wù)器修改 php.ini 的內(nèi)容,設(shè)置 cgi.fix_pathinfo=1(要先刪除前面的;注釋符)桶唐。==

前面關(guān)于php-fpm的一系列操作主要是為了獲得配置文件,并沒有掛載本地目錄到容器中,所以接下來需要?jiǎng)h除容器,重新實(shí)例一個(gè)容器出來

$ docker stop php-fpm
$ docker rm php-fpm
$ docker run --name php-fpm -p 9000:9000 --link mysql:mysql -v ~/www/html:/var/www/html -v ~/www/www.conf:/usr/local/etc/php-fpm.d/www.conf -v ~/www/php.ini:/usr/local/etc/php/php.ini -d php:7.2-fpm

上述操作栅葡,從博客中直接復(fù)制過來,實(shí)操過程基本一致尤泽。php.ini的獲取欣簇,我使用的是php-7.2.12所以路徑也有細(xì)微不同。按照上述操作獲取即可坯约。

Nginx

拉取鏡像

docker pull nginx

實(shí)例容器

docker run --name nginx -p 80:80 -d nginx

通過瀏覽器:localhost 就會(huì)看到Nginx默認(rèn)的歡迎界面:Welcome to Nginx

映射HTML路徑

默認(rèn)情況下熊咽,Docker nginx服務(wù)器的HTML路徑(網(wǎng)站根目錄)在容器/usr/share/nginx/html目錄下,現(xiàn)在需要把這個(gè)目錄映射到本地服務(wù)器的~/www/html目錄闹丐。在上面命令的基礎(chǔ)上加上-v參數(shù)横殴,具體如下:

## 先刪除之前的容器
$ docker rm nginx    
$ docker run --name nginx -p 80:80 -d -v ~/www/html:/usr/share/nginx/html nginx

-v的參數(shù)格式為:<local-volumes>:<container-volumes>

在~/www/html下創(chuàng)建一個(gè)index.html文件卿拴,內(nèi)容隨意

比如 hello world

在瀏覽器上訪問 http://localhost衫仑,刷新一下就可以看到新的內(nèi)容了。

配置Nginx

Nginx的強(qiáng)大很大部分體現(xiàn)在配置文件上堕花,對(duì)于一些高級(jí)的應(yīng)用來說文狱,自定義Nginx非常重要。所以缘挽,我們需要把Nginx的配置文件復(fù)制到本地服務(wù)器目錄:

$ cd ~/www
$ docker cp nginx:/etc/nginx/conf.d/default.conf default.conf

再加一個(gè)-v參數(shù)瞄崇,把本地的配置文件映射到容器上,在重啟容器:

$ docker stop nginx
$ docker rm nginx
$ docker run --name nginx -p 80:80 -v ~/www/html:/usr/share/nginx/html -v ~/www/default.conf:/etc/nginx/conf.d/default.conf -d nginx

如果配置文件有修改壕曼,需要重啟容器生效:

$ docker restart nginx

這樣就可以直接在本地修改配置文件了苏研。

修改Nginx配置

就是前面我們從容器中復(fù)制出來的 default.conf

server {
    listen       80;
    server_name  _;
    root   /usr/share/nginx/html;
    index  index.html index.htm;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        #root   /usr/share/nginx/html;
        #index  index.html index.htm;
        try_files $uri $uri/ =404;
    }

    error_page  404              /404.html;
    location = /40x.html {
        root    /user/share/nginx/html;
    }    

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           /var/www/html/;
        fastcgi_pass   php-fpm:9000;
        fastcgi_index  index.php;
        include        fastcgi_params;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;        
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny  all;
    }
}

關(guān)于配置文件,有個(gè)需要注意的地方

location ~ \.php$ {
        root           /var/www/html/;
        fastcgi_pass   php-fpm:9000;
        fastcgi_index  index.php;
#        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
    
include        fastcgi_params;  
要放在
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
的前面

fastcgi_pass:其中配置的 php-fpm:9000,就是之前實(shí)例PHP的容器名

刪除剛才的nginx容器,重新生成一個(gè)

$ docker stop nginx
$ docker rm nginx
$ docker run --name nginx -p 80:80 --link php-fpm -v ~/www/html:/usr/share/nginx/html -v ~/www/default.conf:/etc/nginx/conf.d/default.conf -d nginx

測試 PHP與Nginx的連接

~/www/html 下創(chuàng)建 index.php

<?php
    phpinfo();

瀏覽器訪問 localhost

會(huì)以長表格形式展現(xiàn)當(dāng)前 PHP的版本信息腮郊。

測試PHP與MySQL的連接

PHP中與MySQL建立連接 還需要我們安裝 PHP的擴(kuò)展:mysqli

# 進(jìn)入 php-fpm 容器中
docker exec -it php-fpm bash
# 執(zhí)行php mysqli 的擴(kuò)展安裝
docker-php-ext-install mysqli
# 退出容器
exit

重啟容器

docker restart php-fpm

~/www/html 中創(chuàng)建 connect_mysql.php

<?php
// mysqli_connect參數(shù):ip:port摹蘑、賬號(hào)、密碼伴榔、數(shù)據(jù)庫
$link = mysqli_connect("10.10.10.1:3306", "root", "123456");

if (!$link) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL . "</br>";
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL. "</br>";
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL. "</br>";
    echo "string";
    // exit;
}

echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL. "</br>";
echo "Host information: " . mysqli_get_host_info($link) . PHP_EOL;

mysqli_close($link);
?>

在瀏覽器中輸入:http://localhost/connect_mysql.php纹蝴,展示如下:

Success: A proper connection to MySQL was made! The my_db database is great. 
Host information: 10.10.10.1:3306 via TCP/IP

則說明php與MySQL連接已建立

配置Dockerfile

上述中,在容器 php-fpm 中手動(dòng)安裝的擴(kuò)展踪少,在容器被刪除后塘安,就會(huì)被刪除了,所以再次實(shí)例 php-fpm 時(shí)援奢,還要再次手動(dòng)安裝擴(kuò)展兼犯。是不是很麻煩,很不自動(dòng)化?

so Dockerfile 就出場了切黔,通過Dockerfile來定制鏡像砸脊,只需要安裝一次擴(kuò)展以后實(shí)例化容器,就自動(dòng)擁有這些擴(kuò)展了纬霞。

先看目錄層級(jí)

www
├── default.conf 
├── Dockerfile
├── html
│   ├── index.php
│   └── connect_mysql.php
├── mysql
├── php.ini
└── www.conf

Dockerfile文件如下:

FROM php:7.2-fpm
ADD www.conf   /usr/local/etc/php-fpm.d/www.conf
ADD php.ini    /usr/src/php/php.ini
RUN docker-php-ext-install mysqli pdo_mysql \
    && docker-php-ext-enable mysqli
EXPOSE 9000

依舊先刪除之前的php-fpm容器:

$ docker stop php-fpm
$ docker rm php-fpm
# 構(gòu)建 運(yùn)行
# 進(jìn)入項(xiàng)目的目錄,比如我的www文件夾就是建在/home/username下的
$ cd ~/www
$ docker build -t php-fpm:v1 ./
$ docker run --name php-fpm -p 9000:9000 --link mysql:mysql -v ~/www/html:/var/www/html -v ~/www/www.conf:/usr/local/etc/php-fpm.d/www.conf -v ~/www/php.ini:/usr/local/etc/php/php.ini -d php:7.2-fpm
即可

當(dāng)然具體需要哪些擴(kuò)展還是根據(jù)自己的需求來編寫Dockerfile凌埂。

docker-compose

上述中,每次都要輸入那么多的shell命令诗芜,每個(gè)容器都要一個(gè)個(gè)的啟動(dòng)瞳抓,還要加那么多的參數(shù),是不是感覺很煩?

so docker-compose 就出場了

先看目錄層級(jí)

.
├── app
│   ├── connect_mysql.php
│   └── index.php
├── docker-compose.yml
└── services
    ├── mysql
    │   └── data
    ├── nginx
    │   ├── config
    │   │   └── default.conf
    │   └── logs
    └── php
        ├── Dockerfile
        └── config
            ├── php.ini
            └── www.conf

docker-compose.yml 文件如下:

version: '3'
services:
    nginx:
        image: nginx:latest
        # 端口映射
        ports:
            - "80:80"
        # 依賴關(guān)系 先跑php
        depends_on:
            - "php"
        # 數(shù)據(jù)卷
        volumes:
            # 映射主機(jī)config目錄到容器/etc/nginx/conf.d目錄
            - "$PWD/services/nginx/config:/etc/nginx/conf.d"
            - "$PWD/app:/usr/share/nginx/html"
        networks:
            - app_net
        # 容器名稱
        container_name: "compose-nginx"
    php:
        build: ./services/php
        # image指定build Dockerfile生成鏡像的名稱
        image: php:7.2-fpm-pdo
        ports:
            - "9000:9000"
        volumes:
            - "$PWD/app:/var/www/html"
        networks:
            - app_net
        container_name: "compose-php"
    mysql:
        image: mysql:5.7
        ports:
            - "3306:3306"
        volumes:
            - "$PWD/services/mysql/data:/var/lib/mysql"            
        # 環(huán)境變量
        environment:
            MYSQL_ROOT_PASSWORD: "123456"
        # 允許運(yùn)行特權(quán)命令    
        privileged: true
        networks:
            app_net:
                # 固定子網(wǎng)ip伏恐,網(wǎng)段必須在子網(wǎng)絡(luò)10.10.*.*
                ipv4_address: 10.10.10.1
        container_name: "compose-mysql"
networks:
    # 配置docker network
    app_net:
        driver: bridge
        ipam:
            config:
                # 子網(wǎng)絡(luò)
                - subnet: 10.10.0.0/16

按照如上目錄層級(jí)孩哑,做好文件配置,其中相關(guān)文件配置內(nèi)容翠桦,同名參考前面步驟就OK横蜒,直接復(fù)制過來就行。

實(shí)際上到了這一步销凑,基本就完成了一個(gè)docker-compose 項(xiàng)目丛晌。

啟動(dòng)項(xiàng)目

docker-compose up -d

實(shí)際上,在這里啟動(dòng)的時(shí)候闻鉴,如果本地鏡像不存在茵乱,就會(huì)去Docker Hub 中去拉取孟岛;如果是定制鏡像且在本地未曾構(gòu)建過,就會(huì)自動(dòng)去構(gòu)建新的鏡像督勺;如果是定制鏡像渠羞,但本地已經(jīng)存在構(gòu)建過的同名鏡像,就會(huì)跳過構(gòu)建這一步智哀,直接啟動(dòng)同名鏡像去實(shí)例化容器次询。

停止項(xiàng)目服務(wù)并刪除所有容器

docekr-compose down

測試Sequel Pro 連接 MySQL

host:127.0.0.1
username:root
password:123456
port:3306

登錄即可

關(guān)于端口

port:MySQL容器的導(dǎo)出端口,即啟動(dòng)時(shí)配置的宿主機(jī)端口與容器端口的映射瓷叫,默認(rèn)是3306

  • 例如:

    ports:
        - 3306:3306
    

    則Sequel Pro 中通過 127.0.0.1:3306連接屯吊。

    ports:
        - 3316:3306
    

    則Sequel Pro 中通過 127.0.0.1:3316連接,而docker-compose容器互聯(lián)則要通過 3306端口來訪問MySQL Server

關(guān)于一些坑

  • php最新版(實(shí)操時(shí):7.2.12-fpm),與最新版 MySQL (8.0)摹菠,由于默認(rèn)的加密機(jī)制不同盒卸,導(dǎo)致無法連接成功,不利于新手上手實(shí)操次氨。故本文中直接采用 mysql:5.7
  • 啟動(dòng) mysql 需要 添加 privileged=true 參數(shù)蔽介,否則連接數(shù)據(jù)庫時(shí),無訪問權(quán)限

參考文獻(xiàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市虹蓄,隨后出現(xiàn)的幾起案子犀呼,更是在濱河造成了極大的恐慌,老刑警劉巖薇组,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件外臂,死亡現(xiàn)場離奇詭異,居然都是意外死亡律胀,警方通過查閱死者的電腦和手機(jī)专钉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來累铅,“玉大人跃须,你說我怎么就攤上這事⊥奘蓿” “怎么了菇民?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長投储。 經(jīng)常有香客問我第练,道長,這世上最難降的妖魔是什么玛荞? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任娇掏,我火速辦了婚禮,結(jié)果婚禮上勋眯,老公的妹妹穿的比我還像新娘婴梧。我一直安慰自己,他們只是感情好客蹋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布塞蹭。 她就那樣靜靜地躺著,像睡著了一般讶坯。 火紅的嫁衣襯著肌膚如雪番电。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天辆琅,我揣著相機(jī)與錄音漱办,去河邊找鬼。 笑死婉烟,一個(gè)胖子當(dāng)著我的面吹牛娩井,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播隅很,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼撞牢,長吁一口氣:“原來是場噩夢啊……” “哼率碾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屋彪,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤所宰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后畜挥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔粥,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年蟹但,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了躯泰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡华糖,死狀恐怖麦向,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情客叉,我是刑警寧澤诵竭,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站兼搏,受9級(jí)特大地震影響卵慰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佛呻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一裳朋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吓著,春花似錦鲤嫡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至紊撕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赡突,已是汗流浹背对扶。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惭缰,地道東北人浪南。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像漱受,于是被迫代替她去往敵國和親络凿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 365天摔踱,天天營養(yǎng)早餐!不是做給誰看怨愤,這是我的需要派敷,我的身體需要,我的細(xì)胞需要撰洗! 健康先做第一步篮愉,糾正早餐!早餐務(wù)...
    榮榮1413閱讀 457評(píng)論 0 4
  • 夜晚十點(diǎn)差导,即將上床睡覺的她试躏,忽然聽到塑料用具與地板相撞擊發(fā)出的“啪”一聲,聲音清脆響亮设褐,猶如敲打著她的神經(jīng)颠蕴。空氣似...
    靈魂的天空閱讀 720評(píng)論 4 4
  • 夜樹蒼天朦络断,日落踐賓朋裁替。 泊車故里路,他期待相逢貌笨。
    玲瓏緒閱讀 243評(píng)論 0 13
  • L美琴閱讀 172評(píng)論 0 0
  • 網(wǎng)易游戲《第五人格》是我玩的第一款“手游”弱判,在此之前我玩過的也就是植物大戰(zhàn)僵尸、黃金礦工這種不需要“操作”锥惋,只要使...
    云西去閱讀 1,725評(píng)論 8 3