MySQL Docker 配置文件挂载 问题

跨虚拟机Docker环境下,拉起MySQL挂载磁盘是,估计大家都会遇到的问题

问题

Docker 拉起官方的 MySQL容器,指定使用挂载的配置文件时,报错如下:

mysql: [Warning] World-writable config file '/etc/mysql/conf.d/mysql.cnf' is ignored.

解决否

已解决

方案

这其实是 Docker 在 Windows 下的坑! 当然了 Docker for Mac 也遇到同样的问题。

这牵涉到MySQL对配置文件的可见性安全性的一个要求。MySQL希望它的配置文件是不可编辑的,可查看不可写的。所以就需要配置对应的umask 0555.

以上问题在特定环境下才会暴露出来。我这边是 Mac OS从宿主机的磁盘一路挂载到vbox,再挂载到Docker,垮了3个环境。为了方便,我直接umask就是 0777。

因为需要在宿主机上编辑代码,Docker环境内运行测试代码。

Windows 上环境我也试过,宿主机挂载到vbox,vbox里装了一个Ubuntu虚拟机,虚拟机内安装了Dcoker,也是跨了3个环境,Windows的磁盘和Linux的权限管理是两套体系,所以umask就直接在vbox上配置了。

那么现在MySQL容器需要的是 0555 权限,我尝试在Ubuntu虚拟机中将挂载的目录的访问权限改为 0555,但没有成功,改不动。

具体原因没有深究, 网上也查阅了很多方案,都试了没成功,接下来是我自己摸索出来方案。

我的解决方案是这样:

把同一个目录在vbox里面的Ubuntu虚拟机内挂载了两次,也就是同一个文件夹挂载了两个文件夹,然后两个文件夹的umask 不一样。

配置如下:

sudo mount -t vboxsf -o umask=000,dmode=777,fmode=777 Jumei /mnt/vbox
sudo mount -t vboxsf -o umask=222 Jumei /mnt/ro-vbox

这样,你挂载代码啊,MySQL的数据目录/var/lib/mysql/,就挂载0777目录——/mnt/vbox下,当需要挂载只读配置文件时,Docker volume就挂载 /mnt/ro-vbox 目录,这样就满足了配置文件只读,数据文件读写的配置要求。

以下是样例:

file: ./docker-compose.yaml

version: "2"
    mysql:
        image: mysql:5.7
        ports:
            - "3306:3306"
        volumes:
            - /mnt/ro-vbox/compose/bs/config/mysql/my.cnf:/etc/mysql/my.cnf:ro
            - /mnt/ro-vbox/compose/bs/config/mysql/conf.d:/etc/mysql/conf.d:ro
            - /mnt/vbox/compose/bs/mysql/:/var/lib/mysql/:rw
            - /mnt/vbox/compose/bs/log/mysql/:/var/log/mysql/:rw
        environment:
            MYSQL_ROOT_PASSWORD: "123456"
        networks:
            tasker_net:
                ipv4_address: "192.168.0.6"

PHP拓展 mysql、mysqli、pdo_mysql 区别与选择

今天是2020年,PHP连接MySQL有什么接口呢?还在用mysql函数?试试mysqli、pdo_mysql吧?那mysqli和pdo_mysql又有什么异同呢?来看看

PHP_mysql

PHP-MySQL 是 PHP 操作 MySQL 资料库最原始的 Extension

为了让自己强大起来,mysql 自己为安全也做了很多努力。以前例的 SQL 叙述来说,在sql 语句中使用 变量 直接拼接 的地方容易被 SQL Injection。后来于是发展出了 mysql_escape_string() (备注:5.3.0之后弃用) 以及
mysql_real_escape_string()解决此问题。

php_mysqli

PHP-MySQLi 的 i 代表 Improvement ,提更了相对进阶的功能,就 Extension 而言,本身也增加了安全性.

