为什么会想起来用 Docker?
去年听说的 Docker,一开始看介绍没有看明白容器技术能做什么。最近有空再次研究了文档,手动试了试,才弄明白是个啥:一种给需要安装、配置操作系统的人的福音。
我很喜欢安装操作系统、配置环境这种事情。无论是桌面还是服务器,每次遇到一个新的操作系统、一个新的机器、一个新的服务环境,从什么都没有一直配置到可以正常工作,特别有成就感。进度条不断前进,或者编译器不断输出看不懂的 log,总是特别有魔力。
但再喜欢的事情做个 100 遍,也就枯燥无谓了,盯着进度条变得枯燥无味。如果遇到些问题更是让人烦躁,如果是以前解决过的问题,又要 Google 的海洋里游荡一番才能解决。
桌面的操作系统,我现在没有这个问题,因为 Mac 有 TimeMachine,换新机器时,让 TimeMachine 自己跑个 1 小时,还是那个熟悉的环境,只是性能变得更强。
服务器的配置就没有那么幸运,每次还是得 apt-get update, apt-get install,各种 /etc/ 下面的 config 文件倒腾一番。好在现在的云主机供应商都有镜像,配置完了做一个镜像,下次开新机器就很方便。不过也有一些缺点:1. 我不会记得自己对操作系统做了什么操作,安装了什么,修改了什么,有些服务的镜像不能直接使用以前的,相同的问题还得再解决一次;2. 如果使用新云主机功能商的服务,所有的努力得再来一次。
Docker 很好的解决了这个问题。所有配置环境的操作,都放在文本文件中。做了哪些事情一目了然,通过版本管理系统,也能记录每次修改。而且,文本文件很小,使用新的供应商提供的服务时,直接下载安装即可,还是一模一样的环境。
Docker 对性能的影响很小。Docker 的容器,相当于一个独立的操作系统,但是它不是虚拟机,它依然依赖宿主机内核提供的服务,在宿主机的内核上,添加所需要的服务,再提供服务给使用者。
为什么用 Docker 搭建开发环境
最主要的原因,是直接上生产环境有风险,通过搭建开发环境练练手..不过用 Docker 的确能解决一些问题
我见过的 PHP 开发模式有 2 种:
- 本地开发。每个开发人员,在自己的机器上,安装 nginx, php, mysql, redis, etc,配置一番,然后开始开发,将所有工作结果通过版本控制工具合并。这个模式有个问题:大家的环境不一样,因为配置的原因,同样的代码,在不同机器上的表现是不一样的,给开发和 debug 带来不变;
- 集中式开发。用一台服务器,部署一个 nginx, php, mysql, redis, etc,每个开发人员将自己的代码上传到不同的目录,每个人分配一个 vhost,这样大家就能各干各的。优势自然是大家的环境都一样,甚至数据都一样,不太容易出现不同机器上的表现不相同的情况。但也带来了问题;一是服务在一起,数据在一起,会互相影响,比如我要测试一下数据库为空的情况,这时别人就没发工作了;二是开发人员得一直连着网,断网了就没法开发,就算现在网络发达,不会断网了,偶尔得在公司外面开发吧,运维得管理一堆 VPN 账号,也是很麻烦的事情。
现在有了新的思路:用 Docker 搭建开发环境。其实还是第一种,本地开发。用 Docker 解决了大家配置不一致的问题。因为 Docker 的配置文件都是一样的,不需要手动操作,理论上安装出来的环境是一样的。
如何使用 Docker 配置开发环境
首先得安装 docker 和 docker-compose。
docker-compose 让你对 container 做一些简单的配置,并且一个文件就能启动多个不同的服务。
**然后配置 docker-compose.yml **
找个地方放这个文件,下面是配置示例。
version: '2'
services:
nginx:
container_name: nginx
image: nginx
ports:
- 8000:80
volumes:
- /path/to/your/php_code:/path/to/your/code/in/container
- ./nginx/sites/your_site.conf:/etc/nginx/conf.d/your_site.conf
php:
container_name: php_fpm
image: suren_php_fpm:latest
bg-sync:
image: cweagans/bg-sync
volumes:
- /path/to/your/php_code:/source
volumes_from:
- php
environment:
- SYNC_DESTINATION=/path/to/your/code/in/container
- SYNC_MAX_INOTIFY_WATCHES=40000
privileged: true
mysql:
image: mysql:5
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/init.d/:/docker-entrypoint-initdb.d/
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: ergedd
MYSQL_USER: ergedd
MYSQL_PASSWORD: ergedd
pma:
container_name: pma
image: phpmyadmin/phpmyadmin
environment:
- PMA_HOST=mysql
ports:
- 8080:80
redis:
container_name: redis
image: redis:3
volumes:
- ./redis/data:/data
这个文件的说明可以查看说明文档,有些特殊的解释一下:
- bg-sync:Docker 在 Mac 下的共享磁盘,性能有问题,导致 php 运行特别慢,通过 bg-sync 折中一下。也有其他的解决方式,但正如 bg-sync 的说明文档所述,bg-sync 是能 work 里面最简单的一种。
- mysql 中的 /docker-entrypoint-initdb.d/,通过共享文件到这个目录下,可以在 container 第一次被创建时,跑一些初始化脚本,比如倒入初始数据库之类的操作。
- suren_php_fpm:latest:这是我自己做的 php_fpm 镜像,没有使用原版的,因为需要添加 mysql 插件。
有了这个文件后,运行命令 docker-compose up -d
,所有服务就启动起来了,非常方便、整洁。