2

I am in the process of moving over some sites in PHP using Slim/Twig to docker containers. In the old server a request came in slim routed the request sent back the html and then the browser made the call to get the resources CSS, images, etc. where apache took over.

Moving to Docker the httpd conf is essentially this:

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

Still working all that out but this essentially forwards a request like http://192.168.33.20:8080/index.php/admin to fcgi://php:9000/var/www/html/public/index.php/$2 and Slim picks off all the rest of the path so admin and returns the correct view rendered by twig.

Issue I am running into is the resources. I have most of my css and front-end frameworks in the php application via composer. So the browser makes another call to:

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

Getting a 404 because Slim has no idea what this path is and apache is just forwarding.

What I have looked at and the cons:

  1. Placing the resources on Apache but this basically couple Apache and php like the server was.

  2. Creating a container to server these files ie another non-loadbalancer Apache to server these requests. This still couples and also means I need to find a way to potentially store multiple versions in a blue green deployment.

  3. Mount a volume to the Apache lb. Not sure why I abandoned this one. Probably version issues.

  4. Create a route that can search for the resource. So far my favorite idea but added code complexity.

So the question I have is there a standard way of dealing with this in Docker?

1
  • As an update to anyone that reads this. The best course of action I found based on a couple days of R&D is to use php:apache. It is apache with mod_php. So all the benefits of apache and php processing. A reverse proxy and php-fpm for a site is basically trying to fit a square into a round hole. That is better fit for an api. When you cross into static files php-fpm adds complications that just are not worth the headache. Commented Aug 1, 2019 at 3:10

1 Answer 1

2

My standard practice is to control resource access by framework route. An example implementation (in Lumen):

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

An example request and response looks like this:

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'

Your controller (e.g., AssetController in my earlier example), would take care to translate the URL path to the file system path (watch out for .. and other tricks, use realpath and compare it to your code's installation base path), set the Content-Type and Content-Length headers, any relevant caching headers, and then stream the file.

While that does add complexity and a certain amount of overhead, it provides the flexibility to constrain resources by business logic.

If performance is a concern, you can promote the access to the web server or shield the route behind a CDN and proxy content.

Sign up to request clarification or add additional context in comments.

5 Comments

Any chance you could share what the route would look like? That is the path I am going with but while slim is sending back the file the browser does not seem to be rendering with it.
Done @nerdlyist!
This is the same approach I was taking using phps file_get_contents it sends the resource back. Problem I seem to be running into is the apache server is sending everythings content type back as text/html which is not allowing the server to load CSS.
@nerdlyist While that sounds like a separate question, are you using the header function to set the content-type?
Admittedly it is a separate question. In slim/php-fpm I am using the response object to set the headers but no matter what I set there apache seems to be setting everything as text/html

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.