The Docker practice of PHP development

Source: Internet
Author: User
Tags gpg
Environment deployment has always been a big problem, whether it is a development environment or a production environment, but Docker packages the development environment and production environment in a lightweight manner, providing a consistent environment. Greatly improved development deployment consistency. Of course, the actual situation is not as simple as the configuration of the production environment and the development environment is completely different, such as the log and other issues need to be configured separately, but at least easier than before, and here is the PHP development as an example to explain how Docker layout development environment.

In general, a PHP project will require the following tools:

    1. Web Server: Nginx/tengine

    2. Web Program: PHP-FPM

    3. Database: Mysql/postgresql

    4. Cache Service: Redis/memcache

This is the simplest architectural way, in the early days of Docker development, Docker was heavily abused, for example, a mirror in the start of multi-service, log collection is still in accordance with the Syslog or other old way, the mirror capacity is very large, the base image can reach 80M, which and Docker The idea was completely different, and the Alpine Linux distribution, as a lightweight Linux environment, was well suited as a docker base image, and Docker also recommended using Alpine instead of Debian as the base image, and a large number of existing official mirrors in the future will be migrated to Alpine. All images in this article will be Alpine as the base image.

Nginx/tengine

This part of the author has in another article in the Docker container Nginx practice explained the Tengine Docker practice, and gave the Dockerfile, because of comparative preference Tengine, and the official has given the Nginx Alpine mirror, so here Just use Tengine. The author has uploaded the image to the official DockerHub, which can be

Docker Pull Chasontang/tengine:2.1.2_f

Get the image, see Dockerfile for details.

php-fpm

Docker has already provided PHP's 7.0.7-fpm-alpine image, Dockerfile as follows:

From alpine:3.4# persistent/runtime depsenv phpize_deps \ autoconf \ file \ g++ \ gcc \ Libc-dev \ make \ pkgconf \ re2crun apk add--no-cache--virtual. persistent-deps \ Ca-cert Ificates \ curl# Ensure www-data user Existsrun set-x \ && addgroup-g 82-s www-data \ && A Dduser-u 82-d-s-g www-data www-data#-the standard uid/gid for "Www-data" in alpine# http://git.alpinelinux.org/c git/aports/tree/main/apache2/apache2.pre-install?h=v3.3.2# http://git.alpinelinux.org/cgit/aports/tree/main/ lighttpd/lighttpd.pre-install?h=v3.3.2# http://git.alpinelinux.org/cgit/aports/tree/main/nginx-initscripts/ Nginx-initscripts.pre-install?h=v3.3.2env php_ini_dir/usr/local/etc/phprun mkdir-p $PHP _ini_dir/conf.d### #ENV PHP_ Extra_configure_args--enable-fpm--with-fpm-user=www-data--with-fpm-group=www-data### #ENV Gpg_keys 1a4e8b7277c42e53dba9c7b9bcaa30ea9c0d5763env php_version 7.0.7ENV php_filename php-7.0.7.tar.xzenv PHP_ SHA256 9cc64a7459242c79c10e79d74feaf5bae3541f604966ceb600c3d2e8f5fe4794run set-xe \ && apk add--no-cache--vi        Rtual. build-deps \ $PHPIZE _deps \ curl-dev \ gnupg \ libedit-dev \ libxml2-dev \ Openssl-dev \ sqlite-dev \ && curl-fsl "http://php.net/get/$PHP _filename/from/this/mirror"-O "$PHP _f Ilename "\ && echo" $PHP _sha256 * $PHP _filename "|    Sha256sum-c-\ && curl-fsl "http://php.net/get/$PHP _filename.asc/from/this/mirror"-O "$PHP _filename.asc" \ && Export Gnupghome= "$ (mktemp-d)" \ && for key in $GPG _keys; Do \ gpg--keyserver ha.pool.sks-keyservers.net--recv-keys "$key"; \ done \ && gpg--batch--verify "$PHP _filename.asc" "$PHP _filename" \ && rm-r "$GNUPGHOME" "$PH  P_filename.asc "\ && mkdir-p/usr/src \  && tar-jxf "$PHP _filename"-c/usr/src \ && mv "/usr/src/php-$PHP _version"/usr/src/php \ &&A mp RM "$PHP _filename" \ && cd/usr/src/php \ &&./configure \--with-config-file-path= "$PHP _ini_ DIR "\--with-config-file-scan-dir=" $PHP _ini_dir/conf.d "\ $PHP _extra_configure_args \--disable-cgi \#--enable-mysqlnd is included here because it's harder to compile after the fact than extensions is (since it's a Plugi N for several extensions, not a extension in itself)--enable-mysqlnd \#--enable-mbstring are included here Becaus e Otherwise there's no-it properly (see https://github.com/docker-library/php/issues/195)--pecl enable-mbstring \--with-curl \--with-libedit \--with-openssl \--with-zlib \ && Make-j "$ (getconf _nprocessors_onln)" \ && make install \ && {find/usr/local/bin/usr/local/sbin- Type F-perm +0111-EXEC strip--strip-all ' {} ' + | | True            } \ && make clean \ && rundeps= "$ (\ scanelf--needed--nobanner--recursive/usr/local \ | awk ' {gsub (/,/, "\nso:", $); Print "So:" $ {} \ | Sort-u \ | Xargs-r apk info--installed \ |  sort-u \) "\ && apk add--no-cache--virtual. php-rundeps $runDeps \ && apk del build-depscopy  docker-php-ext-*/usr/local/bin/### #WORKDIR/var/www/htmlrun set-ex \ && cd/usr/local/etc \ && If [-D PHP-FPM.D]; Then \ # for some reason, Upstream's php-fpm.conf.default has "include=none/etc/php-fpm.d/*.conf" sed ' s!=no Ne/!=!g ' Php-fpm.conf.default | Tee php-fpm.conf >/dev/null; \ cp Php-fpm.d/www.conf.default php-fpm.d/www.conf;  \ else \ # php 5.x don ' t use "include=" by default, so we'll create our own simple config this mimics PHP 7+ for Consistency mkdir PHP-FPM.D; \ cp Php-fpm.conf.defaUlt php-fpm.d/www.conf; \ {\ echo ' [global] '; \ Echo ' include=etc/php-fpm.d/*.conf '; \} | Tee php-fpm.conf; \ fi \ && {\ echo ' [global] '; \ Echo ' error_log =/proc/self/fd/2 '; \ echo; \ E Cho ' [www] '; \ Echo '; If we send this to/proc/self/fd/1, it never appears '; \ echo ' access.log =/proc/self/fd/2 '; \ Echo; \ echo ' clear_env = no '; \ Echo; \ Echo '; Ensure worker stdout and stderr is sent to the main error log. \ echo ' catch_workers_output = yes '; \    } |        Tee php-fpm.d/docker.conf \ && {\ echo ' [global] '; \ echo ' daemonize = no '; \ echo; \ Echo ' [www] '; \ echo ' Listen = [::]:9000 '; \    } | Tee php-fpm.d/zz-docker.confexpose 9000CMD ["PHP-FPM"]####

