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;
}
Related
I want to serve multiple Laravel apps in a single nginx server, the first one has a root directory in /var/www/html/app1, the second one has /var/www/html/app2, and so on. The index.php file of each app is in a subdirectory named /public.
Whenever user calls http://www.mywebsite.com/app1, nginx shoulds return the app1 and if user calls http://www.mywebsite.com/app2, nginx shoulds return the app2.
My current nginx conf file is as below:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location /app1 {
root /var/www/html/app1/public;
index index.php;
}
location /app2 {
root /var/www/html/app2/public;
index index.php;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
But, nginx always returning 404 page result. What's going wrong here?
During one of the deployment on linux server, I came across some sort of your challenge. It was as follow
<base_url> : One Laravel project needs to served on this.
<base_url>/<sub_url> : Another Laravel project needs to be served on this.
Of course this can be extended to any number of Laravel projects which follows <base_url>/<unique_sub_url> concept.
Now let's dive into actual implementation
# Nginx.conf
# App 1(Path: /var/www/html/app1, Url: http://www.mywebsite.com)
# App 2(Path: /var/www/html/app2, Url: http://www.mywebsite.com/app2)
server {
# Listing port and host address
# If 443, make sure to include ssl configuration for the same.
listen 80;
listen [::]:80;
server_name www.mywebsite.com;
# Default index pages
index index.php;
# Root for / project
root /var/www/html/app1/public;
# Handle main root / project
location / {
#deny all;
try_files $uri $uri/ /index.php?$args;
}
# Handle app2 project, just replicate this section for further projects app3, app4
# by just replacing app2 with appropriate tag(app3/app4)
location /app2 {
# Root for this project
root /var/www/html/app2/public;
# Rewrite $uri=/app2/xyz back to just $uri=/xyz
rewrite ^/app2/(.*)$ /$1 break;
# Try to send static file at $url or $uri/
# Else try /index.php (which will hit location ~\.php$ below)
try_files $uri $uri/ /index.php?$args;
}
# Handle all locations *.php files (which will always be just /index.php)
# via factcgi PHP-FPM unix socket
location ~ \.php$ {
# At this point, $uri is /index.php, $args=any GET ?key=value and $request_uri = /app2/xyz.
# But we don't want to pass /app2/xyz to PHP-FPM, we want just /xyz to pass to fastcgi REQUESTE_URI below.
# This allows laravel to see /app2/xyz as just /xyz in its router.
# So laravel route('/xyz') responds to /app2/xyz as you would expect.
set $newurl $request_uri;
if ($newurl ~ ^/app2(.*)$) {
set $newurl $1;
root /var/www/html/app2/public;
}
# Pass all PHP files to fastcgi php fpm unix socket
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Use php fpm sock which is installed on your machine like php7.2, php5.6
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# Here we are telling php fpm to use updated route that we've created to properly
# response to laravel routes.
fastcgi_param REQUEST_URI $newurl;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
# Deny .ht* access
location ~ /\.ht {
deny all;
}
}
Note: When we're using session based laravel setup, all the route generator functions(url(), route()) use hostname www.mywebsite.com as root url, not www.mywebsite.com/app2. To resolve this issue please do following changes in laravel app.
Define APP_URL in .env file as APP_URL="www.mywebsite.com/app2"
Go to RouteServiceProvider which is located at app/Providers/RouteServiceProvider and force laravel to use APP_URL as root url for your app.
public function boot()
{
parent::boot();
// Add following lines to force laravel to use APP_URL as root url for the app.
$strBaseURL = $this->app['url'];
$strBaseURL->forceRootUrl(config('app.url'));
}
Update: Make sure to run php artisan config:clear or php artisan config:cache command to load the updated value of APP_URL.
For windows: Multiple Laravel Applications Using Nginx - Windows
I have been stucked with this for a while. We have a Symfony 2.8 project and I want to deploy it to the cloud. I have properly created the ElasticBeanstalk environment and it works! But I still need to access http://domain/app.php in order to make it work. I managed to delete web/ changing documentDirectory part from URL but app.php is still there.
I have also tried with a new brand project following this:
https://docs.aws.amazon.com/es_es/elasticbeanstalk/latest/dg/php-symfony-tutorial.html
But when I change it to public/ happens to me the same I need to use index.php in the URL
I have modified NGINX conf following:
https://community.bitnami.com/t/how-to-change-default-root/65639/9
https://symfony.com/doc/current/setup/web_server_configuration.html
This is what I added to /etc/nginx/nginx.conf.default
location / {
try_files $uri $uri/ /app.php$is_args$args;
}
location ~ \.php$ {
try_files $uri $uri/ =404;
fastcgi_pass unix:/var/run/php-fpm/www.sock;
fastcgi_index app.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
I have restart nginx service using
sudo service nginx restart
but it remains the same.
I have also tried renaming app.php to index.php just in case. But I need to add /index.php to the URL then.
Any idea?
Use the index nginx directive to make app.php the default handler of http://domain/ requests:
server {
...
index app.php;
# your locations here
}
There are some things you can try.
https://symfony.com/doc/2.8/setup/web_server_configuration.html#nginx
Here you can find a configuration for your project. There you can see that the location is rewritten to the app.php.
location ~ ^/(app_dev|config)\.php(/|$) {
so i would suggest to take the configuration and test it.
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.
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