Serving remote static files with symfony3 - nginx

I have a problem with my Nginx configuration. I have 2 servers, one with nginx and one with my webApp in symfony3.
Here is my configuration :
location /portal/mysite/ {
set $frontRoot /srv/data/apps/mysite-portal-stag/current/web;
set $sfApp app.php; # Change to app.php for prod or app_dev.php for dev
root /srv/data/apps/mysite-portal-stag/current/web;
rewrite ^/portal/mysite/(.*)$ /$1 break;
try_files $uri #sfFront;
}
location #sfFront {
root /srv/data/apps/mysite-portal-stag/current/web;
fastcgi_pass myserver:myport;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $frontRoot/$sfApp;
fastcgi_param SCRIPT_NAME /portal/mysite/$sfApp;
}
The webSite work for all the php scripts but all the assets (static files) are broken files. I don't understand enough how Nginx works to indicate what are the static files and "tell" my proxy that they aren't script.

The try_files directive automatically tries to find static files, and serve them as static, prior to giving up, and letting the request be served as a script.
http://nginx.org/r/try_files
Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the file parameter according to the root and alias directives. It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made.
Note that although you're already using try_files, it appears that perhaps your path handling isn't up to spec.
As for your own answer with a temporary solution, there's nothing wrong with using a rewrite or two, but that said, it looks like you'd benefit from the alias directive.
http://nginx.org/r/alias
Defines a replacement for the specified location.
However, you've never explained why you're serving stuff out of /tmp. Note that /tmp is often automatically cleared by some cron scripts, e.g., on OpenBSD, the /etc/daily script would automatically find and remove files older than about 7 days (on a daily basis, as the name suggests).
In summary, you should first figure out what is the appropriate mapping between the web view of the filesystem and your filesystem.
Subsequently, if a prefix is found, just use a separate location for the assets, together with alias.
Else, figure out the paths for try_files to work as intended.

I have find a very ugly solution until anyone find a better solution, here is what I have done :
I have copied all the assets repository and copied it to my proxy server where nginx is.
Here is my new config :
location /portal/mysite/ {
set $frontRoot /srv/data/apps/mysite-portal-stag/current/web;
set $sfApp app.php;
root /srv/data/apps/mysite-portal-stag/current/web;
rewrite ^/portal/mysite/(.*)$ /$1 break;
try_files $uri #sfFront;
}
location /portal/mysite/asset {
root /tmp/mysite/asset;
rewrite ^/portal/mysite/asset/(.*)$ /$1 break;
}
location #sfFront {
set $frontRootWeb /srv/data/apps/mysite-portal-stag/current/web;
root /srv/data/apps/mysite-portal-stag/current/web;
fastcgi_pass myAdressWeb:myPort;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $frontRoot/$sfApp;
fastcgi_param SCRIPT_NAME /portal/mysite/$sfApp;
}
And now it's working, all the js/css and pictures are found.
If anyone think about a "cleaner" answer, he is more than welcome to answer.

Related

rewrite rules for nginx and Codeigniter

