Where to place NGINX host configuration file? - nginx

I've used WINGINX to install NGINX, PHP-FPM, MySQL, MongoDB, NodeJS and MemcacheD on my Windows machine.
In the Yii Framework documentation I've found the following host configuration code:
server {
set $host_path "/www/mysite";
access_log /www/mysite/log/access.log main;
server_name mysite;
root $host_path/htdocs;
set $yii_bootstrap "index.php";
charset utf-8;
location / {
index index.html $yii_bootstrap;
try_files $uri $uri/ $yii_bootstrap?$args;
}
location ~ ^/(protected|framework|themes/\w+/views) {
deny all;
}
#avoid processing of calls to unexisting static files by yii
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
#let yii catch the calls to unexising PHP files
set $fsn /$yii_bootstrap;
if (-f $document_root$fastcgi_script_name){
set $fsn $fastcgi_script_name;
}
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fsn;
#PATH_INFO and PATH_TRANSLATED can be omitted, but RFC 3875 specifies them for CGI
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fsn;
}
location ~ /\.ht {
deny all;
}
}
Where do I need to store this code?
I've used the hosteditor to create: http://project.loc, and the file: index.php is displayed correctly (located at: /winginx/home/project.loc/pubic_html).
I tried placing the code several directoires:
/winginx/conf
/winginx/conf/vhosts
/winginx/home/project.loc
..but non of it worked.

The Wingix Documentation explains how to do this:
you should create in the winginx\conf\vhosts folder a separate config
file named to domain name plus .conf, e.g. mysite.local.conf.
After the config is added or edited, you should restart Winginx,
double-click start-winginx.exe.
If something goes wrong after these manipulates, please read
winginx\logs\error.log.

Related

nginx vhost, problem service .css as static file or dynamic file

