i'm trying to configure nginx to serve several releases of one symfony project.
Releasefolder structure:
/var/www/my-project/releases/24/
/var/www/my-project/releases/46/
/var/www/my-project/releases/47/
I'd like to call a URL like "http://my-server/my-project/release/47" which should access /var/www/my-project/releases/47/web/app.php on the server.
I tried for a while now but couldn't find the final solution, any help would be great!
My last try:
server {
server_name my-server;
location / {
# try to serve file directly, fallback to app.php
try_files $uri $uri$2app.php$is_args$args;
}
location ~ /my-project/release/([-a-zA-Z0-9]+)/app\.php(/|$) {
root /var/www/my-project/releases/$1/web;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/app.php;
fastcgi_param HTTPS off;
error_log /var/log/nginx/my-project_$1_error.log;
access_log /var/log/nginx/my-project_$1_access.log;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
}
This config produces following error:
[error] 2272#0: *169 rewrite or internal redirection cycle while internally redirecting to "/my-project/release/47app.phpapp.phpapp.phpapp.phpapp.phpapp.phpapp.phpapp.phpapp.phpapp.phpapp.php"
You are missing a root directive in your server container -- is /var/www the default on your architecture? Otherwise, add a root directive:
root /var/www;
try_files is failing for find a match and will rewrite the URL by appending app.php to it. The resulting URL does not match your other location block, so it gets rewritten again and again.
The final term on your try_files directive is wrong. You have $2 where /web/ should be (probably inherited from a previous experiment).
Using try_files to make a general rewrite is a bad idea, as any mistyped URL could lead to a rewrite loop. Try:
location / {
rewrite ^(/my-project/release/[-a-zA-Z0-9]+)$ $1/app.php;
}
I changed the config to this:
server {
server_name my-server;
root /var/www;
location / {
rewrite ^(/my-project/release/[-a-zA-Z0-9]+)$ $1/app.php;
}
location ~ /my-project/release/([-a-zA-Z0-9]+)/app\.php(/|$) {
alias /var/www/my-project/releases/$1/web;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/app.php;
fastcgi_param HTTPS off;
error_log /var/www/my-project/releases/$1/app/logs/nginx_error.log;
access_log /var/www/my-project/releases/$1/app/logs/nginx_access.log;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
}
Now a call like "http://my-server/my-project/release/47" points correctly to "/var/www/my-project/releases/47/web/app.php".
The problem is now that the url "my-project/release/47" arrives at symfony router which can't find a route to this url.
What is now the right way to keep the url showing up like "//my-server/my-project/release/47" at browser but arrives at symfony as "//my-server/"?
Thank you all for your help, unfortunately i couln't get it working. I think i have to learn more about nginx configuration generally to be able to handle such problems, before i can use it in production.
My workaround for my problem is to create an own nginx conf per release. The file will be created at build process, is then transfered to the webserver, copied to /etc/nginx/conf.d/[releasename].conf and activated by sudo service nginx reload.
A deinstallation script within the release dir removes sources and config, when release no longer needed.
Related
I want to setup symfony with nginx and this config is working fine
server {
listen 80;
root /src/web;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app.php$is_args$args;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
error_log /var/log/nginx/symfony_error.log;
access_log /var/log/nginx/symfony_access.log;
}
However i also want that on my server i should also be able to access files via app_dev.php and app_test.php as well
so far with above config. http://127.0.0.1/api/check is working fine
but i also want
http://127.0.0.1/app_dev.php/api/check and http://127.0.0.1/app_test.php/api/check to work as well.
Currently its gives me 404 error
Assuming your using this for development you can list each file (Environment) in a capturing group () and separate with | which basically means "or".
location ~ ^/(app|app_dev|app_test)\.php(/|$) {
....
}
It is important not to use this example on a production server, as it is completely unsecure.
On a production server your current conf, is correct to only allow app.php.
For more information you can use description from symfony and nginx official docs.
As you can see you should add some lines into your nginx conf file:
location ~ ^/(app_dev|config)\.php(/|$) {
...
}
In case you also need app_test.php, then it should be changed a little bit. Just by including the file name:
location ~ ^/(app_dev|app_test)\.php(/|$) {
...
}
But please have a note:
In production, don't include this and don't deploy app_dev.php or app_test.php
Also it would be better to have following configuration before error_log ...:
location ~ \.php$ {
return 404;
}
I have created some Laravel routes with they have ".php" extention, such as
Route::get('/api/send.php', function(){
echo 'Hi There';
});
But when I open the route it shows 404 error in Nginx server... That is Nginx configurations
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/laravel/public;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name xxx.xxx.xxx.xxx;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
What is the problem? I have used the same code it worked before..
Thanks
SOLVED
It solved by changing
try_files $fastcgi_script_name =404;
in /etc/nginx/snippets/fastcgi-php.conf to
try_files $fastcgi_script_name /index.php?$query_string;
This is a very common problem with nginx configured to serve PHP applications, especially Laravel. You can reproduce it on sites like laravel.com, e.g: laravel.com/example.php.
The default configuration (what you're probably using in snippets/fastcgi-php.conf) is this:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
And fastcgi_script_name is...
request URI or, if a URI ends with a slash, request URI with an index file name configured by the fastcgi_index directive appended to it. This variable can be used to set the SCRIPT_FILENAME and PATH_TRANSLATED parameters that determine the script name in PHP. For example, for the “/info/” request with the following directives
That means, when a request URI contains .php it is treated as if it is a request for a PHP file, and if that PHP file doesn't exist an error is returned by nginx -- it never reaches your application.
The solution is to force fastcgi_script_name to always equal your application's entry point, in this case that's index.php. You can either edit snippets/fastcgi-php.conf or add it into your location block like this:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
Your application will now receive every request, including those that have .php in the path.
Need some help installing Magento 2.0.2 on nginx 1.9.3 with php-fpm currently I'm using the default configuration provided by Magento ( https://github.com/magento/magento2/blob/develop/nginx.conf.sample ).
The issue that's happening is when accessing /setup after unpacking it I'm presented with a 403 on "setup/index.php/navigation" as well as other URLs the page attempts to access.
I've realized the issue behind this is that it's not passing "navigation" as an argument to the index.php file and is actually looking for "index.php/navigation" as a file and attempting to pass that to php5-fpm which results in security.limit_extensions to be triggered causing the 403.
So the question becomes how do I get requests to process properly?
E.X. when the javascript being rendered by the setup index.php requests index.php/navigation how do I ensure it's passed to index.php as an argument instead of trying to look for a file at "index.php/navigation" as if index.php were a directory.
This problem become more and more common as I can see. It seems that fastcgi_split_path_info needs to define. Try to changed nginx.conf.sample /setup location block (I pointed to solution-code with ##) to:
location /setup {
root $MAGE_ROOT;
location ~ ^/setup/index.php {
### This fixes the problem:
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
################################
fastcgi_pass fastcgi_backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ ^/setup/(?!pub/). {
deny all;
}
location ~ ^/setup/pub/ {
add_header X-Frame-Options "SAMEORIGIN";
}}
I am using Symfony2 (PHP) framework for my project and is having a small problem with regards to configuring my NGINX to catch request going to a 3rd party library I placed under "web" directory.
This is my configuration
server {
listen 80;
server_name test.com;
root /var/www/my-symfony-project/web;
rewrite ^/app\.php/?(.*)$ /$1 permanent;
location / {
index app.php;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|app_dev|config)\.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;
}
}
As you may have noticed that the root is pointed in "/var/www/my-symfony-project/web" directory.
Now, the problem is that I have this "some-plugin" folder inside the "web" directory and there are PHP files from there that are not handled by the Symfony2 routing.
I actually made it work when I have the following "location" block inside the "server" block illustrated above.
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
}
It seems okay having this type of configuration at first but we realized that it accepts request to any "*.php" file to which we evaluated as a security breach.
Any suggestions?
Allowing access to .php files is usually not considered dangerous or a security breach, as long as the PHP files are executed and not served in their source form and, of course, don't print any sensitive information.
If either of the former are not the case, you should probably change your setup or your code.
Anyway, you should be able to restrict the .php file handling to /var/www/my-symfony-project/web/some-plugin by using the following as location:
location ~ ^/var/www/my-symfony-project/web/some-plugin/.*\.php$ {
# your rules here
}
This should match all files whose path starts with /var/www/my-symfony-project/web/some-plugin/ and end with .php in upper or lower case.
I tried to learn and configure phalcon by testing INVO sample application
It appears that the tutorial doesn't include nginx config for the testing so that I got some difficulty to test the sample application.
I used nginx as the web server, I took nginx configuration from here
Here is my nginx config:
server {
listen 80;
server_name local.phalcon.dev;
access_log /Users/mylocal/www/log/phalcon.access.log;
error_log /Users/mylocal/www/log/phalcon.error.log;
index index.php index.html index.htm;
set $root_path '/Users/mylocal/www/phalcon/current';
root $root_path;
try_files $uri $uri/ #rewrite;
location #rewrite {
rewrite ^/(.*)$ /index.php?_url=/$1;
}
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index /index.php;
include /usr/local/etc/nginx/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 SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
root $root_path;
}
location ~ /\.ht {
deny all;
}
}
Looking at the tutorial, I believe the structure is like this:
webroot
invo
app
...
public
index.php
...
...
which means, webroot is my /Users/mylocal/www/phalcon/current
and I should be able to access it with this url http://local.phalcon.dev/invo
It lead to 403 forbidden which is understandable because it appears that we should rewrite path from webroot/invo to webroot/invo/public
I did some trial and error changing the configuration but found no luck, can somebody help me to configure the nginx config for that tutorial? (which means accessing it from http://local.phalcon.dev/invo)
PS:
I was able to access it by changing the $root_path into /Users/mylocal/www/phalcon/current/invoice/public
and changing the $url->setBaseUri($config->application->baseUri); into $url->setBaseUri('/'); in invo/public/index.php
but that means I accessed it from url http://local.phalcon.dev NOT http://local.phalcon.dev/invo
To access it via http://local.phalcon.dev/invo instead of http://local.phalcon.dev all you need to do now is to configure the routing. I think in your case you simply need to set the base uri as per this example:
//Setup a base URI so that all generated URIs include the "tutorial" folder
$di->set('url', function(){
$url = new \Phalcon\Mvc\Url();
$url->setBaseUri('/tutorial/');
return $url;
});
I'm also getting a feeling that you also want to use http://local.phalcon.dev for other Phalcon apps? If that's the case then it will not work. All requests are forwarded to index.php, which rules out what to do. You can create multi-module app, but you can't have different apps sittings on the same domain (without serious pain).
the only directory which should be available via url is public. You home direcotry must end with public something like:
/Users/mylocal/www/phalcon/public
and you will be able to use base dir of /:
$di->set('url', function(){
$url = new \Phalcon\Mvc\Url();
$url->setBaseUri('/');
return $url;
});
of course you can use whatever name for your public dir, but not recommended, because if you will want to use phalcon's devtools, they are working with home dir called "public"
Please check app/config/config.ini file. There is a "baseUri" section.
1. nginx root_path should be "webroot/invo/public.
2. phalcon code: app/config/config.ini -> baseUri = /
3. url: local.phalcon.dev