Docker LNMP環(huán)境搭建
Docker LNMP環(huán)境搭建最終完成的環(huán)境我們稱為:DNMP(即 Docker + Nginx + MySQL + PHP)。 最終實(shí)現(xiàn)一鍵部署LNMP環(huán)境的目的,該環(huán)境特點(diǎn):完全開源 支持多版本PHP切換(PHP5.4、PHP5.6、PHP7.2...) 支持綁定任意多個(gè)域名
Docker LNMP環(huán)境搭建最終完成的環(huán)境我們稱為:DNMP(即 Docker + Nginx + MySQL + PHP)。 最終實(shí)現(xiàn)一鍵部署LNMP環(huán)境的目的,該環(huán)境特點(diǎn):完全開源 支持多版本PHP切換(PHP5.4、PHP5.6、PHP7.2...) 支持綁定任意多個(gè)域名
最終完成的環(huán)境我們稱為:DNMP(即 Docker + Nginx + MySQL + PHP)。
最終實(shí)現(xiàn)一鍵部署LNMP環(huán)境的目的,該環(huán)境特點(diǎn):
github倉庫地址:https://github.com/yeszao/dnmp
QQ群:?572041090
(請備注dnmp交流)
1、安裝git
、docker
和docker-compose
。
2、使用git
下載完整代碼:
$ git clone?https://github.com/yeszao/dnmp.git
3、用docker-compose
命令啟動(dòng)容器,首次使用需要下載鏡像,會稍慢:
$ docker-compose up
4、然后在瀏覽器中訪問localhost
,就可以看到如下頁面:
5、源代碼在:./www/site1/
目錄下。
具體安裝步驟:
注意:Docker安裝要求Linux 3.10
以上版本,用uname -a
命令可查看到。
安裝之后,可查看版本:
$ docker -v $ docker-compose -v
然后把當(dāng)前用戶加到docker
用戶組里面:
$ sudo gpasswd -a ${USER} docker
就不用每次啟動(dòng)Docker都得加sudo
了。
注意,執(zhí)行gpasswd
命令之后要重新登陸才有效。
在沒有梯子的情況下,Docker默認(rèn)從Docker Hub倉庫下載鏡像,完整的LNMP鏡像估計(jì)需要一兩天時(shí)間。
所以只能換個(gè)途徑,比如使用阿里云的加速倉庫。
首先注冊一個(gè)阿里云賬號,然后訪問阿里云的Docker鏡像倉庫,能找到加速器地址。
對于Docker 1.10+,打開配置文件 /etc/docker/daemon.json
(沒有時(shí)新建該文件):
{ "registry-mirrors": ["https://6evg8u3r.mirror.aliyuncs.com"] }
以上是我的加速地址。
然后重啟Docker Daemon:
sudo systemctl daemon-reload sudo systemctl restart docker
就可以了。
Docker 1.10以下請看:https://yq.aliyun.com/articles/29941。
大致框架如下:
(圖片使用UMLet繪制,下載原文件)
目錄結(jié)構(gòu)如下:
. ├── docker-compose.yml 容器啟動(dòng)配置文件 ├── Dockerfile PHP-FPM構(gòu)建配置文件 ├── conf 配置目錄 │?? ├── mysql MySQL配置文件目錄 │?? │?? └── my.cnf MySQL配置文件 │?? ├── nginx Nginx配置文件目錄 │?? │?? ├── conf.d 站點(diǎn)配置文件目錄 │?? │?? │?? ├── certs SSL認(rèn)證文件、密鑰和加密文件目錄 │?? │?? │?? │?? └── site2 站點(diǎn)2的認(rèn)證文件目錄 │?? │?? │?? ├── site1.conf 站點(diǎn)1 Nginx配置文件 │?? │?? │?? └── site2.conf 站點(diǎn)2 Nginx配置文件 │?? │?? └── nginx.conf Nginx通用配置文件 │?? └── php PHP配置目錄 │?? ├── php-fpm.d PHP-FPM配置目錄 │?? │?? └── www.conf PHP-FPM配置文件 │?? └── php.ini PHP配置文件 ├── log 日志目錄 │?? ├── mysql MySQL日志目錄 │?? ├── nginx Nginx日志目錄 │?? └── php-fpm PHP-FPM日志目錄 ├── mysql MySQL數(shù)據(jù)文件目錄 └── www 站點(diǎn)根目錄 ├── site1 站點(diǎn)1根目錄 └── site2 站點(diǎn)2根目錄
本文有默認(rèn)加了兩個(gè)站點(diǎn):www.site1.com
(同localhost
)和www.site2.com
。
要在本地訪問這兩個(gè)域名,需要修改你的hosts文件,添加以下兩行:
127.0.0.1 www.site1.com 127.0.0.1 www.site2.com
其中,www.site2.com
為支持SSL/https和HTTP/2的示例站點(diǎn)。
因?yàn)檎军c(diǎn)2的SSL采用自簽名方式,所以瀏覽器有安全提示,繼續(xù)訪問就可以了,自己的站點(diǎn)用第三方SSL認(rèn)證證書替換即可。
如果只用到站點(diǎn)1,把站點(diǎn)2相關(guān)的目錄和配置文件刪除:
./conf/nginx/conf.d/certs/site2/ ./conf/nginx/conf.d/site2.conf ./www/site2/
重啟容器內(nèi)的Nginx生效:
docker exec -it dlnmp_nginx_1 nginx -s reload
在容器中我們也是可以用HTTPS的,具體的配置請參考如下文件:
./conf/nginx/conf.d/site2.conf
如果是自簽名,可以用廖雪峰提供的一個(gè)自動(dòng)生成認(rèn)證文件、私鑰腳本:gencert.sh
,
這個(gè)腳本已經(jīng)放在項(xiàng)目中,在這個(gè)目錄下:
./conf/nginx/conf.d/certs/site2/
在Bash中輸入:
$ ./gencert.sh
輸入一次域名,和幾次密碼(內(nèi)容隨意)后,就會生成幾個(gè)認(rèn)證文件。
其中自簽名情況不需要.csr
和.origin.key
后綴的文件。
然后修改Nginx配置文件,配置SSL支持就可以了。
如下是docker容器的運(yùn)行配置docker-compose.yml的內(nèi)容:
nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./www/:/var/www/html/:rw - ./conf/nginx/conf.d:/etc/nginx/conf.d/:ro - ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./log/nginx/:/var/log/nginx/:rw links: - php-fpm:fpm php-fpm: build: . expose: - "9000" volumes: - ./www/:/var/www/html/:rw - ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro - ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw - ./log/php-fpm/:/var/log/php-fpm/:rw links: - mysql:mysql - redis:redis mysql: image: mysql:latest ports: - "3306:3306" volumes: - ./conf/mysql/my.cnf:/etc/mysql/my.cnf:ro - ./mysql/:/var/lib/mysql/:rw - ./log/mysql/:/var/log/mysql/:rw environment: MYSQL_ROOT_PASSWORD: "123456" redis: image: redis:latest ports: - "6379:6379"
這里我們用了nginx的alpine鏡像,以及php-fpm和MySQL的最新鏡像。
這里默認(rèn)加了redis容器,不需要的話可以把文件的最后4
行以及php-fpm塊下的- redis:redis
刪除。
因?yàn)橄啾?code>nginx:latest,nginx:alpine
有幾點(diǎn)優(yōu)勢:
nginx:latest
一模一樣nginx:alpine
默認(rèn)支持http2。Alpine的更多請看《Alpine Linux,一個(gè)只有5M的Docker鏡像》。
如要進(jìn)入alpine容器,命令是(后面的路徑不是/bin/bash
):
$ docker exec -it dnmp_nginx_1 /bin/sh
為什么站點(diǎn)根目錄在Nginx和PHP-FPM都這樣掛載?
./www/:/var/www/html/
我們知道,Nginx配置都有這樣一項(xiàng):
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
其中,$document_root
就是server
塊下root
所指的路徑:
server { #... ? ? root /var/www/html; #... }
這里$document_root
就是/var/www/html
。
如果Nginx和PHP-FPM在同一主機(jī),Nginx會通過9000
端口把這個(gè)目錄值和腳本URI傳給PHP-FPM。
PHP-FPM再通過9000
端口接收Nginx發(fā)過來的目錄值和腳本URI,發(fā)給PHP解析。
PHP收到后,就到指定的目錄下查找PHP文件并解析,完成后再通過9000
端口返回給Nginx。
如果Nginx和PHP-FPM在同一個(gè)主機(jī)里面,PHP就總能找到Nginx指定的目錄。
但是,如果他們在不同的容器呢?
未做任何處理的情況,Nginx容器中的站點(diǎn)根目錄,PHP-FPM容器肯定不存在。
所以,這里需要保證Nginx和PHP-FPM都掛載了Host的./www/
,并且都掛載在容器的:/var/www/html
。
(當(dāng)然,你也可以指定別的目錄,確保統(tǒng)一即可)
如果容器已經(jīng)生成,回頭再編輯docker-compose.yml,用
docker-compose up
命令會直接啟動(dòng)原來的容器,修改的內(nèi)容不會體現(xiàn)在啟動(dòng)的容器里。
所以,要使修改的docker-compose.yml生效,需要以下4步:
$ docker stop dnmp_nginx_1 # 第一步:停止容器 $ docker rm dnmp_nginx_1 # 第二步:刪除容器 # !!第三步:重啟Docker服務(wù)!! $ docker-compose up -d --no-deps --build mysql # 第四步:重新啟動(dòng)容器
其中最后一條命令參數(shù)作用:
-d
:后臺執(zhí)行--no-deps
:不啟動(dòng)link
的容器--build
:啟動(dòng)容器前先構(gòu)建鏡像因?yàn)镻HP-FPM構(gòu)建稍微復(fù)雜,涉及到很多擴(kuò)展。
所以單獨(dú)用Dockerfile文件構(gòu)建PHP-FPM:
FROM php:fpm ## Copy sources.list to container. ## Here we use 163.com sources list. ## PHP 5.6.31+ should use jessie sources list ## PHP 7.2.0+ should use stretch sources list ## For more please check: ## PHP official docker repository: https://hub.docker.com/r/library/php/ #COPY ./files/sources.list.stretch /etc/apt/sources.list #COPY ./files/sources.list.jessie /etc/apt/sources.list ## Update Ubuntu RUN apt-get update ## mcrypt RUN apt-get install -y libmcrypt-dev RUN docker-php-ext-install mcrypt ## GD RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng12-dev RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ RUN docker-php-ext-install -j$(nproc) gd ## Intl RUN apt-get install -y libicu-dev RUN docker-php-ext-install -j$(nproc) intl ## General RUN docker-php-ext-install zip RUN docker-php-ext-install pcntl RUN docker-php-ext-install opcache RUN docker-php-ext-install pdo_mysql RUN docker-php-ext-install mysqli RUN docker-php-ext-install mbstring ## ...
完整Dockerfile請移步本項(xiàng)目GitHub倉庫。
這里,我們還需要稍微修改nginx配置文件:
location ~ .php$ { fastcgi_pass fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
這里,我們僅需把fastcgi_pass
改成:fpm:9000
。
也就是,PHP-FPM的偵聽主機(jī)改成:Nginx?links
PHP-FPM容器的別名,在docker-compose.yml文件里面我們設(shè)置為fpm
。
這樣Nginx容器啟動(dòng)的時(shí)候,就會自動(dòng)修改自己的/etc/hosts
,讓fpm
指向php-fpm容器的IP。
修改之后,重啟容器中的nginx:
$ docker exec dlnmp_nginx_1 nginx -s reload
其中,dlnmp_nginx_1
是容器的名稱,也可以指定容器的ID。
有時(shí)候,我們的PHP代碼需要某個(gè)目錄的寫權(quán)限。
比如,Wordpress的wp-content/uploads
目錄,只有寫權(quán)限我們才能正常上傳文件。
默認(rèn)的,容器中的/var/www/html
目錄屬于root
,我們需要修改為www-data
,PHP才能正常寫目錄。
先進(jìn)入到容器中:
$ docker exec -it dlnmp_php-fpm_1 /bin/bash
然后修改目錄權(quán)限:
$ chown -R www-data:www-data /var/www/html
這樣PHP就能正常讀寫目錄了。
在docker-compose.yml文件中,我們指定了MySQL數(shù)據(jù)庫root
用戶的密碼為123456
。
所以,我們就可以在主機(jī)中通過:
$ mysql -h 127.0.0.1 -u root -p
輸入密碼,就可以進(jìn)入MySQL命令行。
說明:這里MySQL的連接主機(jī)不能用localhost
,因?yàn)镸ySQL客戶端默認(rèn)使用unix socket方式連接,應(yīng)該直接用本地IP。
在PHP代碼中的使用方式與在主機(jī)中使用稍有不同,如下:
$pdo = new PDO('mysql:host=mysql;dbname=site1', 'root', '123456');
其中,host
的值就是在docker-compose.yml里面指定的MySQL容器的名稱。
這是因?yàn)镻HP代碼是在FPM容器中,F(xiàn)PM容器啟動(dòng)時(shí)會自動(dòng)在/etc/hosts
中加上:
172.17.0.2 mysql 11e55f91c4c3 dlnmp_mysql_1
就是說,mysql
自動(dòng)指向了MySQL容器動(dòng)態(tài)生成的IP。
Redis使用和MySQL類似。
在主機(jī)和容器內(nèi)部都通過地址127.0.0.1
,端口6379
訪問。
PHP則是跨容器訪問,host
參數(shù)用redis
(links
指定的名稱),端口用6379
。
到這里我們用docker搭建的Docker (Linux) + Nginx + MySQL + PHP環(huán)境已經(jīng)可以正常使用了。
但每次啟動(dòng)系統(tǒng)都得切換到項(xiàng)目目錄,再執(zhí)行compose up
,就略顯繁瑣。
要是能在系統(tǒng)啟動(dòng)的時(shí)候自動(dòng)啟動(dòng)容器,豈不是更好,下面是具體的方法。
從Launcher中搜索Startup Applications(啟動(dòng)應(yīng)用程序),
然后Add一項(xiàng),名字:Dnmp,命令填:
docker-compose -f /home/gary/dnmp/docker-compose.yml up -d
其中,-f
指定docker-compose.yml文件的位置。
然后保存即可。
其他命令行下的Linux系統(tǒng),可以直接編輯 /etc/rc.local 文件,加上上面的命令。
版權(quán)所有:深圳市網(wǎng)商在線科技有限公司