特別說明
最近在GitHub上發現一個不錯的PHP全家桶開發環境,是使用的docker搭建的。不過看更新動態,作者很少維護了。同時也加入了這個群,也發現使用這個倉庫的很多開發者會遇到很多的問題。為了讓這個倉庫發揮真正的作用,變fork了一個倉庫,保證後面的長時間更新和解決大家所遇到的問題。
Gitee倉庫地址:gitee.com/bruce_qiq/php_dnmp
GitHub倉庫地址:github.com/bruceqiq/php_dnmp
使用說明
如果你在使用的過程中發現什麼問題,可以提issue。如果你的問題比較著急,需要得到快速解決,你可以新增下面的公眾號,關注之後,點選相關資源
選單,得到倉庫維護者的即使支援。
文件說明
DNMP(Docker + Nginx + MySQL + PHP7/5 + Redis)是一款全功能的LNMP一鍵安裝程式。
使用前最好提前閱讀一遍目錄,以便快速上手,遇到問題也能及時排除。
DNMP專案特點:
100%
開源100%
遵循Docker標準- 支援多版本PHP共存,可任意切換(PHP5.4、PHP5.6、PHP7.1、PHP7.2、PHP7.3)
- 支援繫結任意多個域名
- 支援HTTPS和HTTP/2
- PHP原始碼、MySQL資料、配置檔案、日誌檔案都可在Host中直接修改檢視
- 內建完整PHP擴充套件安裝命令
- 預設支援
pdo_mysql
、mysqli
、mbstring
、gd
、curl
、opcache
等常用熱門擴充套件,根據環境靈活配置 - 可一鍵選配常用服務:
- 多PHP版本:PHP5.4、PHP5.6、PHP7.1-7.3
- Web服務:Nginx、Openresty
- 資料庫:MySQL5、MySQL8、Redis、memcached、MongoDB、ElasticSearch
- 訊息佇列:RabbitMQ
- 輔助工具:Kibana、Logstash、phpMyAdmin、phpRedisAdmin、AdminMongo
- 實際專案中應用,確保
100%
可用 - 所有映象源於Docker官方倉庫,安全可靠
- 一次配置,Windows、Linux、MacOs皆可用
- 支援快速安裝擴充套件命令
install-php-extensions apcu
1.目錄結構
/
├── data 資料庫資料目錄
│ ├── esdata ElasticSearch 資料目錄
│ ├── mongo MongoDB 資料目錄
│ ├── mysql MySQL8 資料目錄
│ └── mysql5 MySQL5 資料目錄
├── services 服務構建檔案和配置檔案目錄
│ ├── elasticsearch ElasticSearch 配置檔案目錄
│ ├── mysql MySQL8 配置檔案目錄
│ ├── mysql5 MySQL5 配置檔案目錄
│ ├── nginx Nginx 配置檔案目錄
│ ├── php PHP5.6 - PHP7.3 配置目錄
│ ├── php54 PHP5.4 配置目錄
│ └── redis Redis 配置目錄
├── logs 日誌目錄
├── docker-compose.sample.yml Docker 服務配置示例檔案
├── env.smaple 環境配置示例檔案
└── www PHP 程式碼目錄
2.快速使用
- 本地安裝
git
Docker
(系統需為Linux,Windows 10 Build 15063+,或MacOS 10.12+,且必須要64
位)docker-compose 1.7.0+
clone
專案:$ git clone https://github.com/yeszao/dnmp.git
- 如果不是
root
使用者,還需將當前使用者加入docker
使用者組:$ sudo gpasswd -a ${USER} docker
- 拷貝並命名配置檔案(Windows系統請用
copy
命令),啟動:$ cd dnmp # 進入專案目錄 $ cp env.sample .env # 複製環境變數檔案 $ cp docker-compose.sample.yml docker-compose.yml # 複製 docker-compose 配置檔案。預設啟動3個服務: # Nginx、PHP7和MySQL8。要開啟更多其他服務,如Redis、 # PHP5.6、PHP5.4、MongoDB,ElasticSearch等,請刪 # 除服務塊前的註釋 $ docker-compose up # 啟動
- 在瀏覽器中訪問:
http://localhost
或https://localhost
(自簽名HTTPS演示)就能看到效果,PHP程式碼在檔案./www/localhost/index.php
。
3.PHP和擴充套件
3.1 切換Nginx使用的PHP版本
首先,需要啟動其他版本的PHP,比如PHP5.4,那就先在docker-compose.yml
檔案中刪除PHP5.4前面的註釋,再啟動PHP5.4容器。
PHP5.4啟動後,開啟Nginx 配置,修改fastcgi_pass
的主機地址,由php
改為php54
,如下:
fastcgi_pass php:9000;
為:
fastcgi_pass php54:9000;
其中 php
和 php54
是docker-compose.yml
檔案中伺服器的名稱。
最後,重啟 Nginx 生效。
$ docker exec -it nginx nginx -s reload
這裡兩個nginx
,第一個是容器名,第二個是容器中的nginx
程式。
3.2 安裝PHP擴充套件
PHP的很多功能都是通過擴充套件實現,而安裝擴充套件是一個略費時間的過程,
所以,除PHP內建擴充套件外,在env.sample
檔案中我們僅預設安裝少量擴充套件,
如果要安裝更多擴充套件,請開啟你的.env
檔案修改如下的PHP配置,
增加需要的PHP擴充套件:
PHP_EXTENSIONS=pdo_mysql,opcache,redis # PHP 要安裝的擴充套件列表,英文逗號隔開
PHP54_EXTENSIONS=opcache,redis # PHP 5.4要安裝的擴充套件列表,英文逗號隔開
然後重新build PHP映象。
docker-compose build php
可用的擴充套件請看同檔案的env.sample
註釋塊說明。
3.3 快速安裝php擴充套件
1.進入容器:
docker exec -it php /bin/sh
install-php-extensions apcu
2.支援快速安裝擴充套件列表
Extension | PHP 5.5 | PHP 5.6 | PHP 7.0 | PHP 7.1 | PHP 7.2 | PHP 7.3 | PHP 7.4 |
---|---|---|---|---|---|---|---|
amqp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
apcu | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
apcu_bc | ✓ | ✓ | ✓ | ✓ | ✓ | ||
bcmath | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
bz2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
calendar | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
cmark | ✓ | ✓ | ✓ | ✓ | ✓ | ||
dba | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
decimal | ✓ | ✓ | ✓ | ✓ | ✓ | ||
enchant | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
exif | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
ffi | ✓ | ||||||
gd | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
gettext | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
gmagick | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
gmp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
grpc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
http | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
igbinary | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
imagick | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
imap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
interbase | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
intl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
ldap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
mailparse | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
mcrypt | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
memcache | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
memcached | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
mongo | ✓ | ✓ | |||||
mongodb | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
msgpack | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
mssql | ✓ | ✓ | |||||
mysql | ✓ | ✓ | |||||
mysqli | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
oauth | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
odbc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
opcache | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
opencensus | ✓ | ✓ | ✓ | ✓ | ✓ | ||
parallel* | ✓ | ✓ | ✓ | ✓ | |||
pcntl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pcov | ✓ | ✓ | ✓ | ✓ | ✓ | ||
pdo_dblib | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pdo_firebird | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pdo_mysql | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pdo_odbc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pdo_pgsql | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pdo_sqlsrv | ✓ | ✓ | ✓ | ✓ | ✓ | ||
pgsql | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
propro | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
protobuf | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pspell | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
pthreads* | ✓ | ✓ | ✓ | ||||
raphf | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
rdkafka | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
recode | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
redis | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
shmop | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
snmp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
snuffleupagus | ✓ | ✓ | ✓ | ✓ | ✓ | ||
soap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
sockets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
solr | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
sqlsrv | ✓ | ✓ | ✓ | ✓ | ✓ | ||
ssh2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
sybase_ct | ✓ | ✓ | |||||
sysvmsg | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
sysvsem | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
sysvshm | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
tdlib* | ✓ | ✓ | ✓ | ✓ | ✓ | ||
tidy | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
timezonedb | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
uopz | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
uuid | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
wddx | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
xdebug | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
xhprof | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
xmlrpc | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
xsl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
yaml | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
zip | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
zookeeper | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
此擴充套件來自github.com/mlocati/docker-php-exte...
參考示例檔案
3.4 Host中使用php命令列(php-cli)
- 參考bash.alias.sample示例檔案,將對應 php cli 函式拷貝到主機的
~/.bashrc
檔案。 - 讓檔案起效:
source ~/.bashrc
- 然後就可以在主機中執行php命令了:
~ php -v PHP 7.2.13 (cli) (built: Dec 21 2018 02:22:47) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.13, Copyright (c) 1999-2018, by Zend Technologies with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans
3.5 使用composer
方法1:主機中使用composer命令
確定composer快取的路徑。比如,我的dnmp下載在
~/dnmp
目錄,那composer的快取路徑就是~/dnmp/data/composer
。參考bash.alias.sample示例檔案,將對應 php composer 函式拷貝到主機的
~/.bashrc
檔案。這裡需要注意的是,示例檔案中的
~/dnmp/data/composer
目錄需是第一步確定的目錄。讓檔案起效:
source ~/.bashrc
在主機的任何目錄下就能用composer了:
cd ~/dnmp/www/ composer create-project yeszao/fastphp project --no-dev
(可選)第一次使用 composer 會在
~/dnmp/data/composer
目錄下生成一個config.json檔案,可以在這個檔案中指定國內倉庫,例如:{ "config": {}, "repositories": { "packagist": { "type": "composer", "url": "https://packagist.laravel-china.org" } } }
方法二:容器內使用composer命令
還有另外一種方式,就是進入容器,再執行composer
命令,以PHP7容器為例:
docker exec -it php /bin/sh
cd /www/localhost
composer update
4.管理命令
4.1 伺服器啟動和構建命令
如需管理服務,請在命令後面加上伺服器名稱,例如:
$ docker-compose up # 建立並且啟動所有容器
$ docker-compose up -d # 建立並且後臺執行方式啟動所有容器
$ docker-compose up nginx php mysql # 建立並且啟動nginx、php、mysql的多個容器
$ docker-compose up -d nginx php mysql # 建立並且已後臺執行的方式啟動nginx、php、mysql容器
$ docker-compose start php # 啟動服務
$ docker-compose stop php # 停止服務
$ docker-compose restart php # 重啟服務
$ docker-compose build php # 構建或者重新構建服務
$ docker-compose rm php # 刪除並且停止php容器
$ docker-compose down # 停止並刪除容器,網路,影像和掛載卷
4.2 新增快捷命令
在開發的時候,我們可能經常使用docker exec -it
進入到容器中,把常用的做成命令別名是個省事的方法。
首先,在主機中檢視可用的容器:
$ docker ps # 檢視所有執行中的容器
$ docker ps -a # 所有容器
輸出的NAMES
那一列就是容器的名稱,如果使用預設配置,那麼名稱就是nginx
、php
、php56
、mysql
等。
然後,開啟~/.bashrc
或者~/.zshrc
檔案,加上:
alias dnginx='docker exec -it nginx /bin/sh'
alias dphp='docker exec -it php /bin/sh'
alias dphp56='docker exec -it php56 /bin/sh'
alias dphp54='docker exec -it php54 /bin/sh'
alias dmysql='docker exec -it mysql /bin/bash'
alias dredis='docker exec -it redis /bin/sh'
下次進入容器就非常快捷了,如進入php容器:
$ dphp
4.3 檢視docker網路
ifconfig docker0
用於填寫extra_hosts
容器訪問宿主機的hosts
地址
5.使用Log
Log檔案生成的位置依賴於conf下各log配置的值。
5.1 Nginx日誌
Nginx日誌是我們用得最多的日誌,所以我們單獨放在根目錄log
下。
log
會目錄對映Nginx容器的/var/log/nginx
目錄,所以在Nginx配置檔案中,需要輸出log的位置,我們需要配置到/var/log/nginx
目錄,如:
error_log /var/log/nginx/nginx.localhost.error.log warn;
5.2 PHP-FPM日誌
大部分情況下,PHP-FPM的日誌都會輸出到Nginx的日誌中,所以不需要額外配置。
另外,建議直接在PHP中開啟錯誤日誌:
error_reporting(E_ALL);
ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
如果確實需要,可按一下步驟開啟(在容器中)。
- 進入容器,建立日誌檔案並修改許可權:
$ docker exec -it php /bin/sh $ mkdir /var/log/php $ cd /var/log/php $ touch php-fpm.error.log $ chmod a+w php-fpm.error.log
- 主機上開啟並修改PHP-FPM的配置檔案
conf/php-fpm.conf
,找到如下一行,刪除註釋,並改值為:php_admin_value[error_log] = /var/log/php/php-fpm.error.log
- 重啟PHP-FPM容器。
5.3 MySQL日誌
因為MySQL容器中的MySQL使用的是mysql
使用者啟動,它無法自行在/var/log
下的增加日誌檔案。所以,我們把MySQL的日誌放在與data一樣的目錄,即專案的mysql
目錄下,對應容器中的/var/lib/mysql/
目錄。
slow-query-log-file = /var/lib/mysql/mysql.slow.log
log-error = /var/lib/mysql/mysql.error.log
以上是mysql.conf中的日誌檔案的配置。
6.資料庫管理
本專案預設在docker-compose.yml
中開啟了用於MySQL線上管理的phpMyAdmin,以及用於redis線上管理的phpRedisAdmin,可以根據需要修改或刪除。
6.1 phpMyAdmin
phpMyAdmin容器對映到主機的埠地址是:8080
,所以主機上訪問phpMyAdmin的地址是:
http://localhost:8080
MySQL連線資訊:
- host:(本專案的MySQL容器網路)
- port:
3306
- username:(手動在phpmyadmin介面輸入)
- password:(手動在phpmyadmin介面輸入)
6.2 phpRedisAdmin
phpRedisAdmin容器對映到主機的埠地址是:8081
,所以主機上訪問phpMyAdmin的地址是:
http://localhost:8081
Redis連線資訊如下:
- host: (本專案的Redis容器網路)
- port:
6379
7.在正式環境中安全使用
要在正式環境中使用,請:
- 在php.ini中關閉XDebug除錯
- 增強MySQL資料庫訪問的安全策略
- 增強redis訪問的安全策略
8 常見問題
8.1 如何在PHP程式碼中使用curl?
參考這個issue:github.com/yeszao/dnmp/issues/91
8.2 Docker使用cron定時任務
8.3 Docker容器時間
容器時間在.env檔案中配置TZ
變數,所有支援的時區請看時區列表·維基百科或者PHP所支援的時區列表·PHP官網。
8.4 如何連線MySQL和Redis伺服器
這要分兩種情況,
第一種情況,在PHP程式碼中。
// 連線MySQL
$dbh = new PDO('mysql:host=mysql;dbname=mysql', 'root', '123456');
// 連線Redis
$redis = new Redis();
$redis->connect('redis', 6379);
因為容器與容器是expose
埠聯通的,而且在同一個networks
下,所以連線的host
引數直接用容器名稱,port
引數就是容器內部的埠。更多請參考《docker-compose ports和expose的區別》。
第二種情況,在主機中通過命令列或者Navicat等工具連線。主機要連線mysql和redis的話,要求容器必須經過ports
把埠對映到主機了。以 mysql 為例,docker-compose.yml
檔案中有這樣的ports
配置:3306:3306
,就是主機的3306和容器的3306埠形成了對映,所以我們可以這樣連線:
$ mysql -h127.0.0.1 -uroot -p123456 -P3306
$ redis-cli -h127.0.0.1
這裡host
引數不能用localhost是因為它預設是通過sock檔案與mysql通訊,而容器與主機檔案系統已經隔離,所以需要通過TCP方式連線,所以需要指定IP。
8.5 容器內的php如何連線宿主機MySQL
1.宿主機執行ifconfig docker0
得到inet
就是要連線的ip
地址
$ ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
...
2.執行宿主機Mysql命令列
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
mysql>flush privileges;
// 其中各字元的含義:
// *.* 對任意資料庫任意表有效
// "root" "123456" 是資料庫使用者名稱和密碼
// '%' 允許訪問資料庫的IP地址,%意思是任意IP,也可以指定IP
// flush privileges 重新整理許可權資訊
3.接著直接php容器使用172.0.17.1:3306
連線即可
本作品採用《CC 協議》,轉載必須註明作者和本文連結