盒子
文章目录
  1. 记录用Docker创建一整套 php7+lumen+mysql5.7+openresty 开发环境
    1. 系统环境和Docker环境
    2. OSX Docker的坑
      1. 1. IP
      2. 2. mysql 不能挂载HOST的目录
        1. 附带跟这个问题相关的解决链接
      3. 3. nginx sendfile 文件的乱码
        1. 附带跟这个问题相关的解决链接
    3. 容器划分
    4. 目录卷挂载的最佳实践
    5. mysql php nginx容器
    6. link 容器之间的通信
    7. port 端口
    8. 总结

记录用Docker创建一整套 php7+lumen+mysql5.7+openresty 开发环境

记录用Docker创建一整套 php7+lumen+mysql5.7+openresty 开发环境

系统环境和Docker环境

Docker的版本是1.9.1
Docker-machine的版本是0.0.5

这个版本已经废除了boot2docker命令。改成了通过docker-machine管理虚拟机(一般来说,这个虚拟机我们是不用管的,只需要知道它的IP就可以)

OSX Docker的坑

1. IP

在OSX下面Docker和HOST,隔了一层轻量虚拟机, 所以HOST不能直接访问容器。Docker容器的端口其实是映射的虚拟机上面的,所以访问127.0.0.1(HOST)并没有用。需要通过访问虚拟机的IP才能访问容器.
绿色的IP是虚拟机的IP。或者通过命令 docker-machine ip获得。

2. mysql 不能挂载HOST的目录

运行mysql容器的时候,如果挂载了HOST的目录

1
docker run -v ~/opt:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -it mysql

获报mysqld没有权限。原因就是隔着一层虚拟机,容器没有办法直接改mac本地的文件。在linux系统下面是不会有这个问题的。

解决比较麻烦,修改容器内的用户id,但我尝试修改,并没有效果。
最后我放弃把挂载目录卷,使用容器自己生成在虚拟机上的匿名目录(避免对镜像做太多处理影响到线上)

用inspect输出容器信息,在Mouts一览众可以可到

1
2
3
docker inspect mysql
# 或者只输入Mounts
docker inspect -f '{{.Mounts}}' mysql

附带跟这个问题相关的解决链接

3. nginx sendfile 文件的乱码

目录卷的挂载,导致nginx传输文件的时候产生乱码。表现为浏览器访问时,静态文件最后一行有一串 ????????
就是把nginx的conf配置中的sendfile 改成off
nginx.conf

1
2
3
4
5
6
7
#......
http {
#......
sendfile off;
#......
}
#......

附带跟这个问题相关的解决链接

容器划分

容器分为4个,数据(目录)容器,mysql容器,php容器,nginx容器。
拆分容器方便管理和维护,比如单独升级mysql,就只需要维护mysql的镜像,重启mysql容器即可。这个是公认的最佳实践,就不展开多说了。

目录卷挂载的最佳实践

所有的目录都挂载在数据容器里,其它的容器通过 —volume-from连接数据容器。
数据容器的运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#运行数据容器
docker run --name data \
-v /app/www1:/var/www1 \
-v /app/www2:/var/www2 \
-v /app/conf:/var/conf dataContainer

#运行mysql容器
docker run --name mysql --volumes-from data -e MYSQL_ROOT_PASSWORD=123456 -d mysql

#运行php-fpm容器
docker run --name php-fpm --volumes-from data --link mysql:mysql -d php-fpm

#运行nginx容器
docker run --name nginx --volumes-from data --link php-fpm:php-fpm -p 80:80 -d nginx
  1. 需要注意的是 -v(—volume) 和 —volume-from 两个命令的区别。
    —volume是挂载宿主机的目录卷
    —volume-from是容器之间共享目录卷

  2. 实际上,需要将mysql的目录卷挂载到宿主机上,保证数据的持久化。但是在OSX上这么做会很麻烦(上面提到坑2)。实际生产环境都是linux系统,并不会出现不能挂载的问题,在本地环境我避免麻烦,就没有挂载。

  3. nginx的主配置文件通过 Dockerfile的ADD,写在镜像里,并且添加一个include,引用挂载目录下的子配置文件。
    这样做的好处是,我们可以在mac里用编辑器修改conf中的子配置文件。然后重启nginx容器,即可完成nginx的配置修改和重新启动。而不需要每次都重新构建镜像。比如,当需要添加一个新的网站server,只需要在conf目录下新建文件,完成配置后,重启nginx容器,即可成功添加。

下图是容器和HOST的大致关系图(MAC环境下)

mysql php nginx容器

容器的镜像 最好是用Dockerfile来构建。
关于这些容器的Dockerfile docker Hub 和github上很容器就能找到合适的。再根据自己的需求修改即可,这部分内容就不详述了。

容器之间的通信,大部分时候只需要单项的通信。通信之后,在各种配置中,就能够通过容器名直接连接。
例如
nginx.conf

php连接mysql(lumen框架的数据库配置文件 .env )

—link 的作用就是在容器内的/etc/hosts 文件中添加一个指向目标容器的ip
如下图所示

port 端口

只有nginx容器需要暴露端口,即 -p 80:80 -p 443:443
-p的作用就是把容器的端口映射到宿主机上。在MAC上,就是映射虚拟机上。

总结

mac上用docker坑还是不少的。不过经过几天的爬坑,越发的觉得统一一个环境,对开发和运维都很有好处。
总的来说,docker还是非常强大的,前期的爬坑是必不可少的技术投资。

最后附上学习和管理docker时最常用的命令

1
2
3
4
5
6
7
8
9
10
11
#构建镜像不使用缓存
docker build -no-cache ...

#删除全部的容器
docker rm -fv $(docker ps -a -q)

#进入运行中的容器
docker exec -it 容器名字 /bin/bash

#查看所有的目录卷
docker volume ls