Nginx and/or php5-fpm remembers symlinked root directory - caching

My nginx site root points to a symlink. If I alter the symlink (aka deploy a new version of the website) the old version of the php script keeps showing up.
That smells like cache, or a bug.
First it looked like Nginx was caching the symlinked dir, but reloading/restarting/killing and starting nginx didn't fix it, so I restarted php5-fpm - this fix my issue.
But I dont want to restart nginx and/or php5-fpm after a deploy - I want to know why there is such a cache (or bug), and why it didn't work properly.
Usefull information:
OS: Ubuntu 13.10 (GNU/Linux 3.8.0-19-generic x86_64)
Nginx: via ppa:nginx/stable
PHP: via ppa:ondrej/php5 (php5-fpm)
Nginx site config:
root /home/rob/sandbox/deploy/public/;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php;
}
Nginx server config (partly, rest is default):
http {
sendfile off;
upstream php {
server unix:/var/run/php5-fpm.sock;
}
}
Tree for /home/rob/sandbox:
├── deploy -> web2
├── web1
│ └── public
│ └── index.php (echo ONE)
└── web2
└── public
└── index.php (echo TWO)
request: http://localhost/index.php
expected response: TWO
actual response: ONE
Part of the output from realpath_cache_get()
[/home/rob/sandbox/deploy/public/index.php] => Array (
[key] => 1.4538996210143E+19
[is_dir] =>
[realpath] => /home/rob/sandbox/web2/public/index.php
[expires] => 1383730041
)
So this means deploy/public/index.php is properly linked to web2/public/index.php, right?
Well, even with the correct paths in the realpath_cache list, the respone still is ONE.
After rm deploy and ln -s web2 deploy Nginx was restarted, no effect.
Restarting php5-fpm after this gives the expected response of 'TWO'.
It's good to know that beside the index.php files, I did some test with .css and .js files.
After removing and recreating the symlink from/to web1 and web2, nginx will respond with the correct contents of the files.
What did I miss, what am I not seeing?

Configure your nginx using $realpath_root. It should help.
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
Kudos go to Vitaly Chirkov (https://stackoverflow.com/a/23904770/219272).

Once I altered the realpath_cache_ttl to '2' (That should fix it) the incorrect content was still showing.
After some digging in the loaded mods for php-fpm, I discovered that opcache was up and running. Disabling that will clear the cached realpath's when the ttl is over.
I don't wanna lower the realpath cache ttl to much,so I will settle in with a reload of php-fpm, since it is graceful.
I hope this thread and my answers will help others ;)

I had exactly same problem and none of the tricks did help. Beside all tricks listed on this page I ensured opcache is disabled then nginx cache was also disabled. I set
sendfile off;
It was described somewhere on stackoverflow.
I started to strace the php and nginx and it turned out that some libraries are read new location but also some were read from OLD location that symlink does not point to anymore.
On top of that updating the php script inside OLD directory was always showing properly - so that did not look like cache to me.
To make it more confusing command line worked fine and followed the symlink to NEW location.
I was pulling hair from my head over this!
It turned out that responsible for all this was the composer cache - it was caching some libraries.
I know not everyone uses it, but if you do and have similar problem it is worth checking.
I have vendor at the same level as the deployment scripts and I assume composer cache was causing a lot of confusion which location should be used.
After cleaning it up with
composer clear-cache
System started to behave as expected.
I hope it will help someone.

Related

Homestead with hhvm:true,but doesn't use hhvm?

