Home  >  Article  >  Backend Development  >  Build a PHP development environment in Docker

Build a PHP development environment in Docker

php中世界最好的语言
php中世界最好的语言Original
2018-03-24 15:45:194036browse

This time I will bring you how to build a PHP development environment in Docker. What are the precautions for building a PHP development environment in Docker? . Here are practical cases, let’s take a look.

1. Introduction

1.1 Why use Docker?

Is there such a scenario? You have a project that requires setting up an environment when you develop it locally, and you also need to set up an environment when you put it online. When you go to the company and want to play around in secret, you need to set up an environment, but it doesn’t work. Not yet, because you have quite a lot of environmental dependencies. If you have Docker at this time, you only need to install Docker on the machine, put the written Dockerfile, and one line of commands will automatically complete this thing, which is convenient and efficient, wouldn't it be great?

1.2 Preparation

Next, this article introduces how to set up a PHP development environment, using zPhal-dockerfiles as an example. This is a set of Dockerfiles I prepared for my blog system.

Now, whether it is Windows, Mac or Linux, Docker can support it very well, including Windows systems. Docker for Windows under Win 10 system is actually quite good, but it consumes more memory.

Through the Docker command line, we can do a lot of things, pull images, run containers, execute commands within the container, etc., but now, we have to use a simpler and more crude way to write the Dockerfiles file, and then use docker -compose manages these files and simplifies the operation process.

What is a Dockerfile?

Dockerfile is a script composed of a series of commands and parameters. These commands are applied to the pulled base image and finally create a new image. Through Dockerfile we can create an image you need, which contains The software you want to install is equivalent to customizing the extensions to be installed, the commands to be executed, etc., and then executing them with one click, greatly simplifying the operation process.

To set up an environment according to this article, you need to:

First understand Docker and some basic operations of Docker, and what docker-compose is.
Then you need to install Docker and docker-compose, I will use docker-compose to manage my Dockerfiles.
Note that writing a Dockerfile is a living thing, not a dead thing. The Dockerfile written by everyone will be different, depending on your needs.

Docker’s official documentation is very clear. Although it is in English, it basically has everything. If you have any questions, it is very wise to refer to the document: Docker Documentation.

2. Start writing

The following will take zPhal-dockerfiles as an example. You can click on the link to view the complete file. The following is just a fragment.

2.1 Preview

First of all, let’s take a look at the Dockerfile project I created. I roughly divided it into the following directories (of course, this is determined by myself, and it is not required to layout it this way for you. file):

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

In this project, I used PHP, MySQL, Nginx, Redis, Composer, Phalcon extensions, etc.

In general, we have three processes to do this: write the Dockerfile of each software; write the configuration file; process all Dockerfiles through docker-compose, including the configuration The configuration file is thrown into the image that the Dockerfile will build.

2.2 Writing a Dockerfile

2.2.1 PHP

The following is the Dockerfile for PHP:

FROM php:7.2-fpm

MAINTAINER goozp "gzp@goozp.com"
Set time zone

ENV TZ=Asia/Shanghai

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

Update and install dependency packages and PHP core extensions

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 the pre-downloaded expansion packages from the host machine

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

Install PECL extension, here we install Redis

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

Install third-party extensions, here is the Phalcon extension

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

Install 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

The first line defines the basic image, here we use the fpm version of PHP 7.2, The second line here defines a maintainer.

Next, the time zone is defined. This sentence is defined in every Dockerfile, mainly to synchronize the time of all containers with the host. In fact, we can define it like this in the docker-composer.yml file:

services:

php-fpm:

volumes:

- /etc/localtime:/etc/localtime:ro
But in non-Linux systems , for example, when running in Windows, we cannot get /etc/localtime. In order to be more compatible with all platforms, I wrote the time synchronization into the Dockerfile.

Next, install some extensions. In fact, the process of installing extensions is similar to how we install PHP extensions in Linux with bare hands. It is worth mentioning Composer. I installed Composer directly in the php-fpm image. In fact, the official image of Composer is also provided. Pulling the Composer image for execution can also achieve the purpose, because we use Composer only to execute the Composer command to manage our packages. If Composer If it is a separate container, we can turn off the container when not in use; but here, I directly installed Composer into the php-fpm image, mainly because my project has installed some PHP extensions, and after writing composer.json When writing the file, I defined the dependencies of the extension, so that when Composer is executed, it will check whether the environment has these dependencies installed. So if I use the Composer image directly, I also need to install the extension I use into the image, which is much more troublesome, so I did this directly in the PHP image. There is actually no difference, it depends on how you use it.

2.2.2 Nginx

The following is the Dockerfile of Nginx:

FROM nginx:1.12
set timezome

ENV TZ=Asia/Shanghai

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

This is much simpler, I only set a time . Because I don't need to install anything else, I can use the official image directly.

Of course, we need to modify the configuration file. Just write the configuration file in advance. Finally, in the docker-compose.yml file, throw the configuration file in. This will be discussed below, including PHP configuration files, MySQL The configuration files are all the same.

2.2.3 MySQL

The following is the Dockerfile of MySQL:

FROM mysql:5.7
set timezome

ENV TZ=Asia /Shanghai

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

There is nothing special about MySQL either , use the official image directly.

2.2.4 Redis

The following is Redis, and the official image is also used directly:

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 Writing configuration files

How to process configuration files? I classify the configuration files. PHP configuration files are placed in the PHP directory, and Nginx configurations are placed in the Nginx directory. As for whether to create a new sub-file The folder depends on the situation, such as the conf.d folder.

The following takes the Nginx configuration file as an example. First, the Nginx directory is like this:

nginx/

conf.d/

default.conf

zphal.conf

Dockerfile

nginx.conf

In addition to nginx.conf, there is also a subfolder conf.d used to store all domain names Configuration files should be familiar to those who have built a PHP environment under Linux. These configuration files are the files we will transfer to the container at that time. We will not use these files on the host.

So the most important thing to note is that the path that appears in the configuration file is the path to the environment in the container, not the path to the host. Each container has a running environment, which is a micro For small systems, these paths are all paths within the container. We can synchronize files by mounting and communicating within the container. Starting the container on the command line also requires mounting the file path. Now we also use docker-compose to solve this step.

The following is an example configuration file:

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

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

php自定义二维数组排序函数array

PHP服务器端的API以及接口开发详解

The above is the detailed content of Build a PHP development environment in Docker. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn