Panel Proxy Issue

Thereā€™s an issue with the panel on Kirby 2.5.8 when using it behind a proxy, even when the appropriate headers are passed through the proxy (X-Fowarded-Host and X-Forwarded-Port). Specifically, the panel will log me out on when clicking certain links, redirect me to the wrong URL (127.0.0.1:8080), and the ā€œYour siteā€™s URLā€ widget shows the wrong address (127.0.0.1:8080).

My Setup
Iā€™m using browser sync to enable live reloading during development. This works great with Kirby proper, no issues on page URLs, but the panel is failing to pick up on the correct host. Browser sync, by default, is running on port 3000 and my PHP server is at 8080 (Iā€™m using the builtin PHP dev server, php -S 127.0.0.1:8080). I access my site locally at http://localhost:3000 (through browser sync), but the panel is picking up the address as http://127.0.0.1:8080, even after verifying that the X-Fowarded-* headers are being passed to the server appropriately. The headers look like the following after adding dump(server::get()) to my home template:

Array
(
    [DOCUMENT_ROOT] => <omitted>
    [REMOTE_ADDR] => 127.0.0.1
    [REMOTE_PORT] => 49513
    [SERVER_SOFTWARE] => PHP 7.1.7 Development Server
    [SERVER_PROTOCOL] => HTTP/1.1
    [SERVER_NAME] => 127.0.0.1
    [SERVER_PORT] => 8080
    [REQUEST_URI] => /
    [REQUEST_METHOD] => GET
    [SCRIPT_NAME] => /index.php
    [SCRIPT_FILENAME] => <omitted>/index.php
    [PHP_SELF] => /index.php
    [HTTP_X_FORWARDED_HOST] => localhost:3000  // This seems correct
    [HTTP_X_FORWARDED_PROTO] => http
    [HTTP_X_FORWARDED_PORT] => 3000  // Same with this
    [HTTP_X_FORWARDED_FOR] => ::1
    [HTTP_COOKIE] => <omitted>
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.9
    [HTTP_ACCEPT_ENCODING] => identity
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    [HTTP_USER_AGENT] => <omitted>
    [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
    [HTTP_CACHE_CONTROL] => max-age=0
    [HTTP_CONNECTION] => close
    [HTTP_HOST] => 127.0.0.1:8080
    [REQUEST_TIME_FLOAT] => 1515183940.2791
    [REQUEST_TIME] => 1515183940
    [argv] => Array
        (
        )

    [argc] => 0
)

Browser Sync Config
As an FYI for those setting up browser sync, which there seems to be a few issue on this forum, you should make sure to configure browser sync to pass the X-Forwarded-* headers with the following:

"proxy": {
    "target": "127.0.0.1:8080",
    "proxyOptions": {
        "xfwd": true
    }
}

Likewise Iā€™ve had success with the following file watch patterns for typical development:

"files": [
    "assets",
    "content",
    "site/snippets",
    "site/templates"
]

Work Around
Iā€™ve found that configuring the url (c::set('url', 'http://localhost:3000');) in the config will solve the issue, but itā€™s not ideal. Mostly because this must be placed in the config.php not a config.localhost.php (because of the aforementioned problem, the panel seems to ignore the localhost config). I believe itā€™s best that config.php represent a production environment and a localhost config should override for development.

Ideally the panel, like Kirby, should be able to pick up on the X-Forwarded-* headers and use that for the site base URL. Thereā€™s a few issues related to proxying and browser sync, but I canā€™t seem to synthesize a solution besides manually setting the url in config.php.

Has anyone else had this problem? Are there any other thoughts on how to fix this issue? Is this indeed a bug in the panel?

Thanks in advance for any assistance!

Update
It appears that the panel URLs whenever a page first loads are correct (they are http://localhost:3000). In other words, if I go directly to any page in the panel, the URLs are correct. However, if I click on any link on the page, the subsequent page has the incorrect URLs (http://127.0.0.1:8080). It appears that there is a distinction between how the PHP backend renders a panel page (from a full refresh) and how the JS frontend will render a page (subsequent navigation).

Hm, or perhaps a difference between how the proxy handle an XHR request vs a document request?

Update 2
Using MAMP with browser sync, or accessing the panel directly the the PHP server seem to work flawlessly. The issue is specifically the panel + browser sync + the PHP dev server.

Try mapping 127.0.0.1:8080 to a local domain name. Iā€™m using browsersync via proxy and laraval mix running on Valet with no problem

If i login to the panel at the http://localhost:3000 its works ok until i click around into some pages then the panel relieses its running on localsite.dev. I think this is down to the way different parts of kirby detect the domain its running on.

try setting your hosts file to map 127.0.0.1:8080 to localsite.dev then set browsersync to something like:

  proxy: 'localsite.dev',
  files: [
    "public/assets/js/**/*.js",
    "public/assets/css/**/*.css",
    "public/site/templates/*.php",
    "public/site/snippets/**/*.php",
    "public/content/**/*.txt"
  ]

Then access the site through localsite.dev/panel

Failing that, consider using Valet. its very light weight.

@jimbobrjames thanks for your reply!

I think your answer is leading in the right direction. Using PHPā€™s dev server seems to be the issue. I just tried using MAMP, and everything seems to be working fine. Though, the yet unmentioned motivation was to basically eliminate all possible dependencies. We have a number of people I would like to be able to do simple local development on this project that donā€™t necessarily have the engineering background to setup a full development environment. People that can edit templates and SASS, but shouldnā€™t need to install the world to do those simple edits (Bower, Grunt, SASS, MAMP, etc). I am trying to lower the barrier to entry, so to speak, as low as possible for Kirby development.

The nice part about the builtin PHP server is that it is installed already on all Macs, however it seems that I missing some crucial header, or something that the panel needs to identify the correct address that MAMP or Valet seems to handle correctly. MAMP is also dead simple, but it is yet another dependency and thereā€™s issues with itā€™s usage (thereā€™s a bug in MAMP that is exacerbated by how our company sets up our user accounts, thereā€™s a work around, but not one that is easy for non-engineers).

Also thereā€™s a slight bug I believe in the PHP dev server when it comes to using it detailed here: http://php.net/manual/en/features.commandline.webserver.php#120449

Essentially IPs must be used to prevent it from spinning up in IPv6 mode, I donā€™t know if this is true, but I did have issues proxying from browser sync to PHP dev server using localhost instead of the IP.

I gave up MAMP a couple of years back because you are locked in to the versions of PHP and MySQL and anything else thats preloaded and configured. i ran into a couple occassions where the system i was working on needed a version of PHP higher then supplied in mamp. The only solution was to hack mamp until the next version came out.

Valet is great because it uses the PHP and MySql already on your mac. (if your running High Sierra, you already have PHP7 and MySql 5.7.20 installed) The only pitfall is that Valet uses Nginix under the hood, so while Kirby works out of the box with the default .htaccess rules, you may find making editions to it dont fly. You will need a custom valet driver to solve that. I have not tried adding an nginx config to Valet.

If Valet is a little to light for you, I would suggest Homesetead or Scotchbox Pro (costs a few dollars if the free version is not enough for you, but you were willing to pay for MAMP so i guess thats ok) over MAMP.

Both of these can be configured via a simple config file. Homestead will do Multisites from one box. Scothbox can do this too, but itā€™s a little harder. This way, you can setup the config and share with with the team and everyone can work the same. The plus side is its a real webserver.

On a side note, might be worth looking at my NPM boilerplate. This uses npm scripts to compile sass, javascript, rather then gulp or grunt, has browsersync already set to go, and I know it works great with Valet, Scotchbox and Homestead. Will also optimise images and deploy your site. :slight_smile:

p.s If you do go down the Vagrant route, this tool is very useful.

Thanks for the input!

Yeah, MAMP has been quite tedious to keep using over the years.

Iā€™ll certainly look into Valet, Homestead, and Scotchbox. Price is not really an issue, easy of use is my primary concern, especially for those that arenā€™t engineers.

Yeeeeess! Thanks for the NPM boilerplate link. This is the exact direction Iā€™ve gone in, eliminated all my dependencies on task runners etc. I was aiming to strip my dependencies down to only OSX, Node, and NPM. Though it seems like I may have to add in some kind of server (unless I can hack PHPā€™s dev server into submission). Itā€™s great to compare and contrast with how someone else rolled their NPM scripts, which judging by my brief glance, thereā€™s some things I should borrow.

@mjboselowitz On a side note: You might want to keep in mind that there are other issues with the built-in PHP server, for example if you want to use Kirbyā€™s content representations feature (because the built-in server doesnā€™t support dots in the URL).

Your welcome. If you keep one thing, see how i copy fonts and images using rsync? This means you donā€™t need to clean up your build folder for old images and fonts manually. rsync cleans up automatically so you donā€™t have to. I was quite pleased with that one :slight_smile:

Good to know! Thatā€™s unfortunate. There are quite a number of limitations to the built-in dev server, it seemed like it would be the simplest to use, but it seems like itā€™s more of a liability.

I believe I have an acceptable solution. As I mentioned in the first post, setting the url in the config works, but you cannot use config.localhost.php to do it (this is because php -S localhost:8080 actually binds to IPv6ā€™s loopback, not IPv4 like browser sync expects. Essentially without using IPā€™s, browser sync cannot proxy to PHPā€™s built-in server). Well, it turns out you can use config.127.0.0.1.php to configure the url. So I added c::set('url', 'http://localhost:3000'); to my config.127.0.0.1.php and everything seems to be good. Donā€™t need to mess up my config.php with dev configurations and the panel and the site seem to work.

However, as @texnixe mentioned, the PHP built-in dev server still has plenty of limitations at least including the inability to utilize Kirbyā€™s content representations because . (dots) in the URL are not supported by it. So this is not an ideal solution, but for attempting to minimize dependencies to near zero, this still seems like a viable option.