I have the last Vagrant+Homestead installation. Nginx+Laravel+php7
I've addedd hhvm: true to yaml file like this
- map: example.local
to: /home/vagrant/Code/example/public
hhvm: true
and issued vagrant reload. No error messages on startup.
However when I show phpinfo() on a page in example.local I still see PHP Version 7.0.8-2
It's there something else to do?
I removed the php config in nginx block.
in /etc/nginx/sites-available/example.local, the config starting with
location ~ \.php$ {...
was clearly pointing to
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
I removed that whole part and replaced with
include hhvm.conf;
and restarted nginx

Hosting Laravel Application on Ubuntu Server

I have recently developed my first Laravel application (version 5.2.).
I now want to host the application on my client's server running Ubuntu.
Their admin managed to install and run the native Laravel application on the server which works just fine, however when I come to copy and paste my own application over, the browser returns:
403 Forbidden
nginx/1.4.6 (Ubuntu)
Accessing the public folder directly (www.example.com/public/index.php) the browser returns:
The www.example.com page isn’t working
www.example.com is currently unable to handle this request.
HTTP ERROR 500
Can anybody please help me out with the proper method of hosting my application?
Seems more like an nginx-problem. Try to change your nginx virtualhost config to this.
server {
listen 80;
server_name yoursite.tld
root /var/www/yoursite/public/;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
# pass the PHP scripts to FastCGI server listening on /var/run/php5-fpm.sock
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
First save your file inside,
var/www/html/
Then using Terminal go to your folder
cd var/www/html/your_folder
Run Laravel application
sudo php -S localhost:8888 -t public
Make sure your port number is not same as the other Laravel instance running in the server.

Don't think I have php setup right in nginx virtual host configs

I'm trying to install magento php ecommerce on a virtual server that previously did not have php. When I put simple php pages into a directory they run (for example I have index.php run phpinfo). But when I try to run the magento setup scripts they bomb out without outputting an error. I have two other virtual servers through a different service (running apache) and when I drop the magento files into them the setup pages light up right away and start checking requirements. On my nginx server the only output is a small grey box, but no error output.
My best guess is that I have not configured nginx virtual hosts properly for php.
I am on php5.5 using fpm on Ubuntu 12.04. I don't run a default file in sites-enabled, just two vhost files. Here's the vhost in question (the other site is working fine, but it's python):
server {
listen 80;
listen [::]:80;
#
server_name magento.mydomain.com;
#
root /var/www/magento.mydomain.com/public_html;
index index.php index.html index.htm;
#
# location / {
# try_files $uri $uri/ /index.php =404;
# }
# location / {
# /index.php;
# }
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:8070;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/magento.mydomain.com/public_html/$fastcgi_script_name;
}
}
You can see my commented out location / directives. I have tried those is various fashion. My hunch was that magento was calling php with directory names only (instead of somedir/index.php) so I was messing with those, but it seems like that would be handled by the index directive before the locations.
I'm pretty green with nginx. Does anyone see anything obvious?

Nginx vhost cache symlink

I've got a problem with deploying my application. I have a PHP application and I deploy my application with Capistrano to my server.
Capistrano makes a new release folder with the latest version of my application and my current folder symlinks to the that release. That works fine, it really links the latest release.
But when I go the the URL of my website nothing changes, the files are from the old release folder even when the symlink links to the current folder (latest release).
Does Nginx cache all my files? Or does it cache my symlinks, I have no idea.
Folder structure:
current (symlink new release)
releases
new release
old release
Vhost:
server {
listen 443;
server_name servname.com;
root /apps/application/production/current/public;
}
The problem is at real path cache level. It caches the PHP file with the symlink path. What you need to do is provide the real document path.
You need to add these 2 lines in your config file
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
The important part is $realpath_root.
From the documentation:
$realpath_root
an absolute pathname corresponding to the root or alias directive’s value for the current request, with all symbolic links resolved to real paths
Meaning $realpath_root solves all symlinks to their real path. This is the important part.
So your location ~ \.php$ would become
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
}
Make sure the include fastcgi_params if present does not overwrite the 2 directives you just added.

404 running Mvc3 with Mono on Raspberry Pi with Nginx and FastCgi

After lots and lots of hours put into configuring, formatting, reformatting, googling and reading what seems like hundred tutorials I still havent been able to run a MVC3 application on Raspberry Pi.
When I try to access it it throws a 404 error regardless if I try to access it via http://network_ip or http://network_ip/Home/Index
(source: shrani.si)
It does the same whether accessed from Nginx or XSP4 server.
My configuration:
nginx
server {
listen 80; ## listen for ipv4; this line is default and implied
root /var/www;
# Make site accessible from http://localhost/
server_name localhost;
access_log /var/log/nginx/localhost.log;
location / {
root /var/www/;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_index Home/Index;
include /etc/nginx/fastcgi_params;
}
}
MVC3 app should be deployed correctly (deleted Entity Framework references, copied Mvc references).
Im running Mono 2.10.8.1
Thank you

Resources