Mac, Linux 使用Docker 配置 dnmp环境,使用compose一键部署(持续更新,新增PHP83)

DNMP(Docker + Nginx + MySQL + PHP)是一款全功能的LNMP环境一键安装程序,可多版本

使用前最好阅读一遍下面的说明文件,以便快速上手,遇到问题也能及时排查

项目地址(github)https://github.com/xiaoyu98628/dnmp.git

项目地址(gitee)https://gitee.com/xiaoyucc521/dnmp

项目特点

  1. 开源
  2. 遵循Docker标准
  3. 支持多版本PHP共存,可任意切换
  4. 支持绑定任意多个域名
  5. PHP源代码、MySQL数据、配置文件、日志文件都可在主机中直接修改查看
  6. 默认支持pdo_mysqlrediszipgdcurlxlswriter等常用热门扩展,根据环境灵活配置
  7. 可一键配置常用服务(后续会增加)
    • 多PHP版本:PHP7.2、PHP7.3、PHP7.4、PHP8.0、PHP8.1、PHP8.2、PHP8.3
    • Web服务:Nginx
    • 数据库:
      • 关系型:MySQL、
      • 非关系型:Redis、Mongo
    • 搜索引擎:Elasticsearch
    • 消息队列:RabbitMQ
    • 辅助工具:Kibana、mongo-express
  8. 实际项目中应用,确保100%可用
  9. 所有镜像源于 Docker官方仓库,安全可靠
  10. 一次配置,Windows、Linux、MacOS皆可用

1. 目录结构

|-- 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 服务配置示例文件

2. 快速使用

  1. 本地安装

    • git
    • Docker
    • docker-compose 2.0.0+
  2. clone 项目

    git clone https://github.com/xiaoyu98628/dnmp.git
  3. 拷贝并命名配置文件,启动:

    cd dnmp                                          # 进入项目目录
    cp sample.env .env                               # 复制并改名 .env 配置文件
    cp compose.sample.yml compose.yml  # 复制并改名 compose.yml 配置文件
    # 执行 docker compose up 之前,建议看一下compose.yml 文件,以便快速上手。
    docker compose up                                # 启动服务
  4. 启动之后查看PHP版本

    http://localhost/         # PHP72
    http://localhost/73       # PHP73 
    http://localhost/74       # PHP74       
    http://localhost/80       # PHP80 
    http://localhost/81       # PHP81 
    http://localhost/82       # PHP82
    http://localhost/83       # PHP83

3. 关于容器

3.1 PHP

3.1.1 docker容器里安装PHP扩展常用命令

  1. 方法一:
  • 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容器里 PHP安装扩展的步骤
  1. 方法二:

注意:以上两种方式是在容器内安装扩展,容器删除,扩展也会随之删除,建议在镜像层安装扩展,在.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

3.1.2 PHP容器中的composer镜像修改

  1. composer查看全局设置
    composer config -gl 
  2. 设置composer镜像为国内镜像
    composer config -g repo.packagist composer https://packagist.phpcomposer.com # 或
    composer config -g repo.packagist composer https://mirrors.aliyun.com/composer 

3.1.3 phpstorm 配置 xdebug

查看 phpstorm 配置 xdebug 步骤

3.1.4 宿主机中使用PHP命令行

  1. 参考bashrc.sample示例文件,将对应的php-cli函数拷贝到主机的 ~/.bashrc 文件中。
  2. 让文件起效:
    source ~/.bashrc 
  3. 然后就可以在主机中执行PHP命令了:
    [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 ~]#

3.2 Nginx

3.2.1 添加新的站点

新增的 .conf 文件应放在 servers/panel/vhost/nginx/nginx1.21 文件夹下

3.2.2 切换PHP版本

比如切换为PHP7.2,打开 ./servers/panel/vhost/nginx/nginx1.21 下对应的Nginx站点配置文件,找到 include enable-php-74.conf 改成 include enable-php-72.conf 即可
例如:

location ~ [^/]\.php(/|$) {
    ...
    include enable-php-74.conf;
    ...
}

改为:

location ~ [^/]\.php(/|$) {
    ...
    include enable-php-72.conf;
    ...
}

注意:修改了nginx配置文件,使之生效必须要 重启 Nginx 容器 或者 在容器中执行 nginx -s reload

3.2.3 站点根目录挂载

为什么站点根目录在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。 (当然,你也可以指定别的目录)

3.2.4 配置https

  1. ssl 证书存放位置
    ./servers/panel/ssl/nginx/nginx1.21/站点名称/证书
  2. 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_certificate /usr/panel/ssl/nginx/nginx1.21/站点名称/xxx; # 公钥
       ssl_certificate_key /usr/panel/ssl/nginx/nginx1.21/站点名称/xxx; # 私钥
       ...
    } 
  3. 修改完成重启(重载)即可
    # 方式一:重启 docker compose restart 服务ID
    docker compose restart nginx1.21 # 方式二:重载 docker exec 容器ID nginx -s reload
    docker exec nginx1.21 nginx -s reload

