DNMP(Docker + Nginx + MySQL + PHP)是一款全功能的LNMP环境一键安装程序,可多版本
使用前最好阅读一遍下面的说明文件,以便快速上手,遇到问题也能及时排查
git
Docker
docker-compose 2.0.0+
clone
项目
git clone https://github.com/xiaoyu98628/dnmp.git
# 或者
git clone https://gitee.com/xiaoyucc521/dnmp.git
# 进入项目目录
cd dnmp
# 复制并改名 .env 配置文件
cp sample.env .env
# 复制并改名 compose.yml 配置文件
cp compose.sample.yml compose.yml
# 复制并改名 vhost文件
cp servers/panel/vhost/nginx/nginx1.21/localhost.conf.sample servers/panel/vhost/nginx/nginx1.21/您的域名.conf
# 执行 docker compose up 之前,建议看一下compose.yml 文件,以便快速上手。
docker compose up # 启动服务
http[s]://[你的域名]/72 # PHP72
http[s]://[你的域名]/73 # PHP73
http[s]://[你的域名]/74 # PHP74
http[s]://[你的域名]/80 # PHP80
http[s]://[你的域名]/81 # PHP81
http[s]://[你的域名]/82 # PHP82
http[s]://[你的域名]/83 # PHP83
|-- data 数据库数据目录
| |--- mysql mysql 数据目录(多版本)
| | |--- mysql8.0 mysql8.0 数据目录
|--- logs 日志目录
| |--- mysql mysql 日志目录(多版本)
| | |--- mysql8.0 mysql8.0 日志目录
|--- plugins 插件目录
| |--- elasticsearch elasticsearch 插件目录(多版本)
| | |--- elasticsearch8.4 elasticsearch8.4 插件目录
|--- resource 资源目录(存放图片和.md的说明文件)
|--- servers 服务构建文件和配置文件目录
| |--- elasticsearch elasticsearch 配置文件目录(多版本)
| |--- kibana kibana 配置文件目录(多版本)
| |--- mysql mysql 配置文件目录(多版本)
| |--- mongo mongo 配置文件目录(多版本)
| |--- nginx nginx 配置文件目录(多版本)
| |--- php php 配置文件目录(多版本)
| | |--- php7.2 php7.2 配置文件目录
| | |--- php7.3 php7.3 配置文件目录
| |--- redis redis 配置文件目录(多版本)
| |--- rabbitmq rabbitmq 配置文件目录(多版本)
| |--- panel 服务面板
| | |--- vhost 站点配置文件目录
| | |--- ssl https 证书目录
| | |--- sock 套接字文件目录
|--- www 项目文件目录
|--- bashrc.sample .bashrc 配置示例文件(宿主机使用容器内命令)
|--- sample.env 环境配置示例文件
|--- compose.sample.yml Docker 服务配置示例文件
docker-php-source
此命令,实际上就是在PHP容器中创建一个
/usr/src/php
的目录,里面放了一些自带的文件而已。我们就把它当作一个从互联网中下载下来的PHP扩展源码的存放目录即可。事实上,所有PHP扩展源码扩展存放的路径:/usr/src/php/ext
里面。
docker-php-ext-install
这个命令,就是用来启动 PHP扩展 的。我们使用pecl安装PHP扩展的时候,默认是没有启动这个扩展的,如果想要使用这个扩展必须要在php.ini这个配置文件中去配置一下才能使用这个PHP扩展。而
docker-php-ext-enable
这个命令则是自动给我们来启动PHP扩展的,不需要你去php.ini这个配置文件中去配置。
docker-php-ext-enable
这个命令,是用来安装并启动PHP扩展的。命令格:
docker-php-ext-install "源码包目录名"
docker-php-ext-configure
一般都是需要跟 docker-php-ext-install搭配使用的。它的作用就是,当你安装扩展的时候,需要自定义配置时,就可以使用它来帮你做到。
docker exec -it php71 sh
install-php-extensions redis
注意:以上两种方式是在容器内安装扩展,容器删除,扩展也会随之删除,建议在镜像层安装扩展,在.env文件里添加对应的扩展,然后重新
docker compose build php72
构建镜像即可
# +--------------+
# PHP7.2
# +--------------+
#
# +--------------------------------------------------------------------------------------------+
# Default installed:
#
# Core,ctype,curl,date,dom,fileinfo,filter,ftp,hash,iconv,json,libxml,mbstring,mysqlnd,openssl,pcre,PDO,
# pdo_sqlite,Phar,posix,readline,Reflection,session,SimpleXML,sodium,SPL,sqlite3,standard,tokenizer,xml,
# xmlreader,xmlwriter,zlib
#
# Available PHP_EXTENSIONS:
#
# pdo_mysql,pcntl,mysqli,exif,bcmath,opcache,gettext,gd,sockets,shmop,intl,bz2,soap,zip,sysvmsg,sysvsem,
# sysvshm,xsl,calendar,tidy,snmp,
# amqp,apcu,rdkafka,redis,swoole,memcached,xdebug,mongodb,protobuf,grpc,xlswriter,igbinary,psr,phalcon,
# mcrypt,yaml
#
# You can let it empty to avoid installing any extensions,
# +--------------------------------------------------------------------------------------------+
PHP_EXTENSIONS_72=pdo_mysql,mysqli,gd,redis,zip,bcmath,xlswriter
composer config -gl
composer config -g repo.packagist composer https://packagist.phpcomposer.com
# 或
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer
~/.bashrc
文件中。source ~/.bashrc
[root@centos ~]# php72 -v
PHP 7.2.34 (cli) (built: Dec 17 2020 10:32:53) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
[root@centos ~]#
在Linux系统中,PHP-FPM使用 SYS_PTRACE 跟踪worker进程,但是docker容器默认又不启用这个功能,所以就导致了这个问题。
解决:
--cap-add=SYS_PTRACE
php72:
# ...
cap_add:
- SYS_PTRACE
# ...
新增的 .conf
文件应放在 servers/panel/vhost/nginx/nginx版本
文件夹下
比如切换为PHP8.3,打开 ./servers/panel/vhost/nginx/nginx版本
下对应的Nginx站点配置文件,找到 include enable-php-80.conf
改成 include enable-php-83.conf
即可
例如:
location ~ [^/]\.php(/|$) {
...
include enable-php-80.conf;
...
}
改为:
location ~ [^/]\.php(/|$) {
...
include enable-php-83.conf;
...
}
注意:修改了nginx配置文件,使之生效必须要 重启 Nginx 容器 或者 在容器中执行
nginx -s reload
为什么站点根目录在Nginx和PHP-FPM都需要挂载?
# php 挂载目录
- "../www:/var/www/html"
# nginx 挂载目录
- "../www:/usr/share/nginx/html"
我们知道,Nginx配置都有这样一项:
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在同一主机,Nginx会通过9000端口(或套接字文件)把这个目录值和脚本URI传给PHP-FPM。
PHP-FPM再通过9000端口(或套接字文件)接收Nginx发过来的目录值和脚本URI,发给PHP解析。
PHP收到后,就到指定的目录下查找PHP文件并解析,完成后再通过9000端口(或套接字文件)返回给Nginx。
如果Nginx和PHP-FPM在同一个主机里面,PHP就总能找到Nginx指定的目录。
但是,如果他们在不同的容器呢?
未做任何处理的情况,Nginx容器中的站点根目录,PHP-FPM容器肯定不存在。 所以,这里需要保证Nginx和PHP-FPM都挂载了宿主机的 ./www
。 (当然,你也可以指定别的目录)
ssl
证书存放位置
./servers/panel/ssl/nginx/nginx版本/站点名称/证书
nginx.conf
配置文件修改
server {
listen 80;
listen [::]:80;
server_name xxx; # 您的域名
# 跳转 实现 http 强转 https
rewrite ^(.*)$ https://${server_name}$1 permanent;
...
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name xxx; # 您的域名和上面的域名一致
#ssl证书地址
ssl_certificate /usr/panel/ssl/nginx/nginx版本/站点名称/xxx; # 公钥
ssl_certificate_key /usr/panel/ssl/nginx/nginx版本/站点名称/xxx; # 私钥
#ssl验证相关配置
ssl_session_timeout 5m; #缓存有效期
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #加密算法
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #安全链接可选的加密协议
ssl_prefer_server_ciphers on; #使用服务器端的首选算法
...
}
# 方式一:重启 docker compose restart 服务ID
docker compose restart nginx1.21
# 方式二:重载 docker exec 容器ID nginx -s reload
docker exec nginx1.21 nginx -s reload
# 自动生成密码
./bin/elasticsearch-setup-passwords auto
# 手动设置密码
./bin/elasticsearch-setup-passwords interactive
执行后会自动生成密码
Changed password for user apm_system
PASSWORD apm_system = {密码}
Changed password for user kibana_system
PASSWORD kibana_system = {密码}
Changed password for user kibana
PASSWORD kibana = {密码}
Changed password for user logstash_system
PASSWORD logstash_system = {密码}
Changed password for user beats_system
PASSWORD beats_system = {密码}
Changed password for user remote_monitoring_user
PASSWORD remote_monitoring_user = {密码}
Changed password for user elastic
PASSWORD elastic = {密码}
elasticsearch.username: "kibana_system或kibana"
elasticsearch.password: "上面Elasticsearch生成的密码"
system.sessions
文档没权限访问授权
db.grantRolesToUser('userName',[{role:"<role>",db:"<database>"}])
// 例如
db.grantRolesToUser('root',[{role:"__system",db:"admin"}])
当前redis容器是 启用密码
的,默认密码 123456
如需修改密码直接在 .env
文件中找到下面配置项,修改即可
# +--------------+
# mysql6.2
# +--------------+
REDIS_PASSWORD_62=123456
当前mysql容器提供两个账户,root账户
,默认在容器内部访问 xiaoyu账户
默认权限不足
# +--------------+
# mysql8.0
# +--------------+
MYSQL_ROOT_PASSWORD_80=root
MYSQL_ROOT_HOST_80=localhost
MYSQL_USER_80=xiaoyu
MYSQL_PASSWORD_80=xiaoyu
如需修改请在 .env
文件中找到相应配置,对应修改
MYSQL_ROOT_PASSWORD_80
默认账户 root
对应的密码MYSQL_ROOT_HOST_80
默认账户 root
对应的访问权限MYSQL_USER_80
新建账户 xiaoyu
用户名MYSQL_PASSWORD_80
新建账户 xiaoyu
对应的密码如需修改权限,对照下面命令修改
-- privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所的权限则使用ALL
-- database_name:数据库名
-- table_name:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用*表示,如*.*
GRANT privileges ON database_name.table_name TO 'username'@'host';
-- 例子:
GRANT SELECT,INSERT ON test.user TO 'xiaoyu'@'%';
GRANT ALL ON *.* TO 'xiaoyu'@'%';
GRANT ALL ON maindataplus.* TO 'xiaoyu'@'%';
由于数据卷和日志卷分离的原因,部分容器启动需要对应的权限,然而宿主机上没有与之对应的权限,所以我们直接赋予777
权限即可
需要给 ./logs/mysql
文件夹赋予权限 chmod -R 777 ./logs/mysql
重启即可
需要给 ./data/elasticsearch
、 ./logs/elasticsearch
文件夹赋予权限 chmod -R 777 ./data/elasticsearch ./logs/elasticsearch
重启即可
需要给 ./data/mongo
、 ./logs/mongo
文件夹赋予权限 chmod -R 777 ./data/mongo ./logs/mongo
重启即可
需要给 ./data/rabbitmq
、 ./logs/rabbitmq
文件夹赋予权限 chmod -R 777 ./data/rabbitmq ./logs/rabbitmq
重启即可
如需管理服务,请在命令后面加上服务器名称,例如:
docker compose up # 创建并启动所有服务
docker compose up -d # 创建并以后台运行方式启动所有服务
docker compose up "服务名..." # 创建并启动服务
docker compose up -d "服务名..." # 创建并以后台运行的方式启动服务
docker compose start "服务名..." # 启动服务
docker compose stop "服务名..." # 停止服务
docker compose restart "服务名..." # 重启服务
docker compose build "服务名..." # 构建或者重新构建服务
docker compose rm "服务名..." # 删除并停止
docker compose down # 停止并删除容器,网络,图像和挂载卷
Docker 镜像(容器)的导入导出,用于迁移,备份,升级等场景。涉及的命令有 save
, load
, export
, import
# docker save [可选项] 镜像名称1 [镜像名称2...]
# 可选项:
# -o, --output string Write to a file, instead of STDOUT
docker save -o dnmp-php72.tar dnmp-php72
# docker export [可选项] 容器
# 可选项:
# -o, --output string Write to a file, instead of STDOUT
docker export -o php72.tar php72
注意:dnmp-php72 是本地已经存在的镜像。完成后会在本地生成一个 dnmp-php72.tar 的压缩包文件
# docker load [可选项]
# 可选项:
# -i, --input string Read from tar archive file, instead of STDIN
# -q, --quiet Suppress the load output
docker load -i dnmp-php72.tar
# docker import [可选项] file|URL|- [REPOSITORY[:TAG]]
# 可选项:
# -c, --change list Apply Dockerfile instruction to the created image
# -m, --message string Set commit message for imported image
# --platform string Set platform if server is multi-platform capable
docker import php72.tar php72:v1
注意:导入之前记得删除本地和导入重名的镜像
save
, load
, export
, import
区别与联系compose.sample.yml
文件中 volumes
的 rw、ro详解众所周知,如果启动容器不使用挂载宿主机的文件或文件夹,容器中的配置文件只能进入容器才能修改,输出的日志文件也是在容器里面,查看不方便,也不利于日志收集,所以一般都是使用参数来挂载文件或文件夹。
而其中的rw、ro和不指定模式,是比较重要的一个环节,关系到宿主机与容器的文件、文件夹变化关系,下面来一一详解
容器时间在.env文件中配置TZ
变量,所有支持的时区请查看 时区列表·维基百科 或者 PHP所支持的时区列表·PHP官网。
SQLSTATE[HY000] [1044] Access denied for user '你的用户名'@'%' to database 'mysql'
compose.yml
文件中或者docker run -e
中,设置并且有且仅有MYSQL_ROOT_PASSWORD
这个参数,你将不会出现这个问题compose.yml
文件中或者docker run -e
中,设置了MYSQL_ROOT_PASSWORD
、MYSQL_ROOT_HOST
、MYSQL_USER
、MYSQL_PASSWORD
,并且你的连接不是使用root
用户连接的将会出现这个问题information_schema
这个库的权限)[output clipped, Log limit 1MiB reached]
日志限制达到1MiB如果在 docker compose build "服务名"
出现了这句话并且构建失败,命令改成 COMPOSE_DOCKER_CLI_BUILD=0 DOCKER_BUILDKIT=0 docker compose build "服务名"
可以看到的错误信息,方便修改
该项目起初参考了很多开源项目的解决方案,开源不易,感谢分享
开源项目离不开大家的支持,如果您有好的想法,遇到一些 BUG 并修复了,欢迎小伙伴们提交 Pull Request 参与开源贡献
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型