准备工作

创建Dockerfile

  1. 在用户目录下创建docker项目文件夹
$ mkdir -p ~/docker && cd ~/docker
  1. 创建Dockerfile
$ vim Dockerfile
  1. 由于我们是基于Ubuntu14.04做的镜像,所以定义好官方Ubuntu地址即可,在Dockerfile插入:FROM ubuntu:trusty,保存Dockerfile,然后运行docker build -t ubuntu:14.04-php-nginx .,如果你是第一次运行,需要从上面修改的docker源拉取ubuntu的镜像,会比较久。

  1. 我们用docker images来看结果,会有两个镜像,一个是拉下来的ubuntu:trusty,一个是我们定制的镜像: ubuntu:14.04-php-nginx

  1. 现在我们已经拥有一个本地image,使用交互模式启动容器准备进行定制 docker run -t -i ubuntu:14.04-php-nginx /bin/bash

  1. 把它当成一台装了Ubuntu的虚拟机,该怎么样怎么样,我们准备安装PHP-FPM和Nginx及一些PHP扩展,那么正常命令是这样的:(容器以root用户登录,且默认没有sudo命令,则不需要sudo)
apt-get update 
apt-get install -y nginx nginx php5 php5-fpm php-pear php5-dev php5-redis php5-gd php5-curl php5-mcrypt imagemagick php5-imagick supervisor
pecl install mongo
echo 'extension=mongo.so' > /etc/php5/mods-available/mongo.ini 
ln -s /etc/php5/mods-available/mongo.ini /etc/php5/fpm/conf.d/20-mongo.ini 

漫长的等待时间之后,安装完了 7. 由于默认的系统是UTC时间,我们将它改为CST

rm /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
dpkg-reconfigure -f noninteractive tzdata

成功之后会输出当前的local time

  1. 接下来我们不需要再安装其他软件了,那么可以删掉没有必要的apt缓存:rm -rf /var/lib/apt/list/*
  2. 由于docker是无状态的,且启动时只能保留一条CMD来执行我们要启动的命令,但是我们需要FPM和Nginx都一起启动,怎么办?于是我们通过supervisor来控制,那么我们需要配置supervisor

supervisord配置:/etc/supervisor/conf.d/supervisord.conf

[supervisord]
nodaemon=true 

nginx配置:/etc/supervisor/conf.d/nginx.conf

[program:nginx] 
command=/usr/sbin/nginx 
autostart=true 
autorestart=true 
priority=10'

fpm配置:/etc/supervisor/conf.d/php-fpm.conf

[program:php-fpm] 
command=/usr/sbin/php5-fpm 
autostart=true 
autorestart=true 
priority=5'
  1. 好了,需要的东西都安装配置了,接下来就剩下启动supervisor了,我们把这个命令放在Dockerfile来启动CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]

完整的文件是这样子的

#FROM ubuntu:14.04.05
FROM ubuntu:trusty

# 更换apt源
RUN sed -i 's/http:\/\/archive\.ubuntu\.com\/ubuntu\//http:\/\/cn\.archive\.ubuntu\.com\/ubuntu\//g' /etc/apt/sources.list \
    && apt-get update \
    && apt-get install -y nginx php5 php5-fpm php-pear php5-dev php5-redis php5-gd php5-curl php5-mcrypt imagemagick php5-imagick supervisor \
    && pecl install mongo \
    && rm /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && dpkg-reconfigure -f noninteractive tzdata \
    # remove caches
    && rm -rf /var/lib/apt/lists/* \
    && echo 'extension=mongo.so' > /etc/php5/mods-available/mongo.ini \
    && ln -s /etc/php5/mods-available/mongo.ini /etc/php5/fpm/conf.d/20-mongo.ini \
    # add supervisord conf before CMD
    && mkdir -p /etc/supervisor/conf.d \
    && echo '[supervisord] \nnodaemon=true' > /etc/supervisor/conf.d/supervisord.conf \
    && echo '[program:nginx] \ncommand=/usr/sbin/nginx \nautostart=true \nautorestart=true \npriority=10' > /etc/supervisor/conf.d/nginx.conf \
    && echo '[program:php-fpm] \ncommand=/usr/sbin/php5-fpm \nautostart=true \nautorestart=true \npriority=5' > /etc/supervisor/conf.d/php-fpm.conf

CMD ["/usr/bin/supervisord", "-n", "-c",  "/etc/supervisor/supervisord.conf"]

使用方法

  • git pull 本工程
  • cd 进入docker-compose.yml文件所在目录(如ubuntu14.04)
  • docker-compose up -d,具体用法命令行输入docker-compose --help查看

docker-compose修改

  • 修改ports端口映射
  • 修改目录映射
    • 修改www目录,将自己本机的目录共享给docker镜像
    • 修改log目录,以便不需要ssh进docker镜像也可以查看log

    nginx/php-fpm/supervisor master process user为root,因此可以直接写入/var/log目录 php-fpm的worker process user为www-data(默认),因此将worker的error output设置成(php_errors = /tmp/php_error.log)以写入/tmp 不建议修改系统默认文件夹权限设置,特别是将一些关键目录设置成777或者使用root权限运行程序

  • 修改docker-compose.yml文件完毕之后请运行docker-compose down && docker-compose up -d重新启动建立映射关系

docker交互模式

  • 通过docker-compose up -d进入后台进程,可以使用docker exec -i -t $containerId bash进入交互模式
  • 通过docker ps查看所有运行的docker情况
  • 通过docker-compose ps -q查看当前镜像运行的containerId
  • 直接使用docker exec -it $(docker-compose ps -q) bash进入交互模式
  • 建议添加function到shell以便快速进入sshdocker() { docker exec -it $(docker-compose ps -q) bash}(alias在shell载入时会计算出结果,所以不能用alias)

其他参考

  • 为什么只用一条RUN命令?

每一次RUN都会导致镜像被包装一层,从而有不必要的额外信息被记录,更多详细信息参考:https://yeasy.gitbooks.io/docker_practice/content/image/build.html

  • 有什么要注意的?

supervisor启动的进程不要以daemon形式启动,所以在php-fpm.confnginx.conf都将daemon关闭了,具体详细参数请参考示例工程

  • 示例工程:

请参考docker-ubuntu-php-nginx,包含ubuntu14.04和ubuntu16.04的示例