First, the image inherits from the alpine:3.4 image, using the APK command to install the PHP minimum dependency, while adding www-data as the php-fpm running user, the PHP configuration file is assigned to/usr/local/etc/php, and then the download php-src , compile the installation, here you can refer to the author before the PHP compilation installation article. The parameters are all the same. The installation directory is assigned to/usr/local and then uses scanelf to obtain the list of dependent runtimes and remove the other installation packages. Docker-php-ext-configure, docker-php-ext-enable, Docker-php-ext-install are copied to the container, and these three files are used for subsequent installation extensions. The php-fpm.conf is then copied to the configuration directory, Error_log and Access_log are specified to the terminal standard output, and daemonize = no indicates that the service process is not running. The EXPOSE 9000 port is used to communicate with other containers and is then CMD ["PHP-FPM"] to run PHP-FPM. and the working directory is assigned to/var/www/html.

Docker-compose

With the base image already in order, we can use the underlying image to configure the container, but it can be cumbersome to start the container with the manual Docker command. But fortunately, the official has provided the Docker-compose command to orchestrate the container, just write a docker-compose.yaml file on the line, specific to the official documents.

Version: ' 2 ' services:  php-fpm:    image:php:7.0.7-fpm-alpine    volumes:      -"./src:/var/www/html"    Restart:always  tengine:    depends_on:      -php-fpm    Links:      -php-fpm    image:chasontang/tengine : 2.1.2_f    Volumes:      -"./nginx.vh.default.conf:/etc/nginx/conf.d/default.conf"    ports:      -"80:80 "    Restart:always

It is very easy to understand that two services are defined here, PHP-FPM relies on php:7.0.7-fpm-alpine mirroring, and the SRC folder is mapped to/var/www/html folder, Tengine Service relies on PHP-FPM service, and link php-f PM service, which communicates with PHP-FPM containers over the network, Tengine services based on Chasontang/tengine:2.1.2_f mirroring and maps nginx.vh.default.conf files to/etc/nginx/ conf.d/default.conf file. and see nginx.vh.default.conf.

server {Listen 80;    server_name localhost;    #charset Koi8-r;    #access_log Logs/host.access.log Main;        Location/{root HTML;    Index index.html index.htm;    } #error_page 404/404.html;    # REDIRECT Server error pages to the static page/50x.html # Error_page 502 503 504/50x.html;    Location =/50x.html {root html; } # Proxy The PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ {# Proxy_pass/http/    127.0.0.1;        #} location ~ [^/]\.php (/|$) {fastcgi_split_path_info ^ (. +?\.php) (/.*) $;        Fastcgi_pass php-fpm:9000;        Fastcgi_index index.php;        Fastcgi_param Script_filename/var/www/html$fastcgi_script_name;        Fastcgi_param path_info $fastcgi _path_info;    Include Fastcgi_params;     } # Deny access to. htaccess files, if Apache ' s document Root # concurs with Nginx ' s one # #location ~/\.ht {    # Deny All; #}}

The tengine image actually uses two configuration files, one is/etc/nginx/nginx.conf, and all the files in the/etc/nginx/conf.d/directory, because the include is used in/etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf, contains this directory, that is, you can not need to pipe nginx other configuration, only need to use their own Nginx virtual host configuration instead of the default virtual host configuration, or increase the virtual host configuration is OK.

As you can see from above, the default.conf file defines a location that matches the URL containing the. PHP, and then splits it out of the PATH_INFO parameter to pass these variables to php-fpm:9000 's PHP-FPM service.

It should be noted here that since Nginx and PHP-FPM are not on the same host, Nginx only does static file processing and route forwarding, and the actual PHP file is executed in the PHP-FPM container. So the script_filename variable must use the directory in the PHP-FPM container, so this is specified using hard coding. Of course, you can also let two containers share the same data volume, but I think this is just for the convenience of container orchestration, the other completely no benefit.

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.