这世界变化快啊 我刚学会这个 又出新东西了
基于Kubernetes构建Docker集群管理详解
Docker Machine + Compose + Swarm
让Docker功能更强大的10个开源工具
连接容器 –link 简要说明
懒人的最爱 – 下载快速用
为了方便急用的同志们,把仓库和配置方法放在最前面,如果想学习的请往下看
- 仓库地址: https://github.com/elickzhao/docker-study
- 配置方法
- 进入
dockerfiles
目录, 修改配置文件docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36data:
build: ./data
volumes:
- "/c/Users/elick/myapp:/data:rw" #这里修改 '/c/Users/elick/myapp' 为你主机上要共享的目录
privileged: true
mysql:
build: ./mysql
volumes_from:
- data
volumes:
- "/c/Users/elick/myapp/db/mysql:/var/lib/mysql" #这里修改 '/c/Users/elick/myapp' 为你主机上要共享的目录
environment:
- MYSQL_ROOT_PASSWORD=123456 #根据你的需要修改数据库密码
ports:
- "3306:3306" #根据需要修改数据库端口
php:
build: ./php
expose:
- "9000"
volumes_from:
- data
links:
- mysql
privileged: true
nginx:
build: ./nginx
volumes_from:
- data
volumes:
- "/c/Users/elick/myapp/nginx/nginx.conf:/etc/nginx/nginx.conf" #这里修改 '/c/Users/elick/myapp' 为你主机上要共享的目录
links:
- php:php
ports:
- "80:80" #根据需要修改web服务器端口
privileged: true - 使用
docker-composer up
建立并启动容器 - 如果除了data容器 全部启动的话 并且浏览localhost也没错的话 那么你就拥有了最新的php环境了
- 几点需要注意的
- 首先你需要有docker-composer 如果你在windows下 那就下载 docker toolbox 这个默认安装了 linux下的话 我那个仓库里已经下好了
- 把仓库克隆下来 并共享此目录 就是替换
/c/Users/elick/myapp
我这个目录 data容器指向的就是这个目录 指向时一定要是绝对路径 还有就是 windows下 要写虚拟机内的地址 不要写成windows的地址 也就是把此目录已经共享给虚拟机了 因为windows下 容器是运行在虚拟机内的 - 目录结构简单说明下
1
2
3
4
5
6
7
8
9
10
11
12
13myapp
├─db
│ └─mysql #数据保存地址
├─dockerfiles
│ ├─data
│ ├─mysql
│ ├─nginx
│ └─php
├─logs
├─nginx #nginx配置文件放在这里
│ └─conf.d #虚拟主机配置文件
└─www #网站内容
└─public
好快速搭建说到这里,喜欢唠叨的可以往下看.
#下面不用看了 自己弄时的一些记录 估计没人能看懂
心路历程 单一进程容器
大坑无数的nginx
单一进程容器,也就是一个服务放在一个容器里
Nginx dockerfile
1 | # Apply Nginx configuration |
执行命令建立镜像并启动容器
1 | $ docker build -t elick/nginx . |
这个nginx有个问题是php-fpm的ip无法得到 必须启动后手动该nginx.conf才行 以前看那个人家使用nginx-start.sh启动 可是到我这命令始终出错 说找不到文件 而且莫名其妙的在每行结尾有个/r的标 而且用#!/bin/bash定义shell也报错 真天了噜
按道理是 link myapp-php 通过环境变量取得ip 可是就这个shell命令不好使无法进行下去了
-p 80 只是指向 容器端口 host端口是随机的
第一个坑,因为需要连接php容器,所以配置文件里需要php服务器的地址,一开始的解决方法是写个shell文件,读取环境变量,因为link以后容器内会包含php容器的环境变量,但是这个shell死活报错,就是下面说的那个问题.
利用命令行已经成功建城环境,不过用docker-composer就遇到问题了
问题终于解决了 原来是shell脚本文件的问题 windows下编辑的文本放到linux就会有格式问题 具体解决看这里
第二个坑,当时直接把配置文件拷贝到/etc/nginx/nginx.conf 但是每次启动IP都会变化 但是替换变量已经,被替换过了.所以改写了shell 每次都重新复制一遍nginx.conf到/etc/nginx/nginx.conf 然后再去替换才行
第三个坑,在shell不行的时候,想过用dockerfile执行命令 直接替换,于是发现了 RUN,ENTRYPOINT,CMD 三个命令执行的差别 具体看这里(总结 Dockerfile 一些命令说明) 但是ENTRYPOINT 执行时 sed命令却没有 不知道为什么没深入研究
经过上面痛苦的经历,最后找到了办法,原来link后会写个静态地址到hosts,所以根本不用那么麻烦,直接在配置文件里写 服务器名称就ok 这个名称就是 –link myapp-php:php 后面php这个别名 具体说明看这里连接容器 –link 简要说明
坑少了不少的 php
1 | FROM php:fpm |
有link 那么 暴露端口其实没用 只要在dockerfile的 EXPOSE 9000 把端口暴露给容器即可 所以没有 -p 9000:9000 暴露端口也没事
1 | $ docker build -t elick/php . #这里可是有个点的啊 |
这里有一个坑,就是扩展php,因为官方镜像竟然没有mysqli 所以没办法只能自己弄,本来都想放弃了,后来还是平心静气看了下鸟语文档,才发现人家已经准备好命令来解决,只不过我只加了mysqli后没有再深入研究了
解决上面的问题mysql就没难度了
1 | FROM mysql |
1 | $ docker build -t elick/mysql . |
以上都搞懂了 其实mysql就没什么了 其他的相加的服务也是一样
$ docker run –name myapp-data -v /c/Users/elick/myapp/:/data:rw -it elick/data
/bin/bash
用php代码 取得容器环境变量 从而能连接到mysql 可以试一下
能够获取环境变量 但是只能获取和自己相关的 因为使用的用户 是php那个用户 也就是 www-data 并不是root 所以没法看到完整的env环境变量
我又个下策 就是建立容器时 用shell把环境变量写到 一个文件里 然后读出来 要不然每次启动 连接数据库 还得改php文件 这有点问题啊
蠢死了 原来这么简单 就像link那篇文章里写的 –link 会写入hosts 那么 –link mysql:mysql 那么就会用这个别名 放到 hosts 这样可以直接用这个别名来当服务器名 也就是网址了
看来想的没错 Nginx 里的ip 也是只要用 php 就可以了 只要yaml里配置的别名是正确的就 哦了
1 | $servername = "mysql"; |
myapp-data 一点小小的问题
使用数据容器 用docker-composer 建立时 容器不会启动 但是共享内容还是好使的 究原因 是因为docker是一次性执行 如果没有挂起任务 就会自动关闭
解决办法 手动建立这个容器 $ docker run --name myapp-data -v /c/Users/elick/myapp/:/data:rw -it elick/data /bin/bash
千万不要用 -d 要不容器还是启动不起来 或者自己写个死循环程序 然后启动时 执行这个程序 但是坏处是 当你关闭容器时 会造成麻烦 具体看这篇文章 通过信号解决docker启动容器后Exited退出的问题
连接mysql居然还需要本地ip才可以 真实麻烦啊
另一种形式的环境 就是把nginx和php放到一个容器里 这样省去了很多麻烦
推荐用这个仓库 这个比较好用一些 https://github.com/skiy-dockerfile/nginx-php7
看来只能使用nginx和php绑定到一起的 因为这样都在同一个服务器 所以使用127.0.0.1 就可以了 而且这种形式也不错 因为根本也没什么必要把他们分开 如有扩展可以前台再加nginx指向这个nginx
过去的总结 这个已经过时了
遇到了好多个坑,为了把php-fpm的ip传给nginx,折腾的要死啊! 使用 –link 虽然nginx容器有了 php容器的环境变量IP地址 但是得把这个IP放到nginx.conf里才行 所以需要做些动作
- 刚开始想放到Dockerfile里 用了
RUN sed -i "s/%fpm-ip%/$PHP_PORT_9000_TCP_ADDR/" /etc/nginx/nginx.conf
但是RUN只在image里 执行也就是说此时容器没有启动 所以环境变量还没有 - 于是乎用了 ENTRYPOINT 这个是可以 但是就是上面提到的 shell错误问题 却一直没往这方面想 所以走了弯路
- 其实还用了 CMD 但是好像并没有 执行命令 还得进入容器启动 不知道为什么 也懒得找了