3.3 Elasticsearch

3.3.1 Elasticsearch账号密码设置

# 自动生成密码
./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 = {密码}

3.4 Kibana

3.4.1 Kibana连接Elasticsearch问题

elasticsearch.username: "kibana_system或kibana"
elasticsearch.password: "上面Elasticsearch生成的密码"

3.5 Mongo

3.5.1 system.sessions文档没权限访问

授权

db.grantRolesToUser('userName',[{role:"<role>",db:"<database>"}])

// 例如
db.grantRolesToUser('root',[{role:"__system",db:"admin"}])

3.6 Redis

3.6.1 redis 密码问题

当前redis容器是 启用密码 的,默认密码 123456 如需修改密码直接在 .env 文件中找到下面配置项,修改即可

# +--------------+
# mysql6.2
# +--------------+
REDIS_PASSWORD_62=123456

3.7 MySQL

3.7.1 mysql 密码问题

当前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 对应的密码

3.7.2 权限问题

如需修改权限,对照下面命令修改

-- 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'@'%';

4. 关于容器挂载路径权限问题

由于数据卷和日志卷分离的原因,部分容器启动需要对应的权限,然而宿主机上没有与之对应的权限,所以我们直接赋予777权限即可

4.1. mysql

需要给 ./logs/mysql 文件夹赋予权限 chmod -R 777 ./logs/mysql 重启即可

4.2 Elasticsearch

需要给 ./data/elasticsearch./logs/elasticsearch 文件夹赋予权限 chmod -R 777 ./data/elasticsearch ./logs/elasticsearch 重启即可

4.3 Mongo

需要给 ./data/mongo./logs/mongo 文件夹赋予权限 chmod -R 777 ./data/mongo ./logs/mongo 重启即可

4.4 RabbitMQ

需要给 ./data/rabbitmq./logs/rabbitmq 文件夹赋予权限 chmod -R 777 ./data/rabbitmq ./logs/rabbitmq 重启即可

5. 管理命令

5.1. 服务器启动和构建命令

如需管理服务,请在命令后面加上服务器名称,例如:

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                     # 停止并删除容器,网络,图像和挂载卷

6. 其他问题

6.1 compose.sample.yml 文件中 volumes 的 rw、ro详解

众所周知,如果启动容器不使用挂载宿主机的文件或文件夹,容器中的配置文件只能进入容器才能修改,输出的日志文件也是在容器里面,查看不方便,也不利于日志收集,所以一般都是使用参数来挂载文件或文件夹。
而其中的rwro不指定模式,是比较重要的一个环节,关系到宿主机与容器的文件、文件夹变化关系,下面来一一详解

  1. 不指定
    (1)文件:宿主机修改该文件后容器里面看不到变化;容器里面修改该文件,宿主机也看不到变化
    (2)文件夹:不管是宿主机还是容器内修改,新增,删除,都会同步
  2. ro
    (1)文件:容器内不能修改,会提示readonly
    (2)文件夹:容器内不能修改,新增,删除文件夹中的文件,会提示readonly
  3. rw
    (1)文件:不管是宿主机还是容器内修改,都会相互同步,但容器内不允许删除,会提示Devivce or resource busy;宿主机删除文件,容器内的不会被同步
    (2)文件夹:不管是宿主机还是容器内修改,新增,删除都会相互同步

6.2 容器内时间问题

容器时间在.env文件中配置TZ变量,所有支持的时区请查看 时区列表·维基百科 或者 PHP所支持的时区列表·PHP官网

6.3 windows下使用PHP

PHP镜像构建失败的建议将PHP的版本改成apline3.12,否则pecl安装的扩展都会失败,原因

6.4 SQLSTATE[HY000] [1044] Access denied for user ‘你的用户名‘@’%’ to database ‘mysql’

  1. 如果在compose.yml文件中或者docker run -e中,设置并且有且仅有MYSQL_ROOT_PASSWORD这个参数,你将不会出现这个问题
  2. 如果在compose.yml文件中或者docker run -e中,设置了MYSQL_ROOT_PASSWORDMYSQL_ROOT_HOSTMYSQL_USERMYSQL_PASSWORD,并且你的连接不是使用root用户连接的将会出现这个问题
    (1):问题:权限问题(默认只有information_schema这个库的权限)
    (2):解决办法:MySQL数据库远程连接创建用户权限等

6.5 [output clipped, Log limit 1MiB reached] 日志限制达到1MiB

如果在 docker compose build "服务名" 出现了这句话并且构建失败,命令改成 COMPOSE_DOCKER_CLI_BUILD=0 DOCKER_BUILDKIT=0 docker compose build "服务名" 可以看到的错误信息,方便修改

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 3

很赞 :+1: 支持m2芯片的电脑吗

5个月前 评论
小煜 (楼主) 5个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!