【问题标题】:Docker + Apache + PHP-FPM static contentDocker + Apache + PHP-FPM 静态内容
【发布时间】:2019-07-31 16:40:24
【问题描述】:

我正在使用 Slim/Twig 将 PHP 中的一些站点迁移到 docker 容器。在旧服务器中,一个请求进来了,将请求发送回 html,然后浏览器进行调用以获取 apache 接管的资源 CSS、图像等。

迁移到 Docker 的 httpd conf 本质上是这样的:

ProxyPassMatch "^/(.*\.php\/(.*)?)$" "fcgi://php:9000/var/www/html/public/index.php/$2"

仍在解决所有这些问题,但这实际上是将http://192.168.33.20:8080/index.php/admin 之类的请求转发到fcgi://php:9000/var/www/html/public/index.php/$2,Slim 会选择路径的所有其余部分,因此admin 并返回由twig 呈现的正确视图。

我遇到的问题是资源。我通过 Composer 在 php 应用程序中拥有大部分 css 和前端框架。于是浏览器再次调用:

/index.php/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js HTTP/1.1" 404

获取404,因为 Slim 不知道这条路径是什么,而 apache 只是在转发。

我看过的内容和缺点:

  1. 将资源放在 Apache 上,但这基本上像服务器一样将 Apache 和 php 结合在一起。

  2. 创建一个容器来服务这些文件,即另一个非负载平衡器 Apache 来服务这些请求。这仍然是一对,也意味着我需要找到一种方法来潜在地在蓝绿色部署中存储多个版本。

  3. 将一个卷安装到 Apache lb。不知道为什么我放弃了这个。可能是版本问题。

  4. 创建可以搜索资源的路径。到目前为止我最喜欢的想法,但增加了代码复杂性。

所以我的问题是在 Docker 中有一个标准的方法来处理这个问题吗?

【问题讨论】:

  • 作为对阅读本文的任何人的更新。根据几天的研发,我发现最好的做法是使用 php:apache。它是带有 mod_php 的 apache。所以 apache 和 php 处理的所有好处。站点的反向代理和 php-fpm 基本上是试图将正方形放入圆孔中。这更适合api。当你进入静态文件时,php-fpm 会增加一些不值得头疼的复杂性。

标签: php apache docker slim


【解决方案1】:

我的标准做法是通过框架路由控制资源访问。一个示例实现(在 Lumen 中):

$router->get('/asset[/{path:.*}]', 'AssetController@load');

请求和响应示例如下所示:

GET /asset/js/app.js HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: */*
Referer: http://localhost:8080/spa/example
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

HTTP/1.1 200 OK
Server: nginx
Content-Type: application/javascript
Content-Length: 21056410
Connection: keep-alive
Last-Modified: Sun, 31 Jul 63 19:34:21 +0000
Cache-Control: private, must-revalidate
Date: Wed, 31 Jul 2019 19:34:21 GMT
Accept-Ranges: bytes
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src  'self'; connect-src  'self'; img-src  'self'; style-src 'unsafe-inline' fonts.googleapis.com 'self'; font-src fonts.gstatic.com 'self'; script-src 'unsafe-inline'  'self' 'unsafe-eval'

您的控制器(例如,我之前的示例中的 AssetController)会注意将 URL 路径转换为文件系统路径(注意 .. 和其他技巧,使用 realpath 并将其与您的代码的安装基路径),设置Content-TypeContent-Length标头,任何相关的缓存标头,然后流式传输文件。

虽然这确实增加了复杂性和一定数量的开销,但它提供了通过业务逻辑限制资源的灵活性。

如果性能是一个问题,您可以提升对 Web 服务器的访问权限或屏蔽 CDN 和代理内容后面的路由。

【讨论】:

  • 有没有机会分享一下这条路线的样子?这就是我要走的路,但是当 slim 发送回文件时,浏览器似乎没有用它渲染。
  • 完成@nerdlyist!
  • 这与我使用 phps file_get_contents 所采用的方法相同,它将资源发回。我似乎遇到的问题是 apache 服务器将所有内容类型作为 text/html 发送回,这不允许服务器加载 CSS。
  • @nerdlyist 虽然这听起来像是一个单独的问题,但您是否使用header 函数来设置内容类型?
  • 诚然,这是一个单独的问题。在 slim/php-fpm 中,我使用响应对象来设置标题,但无论我在那里设置什么,apache 似乎都将所有内容设置为 text/html
猜你喜欢
  • 1970-01-01
  • 2017-08-21
  • 2015-08-07
  • 2018-07-17
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
相关资源
最近更新 更多