Docker 运行基于 Nginx + PHP 的应用程序
个人研究笔记,目的是描述如何让基于 Nginx + PHP 的应用程序在 Docker 中运行。其原理内容将在另一章中讨论。
运行环境
操作系统
使用Ubuntu 16.04 LTS完成。你也可以选择CentOS 7,因为问题很多。已提交CentOS 6.5 的尝试(毕竟是一个很老的系统了)。
Docker
1.13
Nginx
选择最喜欢的Openresty,版本是1.61.6。 ,镜像为 openresty/openresty:高山 。
PHP
本文为 如果你想使用Docker来运行自己的应用程序,你首先必须对镜像有一些了解。 对于OpenResty来说,关于Dockerfile最需要了解的是Nginx的配置。 从 Dockerfile 中可以看到 nginx.conf 在构建过程中被复制到容器中。 您可以在GitHub上查看nginx.conf文件的内容: 您可以了解以下信息: 对于 PHP,您至少需要了解以下有关 Dockerfile 方面的信息: Docker 在构建镜像时使用 Dockerfile 来描述构建镜像的动作。通过分析该文件,您可以了解选择图像的特征。 源文件内容虽然很多,但是需要注意的地方并不多。阅读此文件时请记住前面的问题。 这个文件实际上完成了以下任务: 整个文件中看不到之类的东西 - -prefix7.2.2,镜像为php:7.2.2-fpm-alpine7.2.2。 这样的参数,那么你就可以知道这些文件会默认安装在部署
openresty容器
1
COPY nginx.conf /usr/local/openresty/nginx/conf/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;
}php-fpm 容器
php:7.2.2-fpm-alpine3.7 Dockerfile
php/php-fpm/php-config等二进制文件的安装位置
/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前端网发表,如需转载,请注明页面地址。
code前端网