MySQL增强扩展,可以用于使用 MySQL4.1.3或更新版本中新的高级特性。其特点为:面向对象接口 、prepared语句支持、多语句执行支持、事务支持 、增强的调试能力、嵌入式服务支持 、预处理方式完全解决了sql注入的问题。不过其也有缺点, 就是只支持mysql数据库。如果你要是不操作其他的数据库,这无疑是最好的选择。

PDO_mysql

其功能类似于JDBC、ODBC、DBI之类接口。

PDO是PHP5.1之后才支持的,他为访问数据库采用了一致性的接口,有非常多的操作却是MySQL扩展库所不具备的:

1). PDO真正的以底层实现的统一接口数库操作接口
2). PDO支持更高级的DB特性操作,如:存储过程的调度等,mysql原生库是不支持的.
3). PDO是php官方的PECL库,兼容性稳定性必然要高于MySQL Extension,可以直接使用 pecl upgrade pdo 命令升级

过渡

那我自己举例,我最早接触的就是php_mysql 拓展,就是一个个的函数,封装一下就面向对象了。后来又听人说mysqli更好,更安全。发现从mysql过渡到mysqli,就是find mysql, repalce mysqli 这么简单。而PDO呢,对外提供的是完全的面向对象的API,而我们mysqli 同时对外暴露了 函数式和 面向对象 API。所以,你用mysqli面向对象那种方式,再切换到PDO 也很容易。

用PDO的好处是,PDO支持多种数据库,而MySQLi只支持MySQL,一但你掌握了就你可以使用连接多种数据库。

bind

php_mysql不能 Bind Column ,以前例的 SQL 叙述来说,$location 的地方容易被 SQL Injection。后来于是发展出了 mysql_escape_string() (备注:5.3.0之后弃用) 以及 mysql_real_escape_string()来解决这个问题,不过这麽一搞,整个叙述会变得複杂且丑陋,而且如果栏位多了,可以想见会是怎样的 情形.

在 PHP-MySQLi 中有了不少进步,除了透过 Bind Column 来解决上述问题,而且也多援 Transaction, Multi Query ,

并且同时提供了 Object oriented style (下面这段 PHP-MySQLi 范例的写法) 和 Procedural style

直观对比

特性、指标 PHP的mysqli扩展 PDO (使用PDO MySQL驱动和MySQL Native驱动) PHP的mysql扩展
引入的PHP版本 5.0 5.0 3.0之前
PHP5.x是否包含
MySQL开发状态 活跃 在PHP5.3中活跃 仅维护
在MySQL新项目中的建议使用程度 建议 建议 不建议
API的字符集支持
服务端prepare语句的支持情况
客户端prepare语句的支持情况
存储过程支持情况
多语句执行支持情况 大多数
是否支持所有MySQL4.1以上功能 大多数
参数命名 不支持 支持 不支持
API 编程范式 OOP + 函数式 OOP 函数式
对象映射(Object Mapping) 不支持 支持 不支持

结语

其实从php_mysql, mysqli,pdo_mysql 得过渡就可以看到php自己的设计哲学,不要以很强硬的方式推倒以前的,要慢慢过渡,设计规则让用户慢慢适应。php_mysql->mysqli->pod_mysql, 从过程编码到过程和OOP兼得的mysqli,再到纯OOP的pdo_mysql. 慢慢得大家都用pdo了,mysql也淡出了php的版本。

MySQL 查询优化,explain 各个字段指标说明

MySQL explain 优化sql时,你知道 select_type, type, possible_keys, key, key_len,ref, row, Extra 这些个字段是代表什么意思?那就来看看吧

explain

别名:desc

例子些

  • 例子1:
select * from `tuanmei_deals` where deal_id = 23421;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tuanmei_deals const PRIMARY PRIMARY 4 const 1 NULL

例子2:

select * from `tuanmei_deals` where ( `end_time` > '1592234464' ) limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tuanmei_deals range end_time end_time 4 NULL 234142 Using index condition; Using MRR
  • 例子3:
select * from `tuanmei_deals` where hash_id = 'ht2020517p51688' or ( `end_time` > '1592234464' ) limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tuanmei_deals index_merge hash_id,end_time,idx_HashId_StartTm hash_id,end_time 32,4 NULL 234143 Using sort_union(hash_id,end_time); Using where

