• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Docker搭建自己的PHP开发环境

    1. 前言

    1.1 为什么要用Docker ?

    是否有这样的场景,你搞了一个项目,在本地开发时需要搭建环境,放到线上时也需要搭建环境,到公司想暗戳戳玩一下要搭建环境,不搭还不行,因为你的环境依赖还挺多。这个时候如果有了Docker,只需要在机器上装个Docker,放上写好的Dockerfile,一行命令就自动完成这个事,方便又高效,岂不是很爽?

    1.2 准备

    接下来,本文介绍如何搭建一个PHP的开发环境,将用 zPhal-dockerfiles 做为例子,这是我为我的博客系统准备的一套Dockerfile。

    现在不管是Windows、Mac还是Linux,Docker都可以很好支持,包括Windows系统,在Win 10系统下Docker for Windows 其实还是挺不错的,就是比较吃内存。

    通过Docker命令行,我们可以做很多事情,拉取镜像,运行容器,容器内执行命令等,但是现在,我们要用更加简单粗暴的方式,编写好Dockerfiles文件,然后通过docker-compose管理好这些文件,简化操作流程。

    什么是Dockerfile?

    Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于拉取的基础镜像并最终创建一个新的镜像,通过Dockerfile我们可以创建一个你需要的镜像,里面是包含了你要安装的软件,相当于是提前定制好要安装的拓展,执行的命令等,然后一键执行,极大地简化操作流程。

    按照本文来搭建环境,你需要:

    首先了解一下Docker以及Docker的一些基本操作,还有docker-compose是什么。
    然后需要安装Docker和docker-compose,我将使用docker-compose来管理我的Dockerfiles。
    注意,编写Dockerfile是活的,不是死的,每个人写出来的Dockerfile都会不一样,取决于你的需求。

    Docker的官方文档非常清楚,虽然是英文,但是基本上什么都有,有问题上文档翻是非常明智的: Docker Documentation 。

    2. 开始编写

    接下来都是以 zPhal-dockerfiles 为例子,完整的可以点链接进去看,下面的只是片段。

    2.1 预览

    首先,我们来看一下,我创建的这个Dockerfile项目,我大概分成了下面的目录(当然这个是自己定的,并不是要求这么去排版你的文件):

    zPhal-dockerfiles
    app/
     index.php
     phpinfo.php
    data/
     .gitignore
    files/
     mysql/
     conf.d/
      mysql-file.cnf
     Dockerfile
     nginx/
     conf.d/
      default.conf
      zphal.conf
     Dockerfile
     nginx.conf
     php/
     pkg/
      .gitignore
     Dockerfile
     php.ini
     php-dev.ini
     php-fpm.conf
     redis/
     Dockerfile
     docker-compose.yml
    logs/
    .gitgnore
    README.md
    

    在这个项目里,我用到PHP、MySQL、Nginx、Redis以及Composer、Phalcon拓展等。

    总的来说,我们做这件事有三个流程:编写好各个软件的Dockerfile;编写好配置文件;通过docker-compose处理所有的Dockerfile,包括将配置配置文件扔进去Dockerfile文件将构建的镜像中。

    2.2 编写Dockerfile文件

    2.2.1 PHP

    下面是PHP的Dockerfile:

    FROM php:7.2-fpm

    MAINTAINER goozp "gzp@goozp.com"
    设置时区

    ENV TZ=Asia/Shanghai

    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ > /etc/timezone

    更新安装依赖包和PHP核心拓展

    RUN apt-get update  apt-get install -y \
    
    git \
    
    libfreetype6-dev \
    
    libjpeg62-turbo-dev \
    
    libpng-dev \
    
     docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    
     docker-php-ext-install -j$(nproc) gd \
    
     docker-php-ext-install zip \
    
     docker-php-ext-install pdo_mysql \
    
     docker-php-ext-install opcache \
    
     docker-php-ext-install mysqli \
    
     rm -r /var/lib/apt/lists/*
    
    

    将预先下载好的拓展包从宿主机拷贝进去

    COPY ./pkg/redis.tgz /home/redis.tgz
    COPY ./pkg/cphalcon.tar.gz /home/cphalcon.tar.gz
    
    

    安装 PECL 拓展,这里我们安装的是Redis

    RUN pecl install /home/redis.tgz echo "extension=redis.so" > /usr/local/etc/php/conf.d/redis.ini

    安装第三方拓展,这里是 Phalcon 拓展

    RUN cd /home \
    
     tar -zxvf cphalcon.tar.gz \
    
     mv cphalcon-* phalcon \
    
     cd phalcon/build \
    
     ./install \
    
     echo "extension=phalcon.so" > /usr/local/etc/php/conf.d/phalcon.ini
    
    

    安装 Composer

    ENV COMPOSER_HOME /root/composer
    RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
    ENV PATH $COMPOSER_HOME/vendor/bin:$PATH
    RUN rm -f /home/redis.tgz \
    
    rm -f /home/cphalcon.tar.gz 
    WORKDIR /data
    Write Permission
    RUN usermod -u 1000 www-data
    
    

    第一行定义了基础镜像,这里我们用了PHP 7.2的fpm版本,这里第二行定义了一个维护者。

    接下来定义了时区,在每一个Dockerfile都定义了这一句,主要是为了使所有的容器的时间都与宿主机同步,其实我们可以在docker-composer.yml文件中这么定义:

    services:

    php-fpm:

    volumes:

      - /etc/localtime:/etc/localtime:ro
    但是在非Linux系统,比如Windows中运行时,我们不能取到/etc/localtime,为了更大兼容所有平台,我把时间同步写到Dockerfile中。

    接下来安装一些拓展,其实安装拓展的过程类似于我们徒手在Linux中安装PHP拓展,值得一提的是Composer。我将Composer直接安装在了php-fpm的镜像中,其实官方也提供了Composer的镜像,拉取Composer镜像执行也可以达到目的,因为我们使用Composer只是为了执行Composer命令来管理我们的包,如果Composer单独是一个容器的话,我们在不用时,还可以将容器关掉;但是在这里,我直接将Composer装进php-fpm镜像中,主要是我的项目安装了一些PHP拓展,在编写composer.json文件时,我定义了extension的依赖,这样Composer执行时会检查环境是否安装了这些依赖,所有如果我直接用Composer镜像的话,还需要把我用的拓展安装到镜像里,就麻烦多了,所以我直接在PHP镜像中就把这个事做了,其实没什么区别,取决于你怎么用。

    2.2.2 Nginx

    下面是Nginx的Dockerfile:

    FROM nginx:1.12
    set timezome

    ENV TZ=Asia/Shanghai

    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ > /etc/timezone

    这个就简单多了,我只设置了一个时间。因为我不需要安装其它的东西,可以直接使用官方的镜像。

    当然,我们需要修改配置文件,只要事先写好配置文件就行,最后在 docker-compose.yml 文件中,将配置文件扔进去,这个下面会讲,包括PHP的配置文件,MySQL的配置文件,都是一样的。

    2.2.3 MySQL

    下面是 MySQL 的 Dockerfile:

    FROM mysql:5.7
    set timezome

    ENV TZ=Asia/Shanghai

    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ > /etc/timezone

    MySQL也没有什么特别之处,直接使用官方的镜像。

    2.2.4 Redis

    下面是 Redis 的,也直接使用官方镜像:

    FROM redis:3.2
    set timezome

    ENV TZ=Asia/Shanghai

    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ > /etc/timezone

    2.3 编写配置文件

    如何处理配置文件呢,我将配置文件进行归类,PHP的配置文件放在PHP目录下,Nginx的配置放在Nginx目录下,至于要不要再新建一个子文件夹就看情况了,比如conf.d文件夹。

    下面以Nginx配置文件为例,首先Nginx目录是这样的:

    nginx/

    conf.d/

        default.conf

        zphal.conf

    Dockerfile

    nginx.conf

    除了nginx.conf外,还有一个子文件夹conf.d用来存放所有的域名配置文件,在Linux下搭建过PHP环境的应该都比较熟悉。这些配置文件就是我们到时候要传进去容器中的文件,我们并不会在宿主机使用这些文件。

    所以需要注意的最重要一点就是,配置文件中出现的路径是容器内环境的路径,而不是宿主机的路径,每一个容器内都有一个运行环境,都是一台微型小系统,这些路径都是容器内的路径。我们可以通过挂载与容器内通讯来同步文件,在命令行启动容器也需要挂载文件路径,而现在挂载这一步我们也用docker-compose来解决。

    下面是一个配置文件示例:

    server {
    listen 80 default;
    index index.html index.htm;
    server_name localhost docker;
    
    root /data/www;
    index index.php index.html index.htm;
    location / {
     try_files $uri $uri/ /index.html;
    }
    
    location ~ \.php {
     include fastcgi_params;
     fastcgi_pass php-fpm:9000;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME /data/www/$fastcgi_script_name;
    }
    } 
    
    

    而root /data/www中,/data/www路径,是到时候Nginx容器的路径,而不是当前在操作的宿主机的路径,所以到时候我们要挂载Web程序放的位置到这个路径。

    2.4 编写 docker-compose.yml

    在PHP、Nginx等目录的同级,我们创建一个docker-compose.yml,我们在执行docker-compose相关命令时,会自动找到这个文件,并根据里面的内容来执行。

    接上面Nginx的例子,我们先谈挂载,因为这是最重要的一步。在docker-compose.yml中,Nginx的部分:

    build: ./nginx
    depends_on:
     - php-fpm
    links:
     - php-fpm:php-fpm
    volumes:
     - ../app:/data/www:rw
     - ./nginx/conf.d:/etc/nginx/conf.d:ro
     - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
     - ../logs/nginx:/var/log/nginx
    ports:
     - "80:80"
     - "8080:8080"
     - "443:443"
    restart: always
    command: nginx -g 'daemon off;'
    

    有一个volumes参数,这里就是我们要挂载的目录的相关配置,第一条我们将../app挂载到/data/www之中,也是我们配置文件中定义的默认监听的root,而APP目录是我们宿主机中的一个目录,通过这样挂载我们可以直接将我们的项目文件放到APP中,Docker会帮你传输到容器内的/data/www目录下。

    其它的参数:

    build定义了你的Dockerfile在哪里,如果没有写Dockerfile可以不用build,可以用images参数定义官方镜像,比如image:mysql:5.7;
    depends_on表示将依赖其它镜像,比如Nginx依赖php-fpm,没有它我Nginx没法玩;
    links定义连接,比如要连接到php-fpm容器,就是php-fpm:php-fpm,后面是别名;
    ports表示端口映射,80:80表示将80端口映射到宿主机的80端口;
    restart重启,restart: always表示将自动重启;
    command是自动执行的命令;
    ……
    参数很多,更多的可以参考官方文档。

    下面是一个完整的 docker-compose.yml 文件:

    version: '3.2'
    services:
    php-fpm:
    build: ./php/
    ports:
     - "9000:9000"
    links:
     - mysql-db:mysql-db
     - redis-db:redis-db
    volumes:
     - ../app:/data/www:rw
     - ./php/php-dev.ini:/usr/local/etc/php/php.ini:ro
     - ./php/php-fpm.conf:/usr/local/etc/php-fpm.conf:ro
     - ../logs/php-fpm:/var/log/php-fpm:rw
    restart: always
    command: php-fpm
    
    nginx:
    build: ./nginx
    depends_on:
     - php-fpm
    links:
     - php-fpm:php-fpm
    volumes:
     - ../app:/data/www:rw
     - ./nginx/conf.d:/etc/nginx/conf.d:ro
     - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
     - ../logs/nginx:/var/log/nginx
    ports:
     - "80:80"
     - "8080:8080"
     - "443:443"
    restart: always
    command: nginx -g 'daemon off;'
    
    mysql-db:
     build: ./mysql
     ports:
     - "3306:3306"
     volumes:
     - ../data/mysql:/var/lib/mysql:rw
     - ../logs/mysql:/var/lib/mysql-logs:rw
     - ./mysql/conf.d:/etc/mysql/conf.d:ro
     environment:
     MYSQL_ROOT_PASSWORD: 123456
     MYSQL_DATABASE: zphaldb
     MYSQL_USER: zphal
     MYSQL_PASSWORD: zphal123
     restart: always
     command: "--character-set-server=utf8"
    redis-db:
     build: ./redis
     ports:
     - "6379:6379"
     volumes:
     - ../data/redis:/data
     restart: always
    
    
    

    3. 使用

    这一套编写下来,我们怎么用呢?

    3.1 使用搭建好的环境

    首先,进入项目Dockerfiles的目录下,这里是files目录:

    cd zPhal-dockerfiles/files

    wget https://pecl.php.net/get/redis-3.1.6.tgz -O php/pkg/redis.tgz

    wget https://codeload.github.com/phalcon/cphalcon/tar.gz/v3.3.1 -O php/pkg/cphalcon.tar.gz
    然后下载我们会用到的PHP拓展包。

    执行命令:

    docker-compose up
    Docker会自动通过编写好的docker-compose.yml内容构建镜像,并且启动容器。

    如果没问题,下次启动时可以以守护模式启用,所有容器将后台运行:

    docker-compose up -d
    关闭容器:

    可以这样关闭容器并删除服务:

    docker-compose down
    使用 docker-compose 基本上就这么简单,用stop,start等这些命令来操纵容器服务。而更多的工作是在于编写Dockerfile和docker-compose.yml文件。

    3.2 使用Composer

    当我们要使用Composer时怎么做呢? 我们已经在php-fpm里安装了Composer。

    用docker-compose进行操作:

    docker-compose run --rm -w /data/www/zPhal php-fpm composer update
    -w /data/www/zPhal为在php-fpm的工作区域,zPhal项目也是挂载在里面,所有我们可以直接在容器里运行Composer。

    或者进入宿主机APP目录下用Docker命令:

    cd zPhal-dockerfiles/app

    docker run -it --rm -v `pwd`:/data/www/ -w /data/www/zPhal files_php-fpm composer update

    4. 注意事项

    注意挂载路径。
    构建失败时,注意容器内是否报错。
    加速镜像。如果过程下载镜像很慢,可以使用国内的加速镜像服务。

    您可能感兴趣的文章:
    • PyCharm使用Docker镜像搭建Python开发环境
    • 利用docker-compose搭建AspNetCore开发环境
    • 使用Docker快速搭建Oracle开发环境的方法教程
    • 详解MAC OSX Docker开发环境搭建
    • Ubuntu 搭建基于Docker的LNMP+Redis的开发环境(图文)
    • 搭建基于Docker的PHP开发环境的详细教程
    • 快速掌握使用Docker搭建开发环境
    上一篇:php爬取天猫和淘宝商品数据
    下一篇:php数据结构之顺序链表与链式线性表示例
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Docker搭建自己的PHP开发环境 Docker,搭建,自己的,PHP,开发,