Code前端首页关于Code前端联系我们

Docker 运行基于 Nginx + PHP 的应用程序

terry 2年前 (2023-09-28) 阅读数 57 #未命名

个人研究笔记,目的是描述如何让基于 Nginx + PHP 的应用程序在 Docker 中运行。其原理内容将在另一章中讨论。

运行环境

操作系统

使用Ubuntu 16.04 LTS完成。你也可以选择CentOS 7,因为问题很多。已提交CentOS 6.5 的尝试(毕竟是一个很老的系统了)。

Docker

1.13

Nginx

选择最喜欢的Openresty,版本是1.61.6。 ,镜像为 openresty/openresty:高山

PHP

本文为7.2.2,镜像为php:7.2.2-fpm-alpine7.2.2。

部署

如果你想使用Docker来运行自己的应用程序,你首先必须对镜像有一些了解。

openresty容器

对于OpenResty来说,关于Dockerfile最需要了解的是Nginx的配置。

从 Dockerfile 中可以看到 nginx.conf 在构建过程中被复制到容器中。

1
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf

您可以在GitHub上查看nginx.conf文件的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

您可以了解以下信息:

  • nginx配置文件为/usr/local/openresty/nginx/conf/nginx.conf
  • vhosts 配置文件目录为/etc/nginx/conf.d/。该目录可以放置项目运行的Nginx配置文件。

php-fpm 容器

对于 PHP,您至少需要了解以下有关 Dockerfile 方面的信息:

  • 二进制文件的安装位置,例如 php/php-fpm/php-config 的位置及其内容php.ini 文件
  • php-fpm.conf 文件的位置和内容
  • php-fpm 运行用户和用户组

Docker 在构建镜像时使用 Dockerfile 来描述构建镜像的动作。通过分析该文件,您可以了解选择图像的特征。

php:7.2.2-fpm-alpine3.7 Dockerfile

源文件内容虽然很多,但是需要注意的地方并不多。阅读此文件时请记住前面的问题。

这个文件实际上完成了以下任务:

  • 声明依赖的基础镜像
  • 设置环境变量
  • 复制 PHP 环境所需的具体工具(如扩展安装工具) 并配置 PHP 7.2 .2
  • 启动php-fpm并暴露端口

php/php-fpm/php-config等二进制文件的安装位置

整个文件中看不到之类的东西 - -prefix

这样的参数,那么你就可以知道这些文件会默认安装在/usr/local/bin/文件夹中。

启动一个容器进行验证:

1
2
3
4
5
 ➜ docker run -it --rm php:7.2.2-fpm-alpine3.7 /bin/sh
/var/www/html # ls /usr/local/bin/
docker-php-entrypoint     docker-php-ext-install    peardev                   phar.phar                 phpdbg
docker-php-ext-configure  docker-php-source         pecl                      php                       phpize
docker-php-ext-enable     pear                      phar                      php-config

php.ini 文件的位置和内容

文件第 37 行:

1
ENV PHP_INI_DIR /usr/local/etc/php

在后续的构建配置阶段(从第 92 行开始): 您可以查看并定义该目录。

但是整个文件中并没有看到将ini文件复制到对应文件夹的操作,所以这个容器并不是使用php.ini文件来配置的。

如果想知道当前的默认设置,不妨进入容器中通过/usr/local/bin/php -i查看。

php-fpm.conf 文件

的位置和内容与 php.ini 文件类似。

php-fpm运行用户和用户组

这就涉及到一个权限问题。 Docker可以将应用程序代码复制到容器中,但这也可以通过挂载目录并将目录的所有者设置为当前运行的容器的Uid来完成,可以避免权限问题。

在文件的第29行中,您可以看到已添加uid为82的www-data用户。

1
2
3
RUN set -x \
	&& addgroup -g 82 -S www-data \
	&& adduser -u 82 -D -S -G www-data www-data

在构建阶段,还声明fpm算子是www-data

1
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data

启动容器

openresty和phpDocker容器之间没有通过链接关联的方式直接访问

1
2
3
RUN set -x \
	&& addgroup -g 82 -S www-data \
	&& adduser -u 82 -D -S -G www-data www-data

,可以使用link方式,也可以直接将端口映射到主机端口,通过主机的网络进行通信。

您需要先启动 php-fpm 容器。

启动php-fpm容器

因为需要配置时区等配置,但当前容器没有默认的php.ini文件,所以可以挂载一个自行配置的php.ini文件。

php.ini PHP错误日志目录在配置文件中定义为/var/www/logs/php_error.log,所以可以写入日志的目录是挂载的容器/var /www/logs 库。

1
2
3
4
5
6
docker run --name=test_phpfpm \
-v /data1/www/etc/test/conf/php/php.ini:/usr/local/etc/php/php.ini:ro \
-v /data1/www/etc/test/conf/php:/usr/local/etc/php/conf.d/:ro \
-v /data1/www/htdocs/test:/var/www/html \
-v /data1/www/logs:/var/www/logs \
-d php:7.2.2-fpm-alpine3.7

php-fpm 的容器名称是test_phpfpm。连接到它的其他容器可以通过这个名称直接访问该容器。

启动openresty容器

1
2
3
4
5
6
docker run --link=test_phpfpm --name=test_openresty -p 8808:80 \
-v /data1/www/etc/test/conf/nginx/nginx.test.config:/usr/local/openresty/nginx/conf/nginx.conf:ro \
-v /data1/www/etc/test/conf/nginx:/etc/nginx/conf.d/:ro \
-v /data1/www/logs:/usr/local/openresty/nginx/logs \
-v /data1/www/htdocs/test:/var/www/html \
-d openresty/openresty:alpine

对应的Nginx配置文件为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
worker_processes  1;

events {
    worker_connections  65535;
}


http {
    include       mime.types;
    #default_type  application/octet-stream;
    default_type  text/html;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen 80 default_server;
        root /var/www/html;
        index index.php index.html index.htm;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php($|/) {
            fastcgi_pass          test_phpfpm:9000;
            fastcgi_index         index.php;
            include               fastcgi_params;
            set $path_info        "";
            set $real_script_name $fastcgi_script_name;

            if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
                set $real_script_name $1;
                set $path_info        $2;
            }

            fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
            fastcgi_param SCRIPT_NAME     $real_script_name;
            fastcgi_param PATH_INFO       $path_info;
            fastcgi_param PHP_VALUE       open_basedir=$document_root:/tmp/:/proc/:/dev/urandom;
        }
    }

    include /etc/nginx/conf.d/*.conf;
}

至此,宿主机的/data1/www/htdocs/test文件夹中的PHP项目就可以与外界通信了。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门