使用 Docker 容器隔离 PHP
Docker 是一项很棒的技术。它能让你很好地搭建开发环境或测试新软件,而且不会阻塞你的系统。
我正在尝试使用 Docker、Apache 和 PHP 来运行一些网页。如何才能轻松地切换 PHP 版本,而不会阻塞本地计算机或创建多个 Docker 镜像/Vagrant 容器?我相信很多开发人员都能轻松找到解决方案,但我必须承认,我在概念化容器解决方案方面确实遇到了困难。层层抽象会造成思维障碍,我相信我并非唯一遇到这种情况的人。
我突然想到,Apache/PHP 并不符合 Docker 的“每个容器一个进程”原则。PHP 和 Apache 紧密结合,以至于在关注点分离方面,根本行不通。
我非常希望我的 Web 服务器容器与编程语言能够完全隔离。切换到 NGINX 和 PHP-FPM 后,隔离更加清晰,让我们能够轻松切换语言版本。如果您的旧网站需要不同的版本,或者您想在升级之前试用一下网站,那么这将会非常方便。
设置
因此计划是,当请求发送到test5.com/index.php url 时,Nginx 容器将传递请求以将index.php处理到运行 PHP 5 的容器中,显然对于test7.com/index.php和 PHP 7 也是如此。
首先,向/etc/hosts
文件添加 2 个条目:
127.0.0.1 test5.com
127.0.0.1 test7.com
这些将是我们用来访问 Nginx 容器的地址。
从 GitHub 下载或克隆docker-php-isolation-example仓库到系统上合适的位置。所有命令都将在此文件夹中通过 CLI 运行。
文件夹结构比较简单:
-
webroot - 不言自明的文件夹,其中包含一个名为的文件
index.php
,其中包含phpinfo()
命令。 -
site.conf ——Nginx 站点配置文件。
-
docker-compose.yml -docker 设置配置文件。
docker -compose.yml文件设置了 3 个容器,全部基于 Alpine Linux 镜像,因此容器的总大小只有 120Mb。
version: '2'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./webroot:/var/www/html
- ./site.conf:/etc/nginx/conf.d/site.conf
links:
- php7
- php5
php7:
image: php:7-fpm-alpine
volumes:
- ./webroot:/var/www/html
php5:
image: php:5-fpm-alpine
volumes:
- ./webroot:/var/www/html
主容器是 Nginx 代理,它是唯一一个拥有外部端口(8080)的容器。该容器将所有有效请求代理到另外两个容器,一个运行 php 7 php-fpm,另一个运行 php 5 php-fpm,端口号为 9000。
webroot文件夹在所有 3 个容器之间共享,Nginx 需要它来提供任何非 PHP 文件,而 PHP 容器需要访问 PHP 文件。
site.conf文件包含定义 Nginx 如何处理请求:
server {
listen 80;
index index.php;
server_name test7.com;
root /var/www/html/;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php7:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
server {
listen 80;
index index.php;
server_name test5.com;
root /var/www/html/;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php5:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
我确信有办法将这两个地址合并为一个并使用正则表达式,但生命太短暂了。
运行它
从 CLI 导航到下载存储库的文件夹并输入docker-compose up -d
。
如果镜像尚未保存在本地,这将下载镜像并启动容器。完成后,输入以下命令docker ps
以确保 3 个容器正在运行。
因此打开您选择的浏览器并输入 test5.com:8080,您应该会看到 PHP 5 的 phpinfo()。
接下来,输入 test7.com:8080,您应该会看到 phpinfo(),您猜对了,就是 PHP 7!
就这样,我们可以定义使用哪个版本的 PHP 来处理相同的 index.php 文件,享受数小时的乐趣……
整理
够刺激了吗?要关闭正在运行的容器,请输入docker-compose down
,这将关闭并删除容器。
如果要删除已下载的图像,请输入,docker images
然后docker rmi IMAGE ID
,例如将删除 ID 为4fe1b7f08eb1、8b057b9de580和1b95155d2daf 的3docker rmi 4fe1b7f08eb1 8b057b9de580 1b95155d2daf
幅图像。
最后
将 PHP 作为一种“软件即服务”来提供,这个想法可能有点不起眼,但我觉得它真的很酷。能够隔离编程语言的不同版本让我非常感兴趣,我可能会尝试在未来的项目中融入这一点。
使用 Docker 容器隔离 PHP 于 2017 年 7 月 10 日首次出现在我的博客网站上。
文章来源:https://dev.to/johnmccuk/isolated-php-with-docker-containers-4epn