首頁  >  文章  >  後端開發  >  Docker建構自己的PHP開發環境

Docker建構自己的PHP開發環境

不言
不言原創
2018-06-07 11:08:131739瀏覽

本文要跟大家介紹的是如何在docker中搭建一個PHP的開發環境,將用zPhal-dockerfiles 做為例子,有需要的小伙伴可以參考下

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. 注意事项

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

相关推荐:

Docker 如何布置PHP开发环境,docker布置php开发

以上是Docker建構自己的PHP開發環境的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn