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
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?
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.
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.
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.
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.
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.
The following is the Dockerfile of MySQL:
FROM mysql:5.7
set timezomeENV 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.
The following is Redis, and the official image is also used directly:
FROM redis:3.2
set timezomeENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
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程序放的位置到这个路径。
在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
这一套编写下来,我们怎么用呢?
首先,进入项目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文件。
当我们要使用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中文网其它相关文章!
推荐阅读:
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!