GITHUB地址:https://github.com/banyancheung/base-docker-envphp
这是一份适用于生产和开发环境的 Dockerfile。 在 phuison/baseimage 的基础上,增长了php、php扩展和nginx的安装脚本, 实现了一键安装LNP及其经常使用扩展的功能。目前已经在我司的生产环境上并运行良好。平常开发中也是基于此镜像进行的。mysql
此镜像包括以下内容:nginx
以上这部份内容请移步到 这里 查看注释。git
以上安装脚本分别在 build/php_7.1.18.sh
和 build/nginx_1.12.2.sh
中。github
APT这块使用了清华大学的ubuntu安装源。 此部分代码可在 build/prepare.sh
中找到。web
使用基于docker的开发和生产环境须要你有基础的docker知识。这里假设你已经了解镜像,容器,以及容器编排的一些概念而且实际使用过。redis
git clone
此仓库,在 Dockerfile 所在的目录执行命令:sql
docker build -t='[ImageName]:[Tag]' . // [ImageName] 为你想要的镜像名称,若是不想标识版本,请忽略:[Tag]。可是别忽略了"."
而后等待构建成功便可。整个安装过程约10-15分钟,取决于你当前所在的网络环境。mongodb
若是不想构建,也可使用我已经打包好的在线仓库。docker
docker pull ccr.ccs.tencentyun.com/qyy-base/qyy-php:1.1.0
经过构建或者在线拉取镜像到本地后,使用 docker images
查看该镜像信息。整个镜像大小为957MB,运行时占用内存约300M。
若是想快速看看镜像里有啥东西,只须要运行:
docker run --rm -it [ImageID] /sbin/my_init -- bash -l // 其中ImageID替换成你实际的镜像ID。
该命令建立容器并启动了shell,进入交互模式。请注意:镜像里面并无运行任何咱们想要的服务(如php和nginx),只是启动了系统并执行了系统的初始化流程。
单独运行这个容器是没有意义的。由于这里面没有任何你的业务代码,也没有任何咱们想要的服务。
下面来看看如何运用在开发环境中:
一个完整的开发环境应当包含数据库、缓存与web服务。该镜像已经包含了nginx,因此咱们只须要把其余的服务跑起来便可。这里使用到了 docker-compose
把该镜像与其余服务连接起来并运行.
咱们应该有一个目录专门放这些配置文件,假设有个目录叫 docker-dev,它的目录结构大概是这个样子:
docker-dev 部署目录 ├─mysql 数据库配置目录 │ ├─my.cnf 公共模块目录(可更改) │ ├─conf.d 模块目录(可更改) │ │ ├─my5.6.cnf 模块配置文件 │ │ ├─mysqld_safe_syslog.cnf 模块函数文件 │ │ └─ ... 更多类库目录 ├─nginx Nginx配置目录 │ ├─nginx.conf 要覆盖的nginx.conf ├─php PHP配置目录 │ ├─php-fpm.conf 要覆盖的php-fpm conf │ ├─php-fpm.ini 要覆盖的php-fpm.ini │ ├─php.d 扩展配置目录 │ │ ├─xdebug.ini 要启用 Xdebug,在该ini文件里填入 `zend_extension=xdebug.so` ├─redis 缓存配置目录 │ ├─redis.conf 要覆盖的redis.conf ├─docker-compose.yml docker-compose 编排文件 ├─game.sh 业务启动脚本 ├─game.conf 业务的web配置
假设个人业务代码在 /d/WWW/gamer/game
,是一个基于yii2的php项目。
先来看 docker-compose.yml
,注意看注释:
version: '2' services: php: restart: always image: ccr.ccs.tencentyun.com/qyy-base/qyy-php:1.1.0 container_name: game volumes: - /d/WWW/gamer/game:/home/worker/data/www/game # 将宿主机的代码目录映射到容器的www目录 # ... 若是有更多的开发中业务代码,一并放到这里并映射到容器 - ./php/php-fpm.ini:/home/worker/php/etc/php-fpm.ini # 用开发配置覆盖容器里的fpm配置 - ./php/php-fpm.conf:/home/worker/php/etc/php-fpm.conf # 同上 - ./php/php.d/xdebug.ini:/home/worker/php/etc/php.d/xdebug.ini # 开发环境开启xdebug。 - ./nginx/nginx.conf:/home/worker/nginx/conf/nginx.conf # 用开发配置覆盖容器里的nginx配置文件 - ./game.conf:/home/worker/nginx/conf.d/game.conf # 业务的nginx配置。 - ./game.sh:/etc/my_init.d/game.sh # 业务的启动配置,通常是启动php-fpm和nginx,也能够按需写其余执行脚本 # 若是有更多的业务须要自定义脚本或者web,在这里添加 ports: - "80:80" networks: - new depends_on: - redis - memcached - mysql extra_hosts: - "gameapi.cc:192.168.1.9" # 将一个用于开发的虚拟域名指向到宿主机的IP。 redis: restart: always image: registry.cn-hangzhou.aliyuncs.com/qyyteam/redis:1.0.0 ports: - "6379:6379" volumes: - /d/persistent/redis:/data # 左边的目录是我宿主机上的持久化redis存储目录,这里换成本身的。 - ./redis/redis.conf:/usr/local/etc/redis/redis.conf # 用开发配置覆盖redis容器里的配置 networks: - new container_name: redis memcached: restart: always image: registry.cn-hangzhou.aliyuncs.com/qyyteam/memcached:1.0.0 ports: - "11211:11211" networks: - new container_name: memcached mysql: image: registry.cn-hangzhou.aliyuncs.com/qyyteam/mysql:5.6 restart: always ports: - "3306:3306" volumes: - ./mysql/my.cnf:/etc/mysql/my.cnf - ./mysql/conf.d:/etc/mysql/conf.d - /d/server/MySql/data:/var/lib/mysql # 左边的目录是我宿主机上的持久化Mysql存储目录,这里换成一个全新的或者已经存在的数据库目录。 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_USER=root - MYSQL_PASSWORD=root networks: - new container_name: mysql networks: new:
如上所示,咱们有php+nginx服务,redis服务、memcached服务,mysql服务。这些服务被编排在一块儿,合成了一个完整的开发环境。(固然若是你的技术栈不是这样或者版本不对,能够换成本身的。这须要你有点动手能力:) )
再来看一下 game.sh
:
#!/bin/sh set -e mkdir -p /home/worker/data/php/logs/xdebug # start nginx,php-fpm setuser worker /home/worker/php/sbin/php-fpm -c /home/worker/php/etc/php-fpm.ini /home/worker/nginx/sbin/nginx
在docker-compose.yml文件里,它被映射到了 /etc/my_init.d/
目录。在启动容器的时候该目录下的shell文件会按文件名顺序执行。
该脚本初始化了一个目录,而且启动了 php-fpm
和 nginx
用于接收访问。
最后在docker-compose.yml所在的目录中,命令输入:
docker-compose -p dev up -d
便启动了全部服务。就是这么简单!最重要的是,它是一个统一的、可维护的、可在团队内普及推广的开发环境!
PS:这个例子的全部代码会在 example/docker-game-dev
中。
请注意:根据本身实际须要,修改docker-compose.yml或其余服务如Mysql,redis的配置项,这只是一个例子,千万不要复制粘贴直接用。
其实若是是小公司,业务量不大而且是单机的话,上面的方法里只须要将配置变量改为生产环境的就能直接用。
但若是:
就必须把你的业务代码打包成一个镜像了。仍是假设项目目录为 /d/WWW/gamer/www, 在该目录下新建一个 Dockerfile
:
FROM ccr.ccs.tencentyun.com/qyy-base/qyy-php:1.1.0 MAINTAINER banyan.cheung@gmail.com # source codes RUN mkdir -p /home/worker/data/www/game COPY . /home/worker/data/www/game # startup scripts COPY docker/game.sh /etc/my_init.d/game.sh RUN chmod +x /etc/my_init.d/game.sh # php-fpm configs COPY docker/php-fpm.ini /home/worker/php/etc/php-fpm.ini COPY docker/php-fpm.conf /home/worker/php/etc/php-fpm.conf # logrotate COPY docker/nginx /etc/logrotate.d/nginx COPY docker/php-fpm /etc/logrotate.d/php-fpm RUN chmod 644 /etc/logrotate.d/nginx RUN chmod 644 /etc/logrotate.d/php-fpm EXPOSE 80
这个Dockerfile继承了基础镜像,还作了它独有的其余事情:
logrotate
每隔一段时间分割nginx和php产生的日志文件相信你已经触类旁通了————每个独立的业务代码都应该像这样构建属于本身的镜像。构建成功后,就能方便的进行分布式部署和CI && CD了。
虽然我已经尽量考虑到各类状况,可是每一个公司每一个团队的状况都不同,适用个人不必定适用于你。这里我列出一些在镜像里你可能须要了解的地方,以方便你进行定制:
/home/worker/data
目录是数据目录,这里面放一些诸如你的代码、日志的东东。
/home/worker/data/www
是固定的web目录。固然你能够在 config/php/etc/php-fpm.ini 中修改它。
下面是一些固定的文件路径:
/home/worker/data/php/logs/php_errors.log
php的错误日志
/home/worker/data/php/logs/opcache_errors.log
opcache 错误日志
/home/worker/data/php/run/php-fpm.pid
php pid 地址。
/home/worker/data/php/logs/php-fpm.log
php-fpm 日志。
/home/worker/data/php/logs/www.access.log
access log
以上这些均可以在 config/php/etc/php-fpm.ini 和 config/php/etc/php-fpm.conf 中修改。
php 安装在 /home/worker/php
中。打开它你会发现熟悉的php安装目录。
nginx 安装在 /home/worker/nginx
中。conf目录是 /home/worker/nginx/conf.d/
若是须要使用 logrotate
, 请写一个配置文件在Dockerfile里COPY到 /etc/logrotate.d/
,并将权限修改成644。这里是一个例子:
/etc/logrotate.d/nginx
/home/worker/data/nginx/logs/*.log { daily missingok rotate 7 compress delaycompress notifempty dateext postrotate if [ -f /home/worker/data/nginx/logs/nginx.pid ]; then kill -USR1 `cat /home/worker/data/nginx/logs/nginx.pid` fi endscript }
定时任务能够写shell放在 /etc/cron.hourly/
,/etc/cron.daily/
,/etc/cron.weekly/
等文件夹中,系统会根据时间自动执行。 cat /etc/crontab
能够看到系统自带的定时任务设置。
若是能帮到你,请到github给我一颗小星星,谢谢 :)