I have implemented a php application in codeigniter and now want to deploy it to the nginx server. Before deploying I checked my nignx configuration on my localhost using MAMP server. It is working correctly. But, this configuration is not working on the live server. As a beginner in nginx, I am not understanding where is the mistake here. In live server, I can not write in the main nginx.conf file. I have a separate configuration file like "abc" for my application "abc". And all my application files are under "abc/xyz" directory. Here is my sample confuguration,
location /abc {
root /srv/www/htdocs/apps/;
index index.html index.htm index.php;
location /xyz {
try_files $uri $uri/ /abc/xyz/index.php;
}
location ~ \.php(\/(\w+))*$ {
try_files $uri =404;
rewrite (.+)\.php(\/(\w+))*$ $1.php break;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Here, I can see my welcome page https://myapplication/abc/xyz. But if I want to navigate other pages like https://myapplication/abc/xyz/other_pages, it is showing "404 Page not found". I have checked the other solutions but none of them is not working in this case. Thanks in advance for the help!
The location /xyz block is nested within the location /abc block. The nested block is required to precess URIs with a prefix of /abc/xyz.
If there are other regular expression location blocks surrounding your location /abc block, you should use the^~` modifier.
For example:
location ^~ /abc {
...
location /abc/xyz {
...
}
...
}
See this document for more.
Sorry for the late answer. It was actually very silly mistake. My controller page name was in small character. This is why it was not working. My configuration is okay. The first letter of the controller page should be in capital character. For example, my controller name is Home. So my php file name must be Home.php not home.php.

rewrite file extension from page.php to page.html in nginx

I am using using nginx and wants to change my url from page.php to page.html
there are two things I want to achieve,
Change url from domain.com/page.php --> domain.com/page.html
The anchore tag in my page is domain.com/page.html but the actual page is page.php. I want this to work without changing my anchor tag.
I have a url like domain.com/page.php?get=value this must be like domain.com/value
Due to limited knowledge in nginx please suggest me the script
When someone states that they want to rewrite a URL from A to B, they often mean the other way around. What they really want is for the URL address bar to show B, but actually access an existing internal resource at A.
From your question, I think that you want the URL address bar to show page.html but internally the page.php resource is served.
Let's assume that you have mixed content, some .html and some .php, so first you might want to remove any .html extension with an internal rewrite so that both .html and .php filenames can be tested. An internal rewrite is one that will not affect the URL address bar, but just makes it easier for the server to internally route the request.
location ~* \.(html|php)$ {
rewrite ^(.*)\.(html|php)$ $1 last;
}
The root location can then process extension-less URIs and test for the presence of .html and .php files, and anything else you fancy.
location / {
try_files $uri $uri/ $uri.html #php;
}
The PHP files are offloaded to a named location which contains the code to send the request upstream to the PHP interpreter:
location #php {
try_files $uri.php /page.php?get=$uri;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass ...;
}
All of the above nginx directives are documented here.

Enable/Disable PHP on Nginx for CDN

I have a server with Nginx installed.
I also have 2 domains pointing to that server. (domain1.com and domain2.com). The first domain (domain1.com) is the front website. The other domain (domain2.com) is the CDN for static content like: JS, CSS, images and font files.
I setup domains config files and everything is running fine. The nginx server has PHP running on it.
My question is: How to disable PHP on the second domain (domain2.com) unless the request has "?param=something" in the GET request?!
It will be something like:
// PHP is disabled
if($_GET['param']){
// Enable PHP
}
or should I use:
location ~ /something {
deny all
}
And keep PHP running?!
Note: I need php to process the param i pass to output some JS or CSS.
PHP with nginx is very different than PHP with Apache, since there is no mod_php equiv for nginx (AFAIK).
PHP is handled by totally separate daemon (php-fpm, or by passing the request to an apache server, etc.) As a result, you can bypass php completely simply by letting nginx handle the request without passing it off to php-fpm or apache. There is a good chance that your nginx configuration already is setup only handoff .php files to php-fpm.
Now, if you're trying to have requests such as /some-style.css?foo=bar get handled by php, then I'd suggest simply segregating static resources from dynamic ones.
You could create a third domain, or simply use two separate directories.
/static/foo.css
vs
/dynamic/bar.css?xyz=pdq
You could then handoff to php inside the location blocks.
location ~ /static {
try_files $uri =404;
}
location ~ /dynamic {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
With the above configuration, requests starting with /static will bypass php regardless of file extension (even .php) and requests starting with /dynamic will be passed on the php-fpm regardless of file extension (even .css)

Nginx root directive inside location block is not working as I expect

I'm having a big headache while configuring Nginx to work inside a location block.
I'm developing a web application with Laravel, and it is located at /srv/http/zenith. With Laravel, the index is inside the public folder, so I'm trying to reach it using the following configuration:
location /zenith/ {
root /srv/http/zenith/public;
try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
But it gets me 404 error everytime. As I read from Nginx documentation, Nginx does not remove the path from the URI, so even inside /zenith/ block, all URIs still start with /zenith/. This way, example.com/zenith points to /srv/http/zenith/public/zenith when I want /srv/http/zenith/public.
How do I fix this error? I expected that Nginx removed this unwanted part automatically, but it seems to be not this way.
You need to understand the difference between a root and alias. A root maps the URI / to the directory mentioned and expects all URI parts after it to match the on disk tree. Alias maps the location of the block it's part of to the directory mentioned and expects all URI parts after this location to match the on disk tree. Since root inside a location block still maps the / URI, the part after / needs to exist on disk for things to work. In the common case you will use root for the document root and alias for location blocks.

Invalid update of symlink static files with nginx

I have got a Symfony2.2.1 project which run with a nginx/1.2.6 (Ubuntu 13.04 VirtualBox).
The render of assets are ok with hard link.
With symlink, it works only on the first initialisation.
When I update a symlink source, the browser render transform my modifications with ����� characters. There is no errors from the browser and the part without modifications is not impacted.
Example of the end of my CSS file after modification:
[...]
div.form-actions {
text-align: center;
}
�����
Currently, I use hard link. I had not this problem with Apache2... :/
Have you got an idea?
Thanks
Nginx site conf:
server {
listen 80;
root /media/sf_NetBeansProjects/XXXX/web;
index app.php;
server_name XXXX.lo;
location / {
# try to serve file directly, fallback to rewrite
try_files $uri #rewriteapp;
}
location #rewriteapp {
# rewrite all to app.php
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|app_dev)\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
error_log /media/sf_NetBeansProjects/XXXX/app/logs/nginx_errors.log;
access_log /media/sf_NetBeansProjects/XXXX/app/logs/nginx_access.log;
}
The subtlety is that the media/sf_NetBeansProjects is a VirtualBox share folder with my Windows8 but as I say previously, apache2 was always ok with that.
Try to restart php5-fpm, after create symlink.
sudo service php5-fpm reload
And check disable_symlinks option http://nginx.org/en/docs/http/ngx_http_core_module.html#disable_symlinks
This article helped:
https://coderwall.com/p/ztskha
"Simply spoken, sendfile() uses kernel calls to copy files directly from disc to tcp. If you are using remote filesystems (like nfs or the VirtualBox Guest Additions stuff), this method isn't reliable."
Essentially, turn off sendfile for NGINX if you are trying to serve files on your guest VM that exist on your host.
"To turn off sendfile() in Apache, you can use the EnableSendfile off directive, for nginx use sendfile off."
Ok well there's one thing that comes up my mind, maybe you're viewing the binary data of the image file, so maybe the browser isn't identifying this as an image file, maybe cause nginx isn't sending the content-type, could be for another reason. but I have one suggestion, add this in your default location /
location / {
try_files ..... ;
types {
image/jpeg jpg jpeg;
}
}
alternatively, you can include mime.types inside the server block
server {
#bla bla bla
include mime.types;
location / {
#bla bla
}
}
I'm not sure if this will work or not, but it's worth a try.
Try clearing your browser cache sometimes nginx throw the the file as raw as in with no mime-type set.
Also try changing the HttpHeaders set the expiration and cache-control of per file to minimum, it depends if your project is still in development. So that the file that is being push by the server is always updated and is not being cache by the browser.
I had the same problem, using the same setup.
You need to disable sendfile from Nginx in order to properly send this static files under symbolic links.
location / {
sendfile off; # Do it before try files
# try to serve file directly, fallback to rewrite
try_files $uri #rewriteapp;
}

Resources