一、概述
環境介紹
操作系統:centos 7.6
docker版本:19.03.8
ip地址:192.168.31.34
本文將介紹如何使用單機部署Nginx+PHP-FPM環境
二、Nginx+PHP-FPM
拉取鏡像
docker pull gaciaga/nginx-vts:latest docker pull crunchgeek/php-fpm:7.3-r7
說明:
nginx鏡像已經加裝了vts模塊,php鏡像是最新版本。
php-fpm安裝的模塊如下:

apc apcu bcmath bz2 calendar Core ctype curl date dba dom ds enchant exif fileinfo filter ftp gd gettext gmp hash iconv igbinary imagick imap interbase intl json ldap libxml mbstring memcache memcached mongodb msgpack mysqli mysqlnd newrelic openssl pcntl pcre PDO pdo_dblib pdo_mysql pdo_pgsql pdo_sqlite pdo_sqlsrv pgsql Phar posix pspell readline recode redis Reflection session shmop SimpleXML soap sockets sodium SPL sqlite3 ssh2 standard sysvmsg sysvsem sysvshm test tidy tokenizer wddx xdebug xml xmlreader xmlrpc xmlwriter xsl Zend OPcache zip zlib
運行鏡像
docker run -d -it --restart=always --name nginx-vts -p 80:80 gaciaga/nginx-vts:latest docker run -d -it --restart=always --name php-fpm -p 9000:9000 crunchgeek/php-fpm:7.3-r7
修改nginx配置文件
復制配置文件,這里先臨時放到/opt目錄
cd /opt/ docker cp nginx-vts:/etc/nginx/conf.d/default.conf .
修改配置文件
vi default.conf
內容如下:

server { listen 80; server_name localhost; #charset koi8-r; location / { root /usr/share/nginx/html; index index.html index.htm; } location /status { vhost_traffic_status_display; vhost_traffic_status_display_format html; } #error_page 404 /404.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$ { fastcgi_pass 192.168.31.34:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name; include fastcgi_params; } location ~ ^/(fpm_status|health)$ { fastcgi_pass 192.168.31.34:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }
說明:
location ~ \.php$ { fastcgi_pass 192.168.31.34:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name; include fastcgi_params; }
這段配置是用來設置php文件訪問的。
注意:
fastcgi_pass 地址為:主機ip+9000。因為在上面的步驟中,我已經把端口映射出來了。
fastcgi_param 表示php腳本運行的目錄,這里的路徑,是php-fpm里面的路徑,不是nginx容器路徑。因為nginx和php-fpm在2個不同的容器中。
php-fpm容器,默認已經創建了/var/www/html/目錄。此目錄時空的,稍后我會將test.php放入此目錄。
location ~ ^/(fpm_status|health)$ { fastcgi_pass 192.168.31.34:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
這里是用來查看php-fpm的狀態頁面的。
這里定義的fpm_status和health,表示訪問php-fpm對應的路徑。在php-fpm里面的www.conf中,路徑必須一致,后面會介紹修改www.conf文件。
fastcgi_param 這里就不需要寫絕對路徑了,它會自動找到對應的腳本。
覆蓋容器配置文件,並重載nginx
docker cp default.conf nginx-vts:/etc/nginx/conf.d/default.conf docker exec -it nginx-vts nginx -s reload
訪問頁面
http://192.168.31.34/status
效果如下:
修改php-fpm配置文件
復制www.conf,並修改status路徑。注意:這里必須和nginx設置的保持一致。
docker cp php-fpm:/usr/local/etc/php-fpm.d/www.conf . sed -i '238c pm.status_path = /fpm_status' www.conf docker cp www.conf php-fpm:/usr/local/etc/php-fpm.d/www.conf
注意:這里的sed命令表示覆蓋238行的內容。
查看php-fpm進程
# docker exec -it php-fpm ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 1.9 299256 37132 pts/0 Ss+ 09:25 0:00 php-fpm: master www-data 14 0.0 0.6 299416 12236 pts/0 S+ 09:25 0:00 php-fpm: pool w www-data 15 0.0 0.6 299416 12236 pts/0 S+ 09:25 0:00 php-fpm: pool w root 23 0.0 0.0 10620 1416 pts/1 Rs+ 09:38 0:00 ps -aux
php-fpm 重啟
docker exec -it php-fpm kill -USR2 1
php 5.3.3 以后的php-fpm 不再支持 php-fpm 以前具有的 /Data/apps/php7/sbin/php-fpm(start|stop|reload)等命令,所以不要再看這種老掉牙的命令了,需要使用信號控制:master進程可以理解以下信號
訪問php-fpm狀態頁面
http://192.168.31.34/fpm_status
效果如下:
測試php文件
在/opt目錄新建一個test.php
vi /opt/test.php
內容如下
<?php
phpinfo();
?>
拷貝test.php到容器目錄
docker cp test.php php-fpm:/var/www/html/test.php
訪問頁面
http://192.168.31.34/test.php
效果如下;
三、MySQL
直接運行dockerhub里面的mysql5.7鏡像
mkdir -p /data/mysql/data docker run -d --name mysql5.7 --restart=always -e MYSQL_ROOT_PASSWORD=abcd@1234 -p 3306:3306 -v /data/mysql/data:/var/lib/mysql mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
四、phpMyAdmin
為了驗證LNMP環境,使用phpMyAdmin來演示一下,它是用php開發的。
下載代碼
cd /opt/ wget https://files.phpmyadmin.net/phpMyAdmin/5.0.2/phpMyAdmin-5.0.2-all-languages.zip unzip phpMyAdmin-5.0.2-all-languages.zip
修改配置
cd /opt/phpMyAdmin-5.0.2-all-languages cp config.sample.inc.php config.inc.php vi config.inc.php
將
$cfg['Servers'][$i]['host'] = 'localhost';
改為
$cfg['Servers'][$i]['host'] = '192.168.31.34';
拷貝phpMyAdmin到容器中
這里需要在nginx容器里面開放一個81端口,用來訪問phpmyadmin,需要刪除nginx容器,重新運行。
docker rm -f nginx-vts docker run -d -it --restart=always --name nginx-vts -p 80:80 -p 81:81 gaciaga/nginx-vts:latest
復制代碼到nginx容器中
為了和php容器目錄一致,先創建目錄,再copy
docker exec -it nginx-vts mkdir -p /var/www/html
復制代碼到php容器中
docker cp phpMyAdmin-5.0.2-all-languages nginx-vts:/var/www/html/
編輯nginx配置
cd /opt/
vi phpmyadmin.conf
內容如下:
server { listen 81; server_name localhost; root /var/www/html/phpMyAdmin-5.0.2-all-languages; index index.php index.html index.htm; location ~ \.php$ { fastcgi_pass 192.168.31.34:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/phpMyAdmin-5.0.2-all-languages/$fastcgi_script_name; include fastcgi_params; } }
復制配置文件到nginx容器,並重新加載
docker cp default.conf nginx-vts:/etc/nginx/conf.d/ docker cp phpmyadmin.conf nginx-vts:/etc/nginx/conf.d/ docker exec -it nginx-vts nginx -s reload
訪問phpMyAdmin
http://192.168.31.34:81
效果如下:
輸入用戶名:root
密碼:abcd@1234
登錄之后,效果如下:
總結
nginx和php都是獨立運行的docker容器。因此,對於php代碼,必須在php容器中映射才行。至於nginx容器,也最好做一下映射。
但是一般php項目,除了php代碼之外,還有一些靜態資源,比如:html,css,js,jpeg,png等等。
所以,最好是2個容器都做一下映射。nginx負責處理靜態資源,php容器用了解析php代碼。
注意:nginx配置中的fastcgi_param 必須寫絕對路徑。
最后補充一點,php-fpm有一個進程池的概念。類型有2種,分別是static和dynamic。
雖然dynamic可以節約服務器資源,但是對於pv流量比較大的情況下,需要頻繁的回收php-fpm進程池,特別耗費CPU
因此,在大並發情況下,使用static。
如果將php項目運行在k8s中,可以將php容器運行多個副本,nginx通過k8s的cluster ip轉發到php容器。