id, table

Id 就不说了,table就是你查阅了哪个表,key就是实际用到的索引

select_type

查询类型,就是我们从sql语法角度来看,会被拆封成什么任务

(1) SIMPLE(简单SELECT,不使用UNION或子查询等), 比如上面的一个单表查询

(2) PRIMARY(查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)

(3) UNION(UNION中的第二个或后面的SELECT语句) 如果你使用了union了多个select 集合

(4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)

(5) UNION RESULT(UNION的结果)

(6) SUBQUERY(子查询中的第一个SELECT), 例如你用到了 where in (select )

(7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,取决于外面的查询)

(8) DERIVED(派生表的SELECT, FROM子句的子查询)

(9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

type

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

index: Full Index Scan,index与ALL区别为index类型只遍历索引树

range:只检索给定范围的行,使用一个索引来选择行

ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。触发条件:只匹配到一行的时候。除了system和const之外,这是最好的连接类型了。当我们使用主键索引或者唯一索引的时候,且这个索引的所有组成部分都被用上,才能是该类型。

const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system。system的触发条件:表只有一行,这是一个const type 的特殊情况。

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

possible_keys

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

key列显示MySQL实际决定使用的键(索引)

key

如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

不损失精确性的情况下,长度越短越好。

key_len 表示一行数据该索引占用的数据宽度,比如对一个 字段类型为 int 建立索引,那么索引的key_len 就是 4。和数量多少没有关系。

ref

显示索引的哪一列被使用了,如果可能的话,是一个常数

表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

rows

表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数, 注意:这是预估值,非实际值

Extra

该列包含MySQL解决查询的详细信息

  • Using index:表示使用索引,如果只有 Using index,说明他没有查询到数据表,只用索引表就完成了这个查询,这个叫覆盖索引。如果同时出现Using where,代表使用索引来查找读取记录, 也是可以用到索引的,但是需要查询到数据表。
  • Using where:表示条件查询,如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现 Using where。如果type列是ALL或index,而没有出现该信息,则你有可能在执行错误的查询:返回所有数据。
  • Using MRR:MMR全称是Multi-Range Read,是MYSQL5.6优化器的一个新特性,在MariaDB5.5也有这个特性。优化的功能在使用二级索引做范围扫描的过程中减少磁盘随机IO和减少主键索引的访问次数。将随机IO转换为顺序IO
  • Using filesort:不是“使用文件索引”的含义!filesort是MySQL所实现的一种排序策略,通常在使用到排序语句ORDER BY的时候,会出现该信息。
  • Using temporary:表示为了得到结果,使用了临时表,这通常是出现在多表联合查询,结果排序的场合。

MRR和没有MRR的区别

给出一个简单的例子,在innodb表执行下面的查询:

SELECT non_key_column FROM tbl WHERE key_column=x

在没有MRR的情况下,它是这样得到结果的:

1.  select key_column, pk_column from tb where key_column=x order  by key_column ---> 假设这个结果集是t2.  for each row in t ; 
select non_key_column from tb where pk_column = pk_column_value。(在oracle里第2步叫回表)在有MRR的情况下,它是这样执行的:
1.  select key_column, pk_column from tb where key_column = x  order by key_column ---> 假设这个结果集是t
2.  将结果集t放在buffer里面(直到buffer满了),然后对结果集t按照pk_column排序 ---> 假设排序好的结果集是t_sort
3.  select non_key_column fromtb where pk_column in (select pk_column from t_sort)

两者的区别主要是两点:

  1. 没有MRR的情况下,随机IO增加,因为从二级索引里面得到的索引元组是有序,但是他们在主键索引里面却是无序的,所以每次去主键索引里面得到non_key_column的时候都是随机IO。(如果索引覆盖,那也就没必要利用MRR的特性了,直接从索引里面得到所有数据)

  2. 没有MRR的情况下,访问主键索引的次数增加。没有MRR的情况下,二级索引里面得到多少行,那么就要去访问多少次主键索引(也不能完全这样说,因为mysql实现了BNL),而有了MRR的时候,次数就大约减少为之前次数t/buffer_size。

关于 Explain 的相关注意事项

总结:
– • EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
– • EXPLAIN不考虑各种Cache
– • EXPLAIN不能显示MySQL在执行查询时所作的优化工作
– • 部分统计信息是估算的,并非精确值
– • EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。

show profile

show profile作用:
能够查出最近15条SQL语句的运行状态(包含运行过程中执行了哪些操作,各占用了多长时间),以便开发者的分析。

1、查看MySQL的版本是否支持show profie
2、查看是否已经开启show profile

$ SHOW VARIABLES LIKE 'profiling';

3、开启功能,默认是关闭
SET profiling=ON;
SHOW VARIABLES LIKE ‘profiling’;

4、运行sql
随便运行几条SQL,以便于show prifiles的日志分析。
5、查看结果
show profiles;

6、诊断SQL
用于单独分析某条sql,查看某条sql的生命周期以及各占用多少时间。
SHOW PROFILE cpu, block io FOR QUERY id;
id为show profiles查出来的某条记录的id


set profiling=1; //打开分析 run your sql1; run your sql2; show profiles; //查看sql1,sql2的语句分析 show profile for query 1; //查看sql1的具体分析 show profile ALL for query 1; //查看sql1相关的所有分析【主要看i/o与cpu,下边分析中有各项意义介绍】 set profiling=0; //关闭分析

引用

  • https://mengkang.net/1124.html
  • https://www.cnblogs.com/fu-yong/p/8496368.html
  • https://www.cnblogs.com/kubidemanong/p/10734045.html
  • https://blog.csdn.net/liang_0609/article/details/44040357
  • https://zhuanlan.zhihu.com/p/100427746
  • https://blog.csdn.net/mingover/article/details/79066064
  • https://www.tuicool.com/articles/ZFrUzia
  • https://blog.csdn.net/lihuayong/article/details/42044593
  • https://www.cnblogs.com/xuanzhi201111/p/4175635.html

Docker快速搭建一套PHP、Nginx、MySQL、Redis、Xdebug、Memcached 开发环境并演进

又来一个新项目,又要配置一套新环境,什么你继续用原来的,不怕互相干扰么。来看看这,一步拉起一套全新的Docker,PHP,Nginx,Redis,MySQL,Memcached开发环境

痛点

如何简单迅速地初始化一个全新的PHP开发环境呢?

笔者在尝试起一个新web项目时,往往会陷入重新建立一套Docker环境的繁琐事当中。我想大家在开始做一个新项目时,或者快速为了和以前的项目做完全的隔离,也会起一套新docker环境。

从这篇文章你会得到

采用docker-compose容器编排技术,一步启动全部服务。php容器在官方的基础上还打包了一些常用拓展(附带build源码,动手能力强可以自己打包),php,nginx,mysql都附带有自定义配置文件(便于开发测试的配置调整),都供下载。

架构

本片文章搭建出来的环境如上图。

环境说明

运行环境

  • Mac OS 10.13.6
  • Virtual Box 5.2.14
  • Ubuntu 16.04.4
  • Docker 17.07.0-ce

容器

  • Nginx 1.12.1-alpine
  • PHP-fpm 5.6
  • MySQL 5.7
  • Redis 3.2
  • Memcached 1.4.27

这里说明一下笔者运行环境,采用了在Mac机上安装vbox虚拟机,在虚拟机里面的debian环境安装了Docker环境,文件放在Mac环境,通过文件挂载方式,达到Mac环境编辑,Docker环境实时更新效果。你要问为啥不在Mac下直接装Docker,历史原因~

运行材料

.
├── build                                   ## docker 镜像build 材料
│   ├── php5.6                              ## php 5.6
│   │   ├── Dockerfile
│   │   ├── imagick-3.4.3.tgz
│   │   ├── memcached-2.2.0.tgz
│   │   ├── redis-4.0.2.tgz
│   │   ├── sources.list
│   │   └── xdebug-XDEBUG_2_5_5.tar.gz
│   └── php-cli                             ## php cli 的自建镜像
│       ├── amqp-1.9.3.tgz
│       ├── Dockerfile
│       ├── Dockerfile-php-swoole
│       ├── memcached-3.0.4.tgz
│       ├── redis-4.1.1.tgz
│       ├── sources.list.jessie
│       ├── swoole-4.0.4.tgz
│       ├── swoole-4.2.6.tgz
│       ├── xdebug-2.6.1.tgz
│       └── yaf-3.0.7.tgz
├── config                                  ## 配置文件
│   ├── apt                                 ## 由于使用的debian系列,所以命名apt
│   │   └── sources.list                    ## 更新为国内源
│   ├── memcached                           ## memchached的配置
│   │   └── memcached.conf
│   ├── mysql                            ## mysql 的配置
│   │   ├── conf.d
│   │   │   └── mysqld_safe_syslog.cnf
│   │   └── my.cnf
│   ├── nginx                            ## nginx 的配置
│   │   ├── conf.d
│   │   │   ├── default
│   │   │   └── xiuno
│   │   ├── mime.types
│   │   ├── nginx.conf
│   │   └── sites-enabled
│   ├── php                            ## php的配置,分cli,和fpm配置
│   │   ├── cli
│   │   │   ├── conf.d
│   │   │   │   ├── 05-opcache.ini
│   │   │   │   ├── 10-pdo.ini
│   │   │   │   ├── 20-curl.ini
│   │   │   │   ├── 20-gd.ini
│   │   │   │   ├── 20-imagick.ini
│   │   │   │   ├── 20-json.ini
│   │   │   │   ├── 20-memcache.ini
│   │   │   │   ├── 20-mysqli.ini
│   │   │   │   ├── 20-mysql.ini
│   │   │   │   ├── 20-pdo_mysql.ini
│   │   │   │   ├── 20-readline.ini
│   │   │   │   ├── 20-redis.ini
│   │   │   │   ├── 20-xdebug.ini
│   │   │   │   └── swoole.ini
│   │   │   └── php.ini
│   │   ├── fpm
│   │   │   ├── conf.d
│   │   │   │   ├── docker.conf
│   │   │   │   ├── www.conf
│   │   │   │   └── zz-docker.conf
│   │   │   ├── docker-php-fpm.conf
│   │   │   ├── php-fpm.conf
│   │   │   ├── php.ini
│   │   │   └── pool.d
│   │   │       └── www.conf
│   │   └── mods-available
│   │       ├── curl.ini
│   │       ├── gd.ini
│   │       ├── imagick.ini
│   │       ├── json.ini
│   │       ├── memcache.ini
│   │       ├── mysqli.ini
│   │       ├── mysql.ini
│   │       ├── opcache.ini
│   │       ├── pdo.ini
│   │       ├── pdo_mysql.ini
│   │       ├── readline.ini
│   │       ├── redis.ini
│   │       └── xdebug.ini
│   └── redis                            ## redis 配置
│       ├── redis.conf
│       ├── redis-server.sh
│       └── sentinel.conf
├── data                                ## 为了数据持久化
│   ├── mysql                            ## mysql 文件挂载
│   └── redis                            ## redis 持久化数据文件夹
├── docker-compose.yaml                 ## 容器编排 !!!
├── log                                 ## 各个容器产生的日志
│   ├── mysql                            ## mysql日志
│   │   ├── error.log
│   │   └── mysql.log
│   ├── nginx                            ## nginx 日志
│   │   ├── access.log
│   │   ├── access_xiuno.log
│   │   ├── error.log
│   │   └── error_xiuno.log
│   └── php
├── php                                    ## php代码存放目录
│   └── xiunobbs                            ## php项目
└── tool                                ## php 一些工具
    ├── composer.phar
    └── phpunit-4.8.36.phar

配置文件下载

git clone https://gitee.com/xupaul/docker_fast_init

配置说明

目前笔者还没有写相关自动化脚本自动适配用户的使用环境,所以这里需要先调整一下下载后的配置文件。

docker-compose.yml 文件调整

这个文件有大量的文件挂载配置,这块就需要调整,拿一个举例。

version: "2"

services:

    http:
        image: nginx:1.12.1-alpine
        volumes:
            - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:rw
        ports:
            - "8080:80"
        environment: 
            TZ : "Asia/Shanghai"
        networks:
            tasker_net:
                ipv4_address: "192.63.0.11"

在例子中最后volumes的下一行,是将宿主机的nginx.conf配置文件挂载并覆盖容器内的nginx.conf文件,./文件路径就是clone git项目后的目录。

如果你也使用了vbox虚拟机,那么你需要./要替换为docker的运行环境的路径!

ports这里,http服务为了不和本机的80端口冲突,以及sudo权限才能申请的小于1024的端口,这里我以8080作为默认值。其他容器的端口配置也遵循以上的规则,为的是能一个命令就能启动起来。

为每个容器都配置了时区。

网络ip这部分,为了便于配置就手动分配ip了。

Nginx 配置

配置好了php-fpm之间tcp通讯,以及php路由的rewrite。配置了静态资源缓存。

MySQL 配置

开启记录了一般性的查询日志,便于debug程序。注意这里挂载的配置文件读写权限要配置只读!

PHP 配置

    php:
        image: paulxu/php:5.6-fpm-jessis-pdo-xdebug-mysqli-gd-mb-zip-2
        volumes:
            - ./config/php/cli/php.ini:/usr/local/etc/php/php.ini/:rw
        ports:
            - "9000"
        environment: 
            PHP_IDE_CONFIG: "serverName=bs"
            XDEBUG_CONFIG: "remote_host=10.0.2.2 remote_port=9000"

我为php一起打包了一些常用拓展,其中xdebug需要调整一下remote_host的的ip(docker-compose.yaml, ~/config/php/cli/20-xdebug.ini 两个文件内的都需要调整). server_name 需要结合开发IDE一起调整,如PHPStorm里Preferences | Languages & Frameworks | PHP | Servers配置路径下有什么可用的记录,那么这里填什么。

Redis 配置

没有特殊配置

Memecached 配置

没有特殊配置

镜像构建

php镜像

可以通过如下命令拉取:

docker pull paulxu/php:5.6-fpm-jessis-pdo-xdebug-mysqli-gd-mb-zip-2

或者在到 ~/build/php5.6 下自行打包:

docker build -t paulxu/php:5.6-fpm-jessis-pdo-xdebug-mysqli-gd-mb-zip-2 -f dockerfile .

如果自定义tag name,需要一并调整docker-compose.yml

启动

  1. 从gitee下载配置
  2. 根据自己的环境调整配置
  3. 准备好镜像,镜像也可直接拉,我已上传了官方了。
  4. 启动

启动命令

## 当前线程运行,要停止时,键入`Ctrl+C`
docker-comose -f ./docker-compose.yaml up

## 后台运行
docker-comose -f ./docker-compose.yaml up -d

摧毁

docker-comose -f ./docker-compose.yaml down

常见问题

MySQL 挂载的配置文件被忽略,不起作用

MySQL 要求配置文件的权限为只能读,你需要已只读方式挂载

不知道remote_host怎么办

禁用xdebug,搭建好环境并启动,在IDE运行的环境(因为xdebug需要和IDE通讯)访问以http(在浏览器访问,注意端口映射)的方式访问php容器内代码,在Nginxaccess.log里查看访问的ip就是remote_host.

docker build 时报错导致打包镜像失败

遇到这种情况,如果时一些不要紧的报错,可以选择忽略他们。可以在命令后面追加 exit 0 来屏蔽错误

最后

祝愿大家能一步到位,有问题留言,遇到疑难杂可以试试本地起虚拟机里跑docker容器的那种方案。