I have problems matching my requirements:
I want 2 things;
https://www.test-boutique.vm/store.css to be routed to the PHP application because the file content is streamed by the app;
https://www.test-boutique.vm/static/css/basic.css to be served from the filesystem because it exists on it;
My vhost is :
server {
listen 443;
server_name www.test-boutique.vm;
root /srv/app/public/front;
index index.php;
location / {
# try to serve file directly, fallback to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# css are for the files generated by the application (store.css)
location ~ \.(php|htm|css)$ {
try_files $uri $uri/ /index.php$is_args$args;
fastcgi_pass unix:/var/run/php-fpm.app.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param HTTPS on;
fastcgi_param APP_ENV dev;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(js|css|bmp|png|jpg|jpeg|gif|swf|ico)$ {
try_files $uri =404;
log_not_found off;
access_log off;
expires 7d;
add_header Cache-Control public;
add_header Cache-Control must-revalidate;
}
rewrite ^/media/(.*)$ https://test.cloud/$http_host/media/$1 permanent;
rewrite ^/img/(.*)$ https://test.cloud/$http_host/img/$1 permanent;
access_log /var/log/nginx/fov4_access_log;
error_log /var/log/nginx/fov4_error_log;
}
With this version:
✅ /store.css file works well (generated by the PHP application)
❌ /static/css/basic.css is trying to be served by the PHP application instead of serving the file directly from the filesystem (the file exists for sure under this path)
When removing the css part from the vhost
(location ~ \.(php|htm|css)$ { TO NEW location ~ \.(php|htm)$ {
❌ /store.css file is trying to be served as a static asset and ends up 404 (the request is not passed to the application)
✅ /static/css/basic.css is served correctly
What am I missing please ?
Instead of matching all css files like you do here: location ~ \.(php|htm|css)$ {, try matching that one css file that you need to have generated by PHP:
location ~ \.(php|htm)$ {
# you php-fpm config here
}
location ~* \.(js|css|bmp|png|jpg|jpeg|gif|swf|ico)$ {
# your static files config here
}
location = /store.css {
# you php-fpm config here
}

serve react frontend and php backend on same domain with nginx

I have a React frontend and a Symfony backend I'm trying to serve on the same domain. The React frontend needs to serve assets if they exist otherwise fallback to serve index.html.
I'd like to serve the php Symfony app when /api is in the request uri. Similar to the React app, I need all requests to go to the index.php file.
The frontend is being served correctly but not the api. I get a 404 from nginx when i hit /api in the browser.
I feel like i'm close but for some reason nginx doesn't have the correct $document_root. I'm adding a header(X-script) to test what the variables are and I'm getting the following:
X-script: /usr/share/nginx/html/index.php
Here's my nginx config.
server {
listen 80 default_server;
index index.html index.htm;
access_log /var/log/nginx/my-site.com.log;
error_log /var/log/nginx/my-site.com-error.log error;
charset utf-8;
location /api {
root /var/www/my-site.com/backend;
try_files $uri $uri/ /index.php$is_args$args;
}
location / {
root /var/www/my-site.com/frontend;
try_files $uri /index.html;
}
location ~* \.php$ {
add_header X-script "$document_root$fastcgi_script_name" always;
try_files $fastcgi_script_name =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
Any help would be much appreciated.
The web root of a Symfony 4 project must include the public subfolder. I am not using NGINX but I think this is the correct configuration:
location /api {
root /var/www/my-site.com/backend/public;
In the following vhost, the most important changes I made are :
commented out index directive in server block : it is handled directly in locations blocks
added a slash after location /api/ and remove unnecessary $uri/ in the same api location block
moved the php_fpm logic to index.php location block : you want all requests to be passed to front controller in Symfony app
For the same reason, moved the 404 logic to a general php block, which will handle any other php file request
server {
listen 80 default_server;
access_log /var/log/nginx/my-site.com.log;
error_log /var/log/nginx/my-site.com-error.log error;
charset utf-8;
location /api/ {
root /var/www/my-site.com/backend;
try_files $uri /index.php$is_args$args;
}
location / {
root /var/www/my-site.com/frontend;
try_files $uri /index.html;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param HTTPS off;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
Last, I bet you'll have to add symfony public folder into api location block root directive.
This vhost was tested fine on my localhost with following tree.
api_test
- backend
- index.php
- frontend
- index.html
I can successfully access to
backend/index.php from api_test.dv/api
frontend/index.html from api_test.dv/
Kojos answer is excellent, but to make it completely functional a root directive needs to be added under server or an error message “primary script unknown” will be observed. This is almost always related to a wrongly set SCRIPT_FILENAME in the nginx fastcgi_param directive.
# Nginx configuration
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name ${NGINX_HOST};
root /var/www/html/backend/public;
access_log /var/log/nginx/access_log.log;
error_log /var/log/nginx/error.log error;
charset utf-8;
location / {
root /var/www/html/frontend/build;
try_files $uri /index.html;
}
location /api {
alias /var/www/html/backend/public;
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}

Nginx multiple locations each with its own root

server {
listen 80;
server_name ~^(?<cc>.+?).local.solar.bc.digital$;
client_max_body_size 1m;
root /home/vagrant/sites/$cc/_www/;
index index.html index.htm index.php;
error_page 404 /index.php;
access_log /var/log/nginx/$cc-access.log;
error_log /var/log/nginx/$cc-error.log;
charset utf-8;
sendfile off;
location / {
root /home/vagrant/sites/$cc/_www/php/;
try_files $uri $uri/ /index.php?$query_string;
}
location /shop/ {
# root /home/vagrant/sites/$cc/_www/bcshop/;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param APP_ENV dev;
fastcgi_param PLATFORM_ENVIRONMENT local;
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
location ~ /\.ht {
deny all;
}
}
Right, given the config above. If you see what I am trying to do, know that it's not working!
Some details:
I have the general 'root', because without I get errors.
This is on a local VM used for development. We have a deployment tool locally that for each project (refer to $cc variable in the config above), it can deploy up to two apps. Not necessarily both are deployed for each project. The first app is deployed in /home/vagrant/sites/$cc/_www/php, the second one in /home/vagrant/sites/$cc/_www/bcshop (but I can make it shop - you'll see why from the config)
Both apps run on Drupal, so the way the load is the same. I simply can't make them work. I get file not found for both with most of the small variants I've tried.
When I place the second app in /home/vagrant/sites/$cc/_www/shop (rather than /home/vagrant/sites/$cc/_www/bcshop) I can get its homepage to load, but nothing else.
When I disregard the second app, and concentrate on the first, I can simply have a general root set to /home/vagrant/sites/$cc/_www/php and remove the local root from location /. That works. But it doesn't when it's specified as local root. In this case, in fact, I get this error in the logs: "FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream". This only for the first app.
If you wonder why the general root is set to that value, it's because I get an error in the logs if the general root is not verifiable for the location being matched. Makes sense?
I think I've covered pretty much all of what I've done in summary.
Thoughts?
I am not an expert at all with nginx, so I am going by trial and errors, with the help of the docs and other questions answered on here. But so far, no joy.
Thanks all.
You have PHP files in both the _www/bcshop/ path and the _www/php/ path. If you would like to use one common location ~ \.php$ for both applications, then the URI for each application will need to be prefixed by /bcshop and /php respectively. That is, both applications appear to run in a subdirectory.
I suspect that you would like to use /shop prefix for one application, and the / prefix for the other. in which case two location ~ \.php$ blocks will be required.
One application runs from the server root:
root /home/vagrant/sites/$cc/_www/php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
...
}
And one application runs with a URI prefix of /shop but located in the subdirectory _www/bcshop:
location ^~ /shop {
rewrite ^/shop(?:/(.*))?$ /bcshop/$1 last;
}
location ^~ /bcshop/ {
internal;
root /home/vagrant/sites/$cc/_www;
try_files $uri /shop/index.php?$query_string;
location ~ \.php$ {
try_files $uri /shop/index.php;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
...
}
}
The ^~ modifier ensures that the location block takes precedence over the regular expression location block above. See this document for details.
Although the external URI prefix is /shop, it is silently rewritten to /bcshop so that we can continue to use the root directive. There is an alias directive, but it has issues with try_files and is tricky to use with PHP.
Based on the answer by #RichardSmith, I come up with my own variant (which is working fine). Simply because repeating the block for location ~ \.php$ was doing my head in.
...
...
root /home/vagrant/sites/$cc/_www/;
...
...
location / {
set $actual_root /home/vagrant/sites/$cc/_www/php/;
set $fastcgi_index /index.php;
root $actual_root;
try_files $uri $uri/ $fastcgi_index?$query_string;
}
location /shop/ {
set $actual_root /home/vagrant/sites/$cc/_www/;
set $fastcgi_index /shop/index.php;
root $actual_root;
try_files $uri $uri/ $fastcgi_index?$query_string;
}
location ~ \.php$ {
root $actual_root;
fastcgi_index $fastcgi_index;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $actual_root/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param APP_ENV dev;
fastcgi_param PLATFORM_ENVIRONMENT local;
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
...
...

How to install symfony2 app in a subdirectory in nginx

I need to install multiple symfony2 applications on the same host but on different subdirectories (or location blocks).
With this config nginx throws a "file not found" or redirect loop message when trying to access any url.
Example:
/login -> /base/login
/app1 -> /base/app1
/app2 -> /base/app2
Current Config:
root /base/default; #Points to an empty directory
# Login Application
location ^~ /login {
alias /base/login/web;
try_files $uri app_dev.php;
}
# Anything else
location ~ ^/([\w\-]+) {
alias /base/$1/web;
try_files $uri app_dev.php;
}
location / {
# Redirect to the login
rewrite ^ /login redirect;
}
# Handle PHP
location ~ \.php$ {
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param HTTPS off;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
After hours spended to find this (sf2 doc doesn't explain how cgi parameters are needed and interpreted, you need to go through Request.php to understand), so I share this.
This is a config which seems ok with sf2 in a directory {subdir} (and web access to others files than {subdir}/web/* prohibited).
It works for me with php-fpm (socket).
Of course, replace "{subdir}" by your /path/from/docroot/to/symfony_root/
dev environnement can be choosen by adding "dev" to "{subdir}" (since app_dev.php in the url no longer works with this conf)
server {
# general directives
location ~ ^/{subdir}(/.*)$ {
try_files /{subdir}/web$1 #sf2;
}
location ~ ^/{subdir}dev(/.*)$ {
expires off;
try_files /{subdir}/web$1 #sf2dev;
}
location #sf2 {
expires off;
fastcgi_pass {your backend};
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/{subdir}/web/app.php;
fastcgi_param SCRIPT_NAME /{subdir}/app.php;
fastcgi_param REQUEST_URI /{subdir}$1;
}
location #sf2dev {
expires off;
fastcgi_pass {your backend};
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/{subdir}/web/app_dev.php;
fastcgi_param SCRIPT_NAME /{subdir}dev/app_dev.php;
fastcgi_param REQUEST_URI /{subdir}dev$1;
}
# other location directives
# if some others apps needs php, put your usual location to cactch php here
}
I Hope it helps (and there isn't any misconfiguration), given without any guarantee...
Of course you can pick out prod/dev conf if you don't need. And you can use var and only one #sf2 location instead :
set $sf2_root /{subdir};
location ~ ^/{subdir}(/.*)$ {
set $sf2_prefix /{subdir};
set $sf2_ctrl app.php;
try_files $sf2_root/web$1 #sf2;
}
location ~ ^/{subdir}dev(/.*)$ {
set $sf2_prefix /{subdir}dev;
set $sf2_ctrl app_dev.php;
expires off;
try_files $sf2_root/web$1 #sf2;
}
location #sf2 {
expires off;
fastcgi_pass {your backend};
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$sf2_root/web/$sf2_ctrl;
fastcgi_param SCRIPT_NAME $sf2_prefix/$sf2_ctrl;
fastcgi_param REQUEST_URI $sf2_prefix$1;
}
Here is a simpler configuration for symfony2 on the "/front/" subdirectory.
Route generation and assets work fine.
The configuration
set $frontRoot /your/project/path/web;
set $sfApp app_dev.php; # Change to app.php for prod
location /front/ { # Static files
root $frontRoot;
rewrite ^/front/(.*)$ /$1 break;
try_files $uri #sfFront;
}
location #sfFront { # Symfony
fastcgi_pass phpfcgi;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $frontRoot/$sfApp;
fastcgi_param SCRIPT_NAME /front/$sfApp;
fastcgi_param REQUEST_URI /front$uri?$args;
fastcgi_param HTTPS off;
}
Some explanation
The trick is to make symfony believe app.php script is in /front/, so it generates routes and assets with this path.
I looked at what apache was giving to MOD-PHP to use the same values.
SCRIPT_FILENAME: The absolute path to the PHP file. Here, it is always /your/project/path/app_dev.php
REQUEST_URI: The URI the user entered. Here, we have to manually re-add /front at the begining of the path as it was removed by the file serving location (via rewrite ^/front/(.*)$ /$1 break;)
SCRIPT_NAME: The value is /front/app_dev.php. This is the most important part. Symfony will cut app_dev.php and prepend /front to all its routes.
Based on dcaillibaud's answer, here's a more generic configuration,
allowing to support multiple Symfony (version 2 or 3) projects under the root web path, using some regular expression magic:
server {
# other specific directives...
root /var/www;
location ~ ^/([^/]+)/dev(/.*)$ {
location ~ \.php { deny all; }
set $sf2_root /$1;
set $sf2_prefix /$1/dev;
set $sf2_ctrl app_dev.php;
expires off;
try_files $sf2_root/web$2 #sf2;
}
location ~ ^/([^/]+)(/.*)$ {
location ~ \.php { deny all; }
set $sf2_root /$1;
set $sf2_prefix /$1;
set $sf2_ctrl app.php;
try_files $sf2_root/web$2 #sf2;
}
location #sf2 {
expires off;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$sf2_root/web/$sf2_ctrl;
fastcgi_param SCRIPT_NAME $sf2_prefix/$sf2_ctrl;
fastcgi_param REQUEST_URI $sf2_prefix$2;
}
}
So basically, you'll have:
www.domain.com/project pointing to your PROD environment
and
www.domain.com/project/dev pointing to your DEV environment
Please replace the line:
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
with your appropriate backend
This can also be easily adapted for newer Symfony projects using index.php script instead of app(_dev).php, changing the web/public path, and setting some ENV variables.
I think this approach, answers better the original question.

Icinga+Nginx configuration

I installed Icinga 1.6.0beta and tried to install it's new web interface using this manual. But it was written for Apache. So I used the following configuration file for nginx to run the interface, but no success. I get directory listing denied in error logs. Any help?
Note: /data/developers/icinga-web symlinked to /usr/local/icinga-web
server {
server_name developers.example.com;
access_log /var/log/nginx/dev.access.log;
error_log /var/log/nginx/dev.error.log;
root /data/developers;
location / {
index index.html index.htm index.php;
}
location /icinga-web/js/ext3/ {
alias /usr/local/icinga-web/lib/ext3/;
}
location /icinga-web/ {
if (!-e $request_filename) {
rewrite ^(/icinga-web)(/.*)$ /icinga-web/index.php?$2 last;
}
}
try_files $uri $uri/ /icinga-web/index.php?$args;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(/icinga-web)(/.*)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
I ran into the same problem. I had to put the following line:
security.limit_extensions = .php .php5 .cgi
Into the php-fpm pool configuration file.
Of course, after I put that, I now get the following line error:
Parse error: syntax error, unexpected '<' in /usr/local/icinga/sbin/tac.cgi on line 313
But hey, progress!
Ran into almost the same problems years later, better late than never. (I marked the variables you have to set yourself with " % ")
location #icinga {
include fastcgi.conf;
fastcgi_temp_path fastcgi;
fastcgi_pass %YOUR_SOCKET%;
fastcgi_param SCRIPT_NAME /icingaweb2/index.php;
fastcgi_param SCRIPT_FILENAME %ICINGA_WEB_LOCATION%/index.php;
fastcgi_param ICINGAWEB_CONFIGDIR %ICINGA_CONFIG_DIR%;
}
location /icingaweb2 {
alias %ICINGA_WEB_LOCATION%/public;
try_files $uri #icinga;
}

Resources