Nginx with multiple symfony2 applications
I've seen a lot of people have a problem setting up one nginx server to have multiple symfony2 applications. However, no one wanted the same thing and had the same problem as me. I want to make multiple applications on the same domain. One main application will respond directly to the domain, while the rest will be in the alias subdirectory. With the scheme:
http://mydomain/ -> main app
http://mydomain/subdir1 -> another app
http://mydomain/subdir2 -> yet another app
I tried to do this and the main app works fine. But subdirectories most of the time are intercepted by the main application which throws 404. When I try to add app.php to the subdirectory url (for example http://mydomain/subdir1/app.php/my/route
) the server returns 404.
This is what I have been doing so far:
server {
listen 80;
server_name mydomain;
root /server/www/main-app/web;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app.php$is_args$args;
# PROD
location ~ ^/app\.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;
}
}
location /subdir1/ {
alias /server/www/other-app1/web;
# try to serve file directly, fallback to app.php
try_files $uri /server/www/other-app1/web/app.php$is_args$args;
# PROD
location ~ ^/other-app1/app\.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;
}
}
}
Thank you for your help!
EDIT 12/26/2014: For those who don't understand what exactly I want: I want to host multiple symfony2 applications on the same domain name without a subdomain. Without a subdomain, I have to use a subdirectory. Before that I tried nginx, I used Apache2 and it was easy to do the trick with Alias.
I did more searching and found out that "alias" and "try_files" are not good friends (see this bug report: http://trac.nginx.org/nginx/ticket/97 ). So I activated debug mode and a lot of tests. Now I have almost done it. The main applications no longer hijack subdirectories, and the rest of the applications respond. But those other apps responded with 404s, so I looked at their logs. And I found out that they were looking for a URL pattern with a subdirectory in it. For example, they searched /subdir1/login
instead of /login
. So this is my new config:
server {
listen 80;
server_name mydomain;
root /server/www/main-app/web;
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location /subdir1/ {
set $root "/server/www/other-app1/web";
# try to serve file directly, fallback to app.php
try_files $uri @rewriteapp;
}
location / {
index app.php;
set $root "/server/www/main-app/web";
# try to serve file directly, fallback to app.php
try_files $uri @rewriteapp;
}
# PROD
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
As you can see, the trick was to not use $ document_root for SCRIPT_FILENAME and I created my own instead. I don't know how the symfony2 router looks at the template in the url, but with my previous configuration (Apache2) I never had this problem. So maybe this is another trick to send the correct path to the script app.php.
Thanks again for your help!
source to share
After many hours of debugging, I finally solved the problem. This is my final config:
server {
listen 80;
server_name mydomain;
root /server/www;
location @rewriteMainApp {
rewrite ^(.*)$ /app.php/$1 last;
}
location @rewriteOtherApp1 {
rewrite ^(.*)$ /subdir1/app.php/$1 last;
}
location /subdir1 {
alias /server/www/other-app1/web;
index app.php;
set $subfolder "other-app1/web";
try_files $uri @rewriteOtherApp1;
}
location / {
root /server/www/main-app/web;
index app.php;
set $subfolder "main-app/web";
try_files $uri @rewriteMainApp;
}
# PROD
location ~ /app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$subfolder/app.php;
}
}
Thank you all for your help!
source to share
This solved it finally for me (thanks to Claros) after a million things I've tried. Likewise, URLs look like this:
/ Abc / path / to / endpoint
but not /abc/app.php/path/to/endpoint. Config.php and App_dev.php if specified as plain text in the web folder.
I'm still trying to figure out to get / abc to work (/ abc / works but / abc not). There I am getting a Symfony exception that route / abc cannot be found.
Also some font urls (for bootstrapping) are still wrong, but styles, routing, etc. work.
location /abc {
set $subpath /abc;
set $sfPath /var/www/abc/current/web;
alias $sfPath;
try_files $uri @rewrite;
}
location / {
set $subpath "";
set $sfPath /var/www/def/current/web;
alias $sfPath;
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*)$ $subpath/app.php$1 last;
}
location ~ /app\.php(/|$) {
internal;
include /etc/nginx/fastcgi_params;
fastcgi_index app.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param DOCUMENT_ROOT $sfPath;
fastcgi_param SCRIPT_FILENAME $sfPath/app.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
}
If you want the app_dev.php app to work in a demo environment, the best way I've found is the following (to have a php block inside a location block every time):
location /xyz {
set $subpath /xyz;
set $sfPath /var/www/xyz/current/web;
alias $sfPath;
try_files $uri @rewrite;
#Change the match for app_dev.php to work
location ~ /(app|app_dev|config)\.php(/|$) {
#Drop the internal for App_dev.php to work
#internal;
include /etc/nginx/fastcgi_params;
fastcgi_index app.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param DOCUMENT_ROOT $sfPath;
fastcgi_param SCRIPT_FILENAME $sfPath/app.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
}
}
source to share
Edit your apps with a different server tag in the site-enabled file.
For example:
#Site 1
server {
#Configuration
}
server {
#Configuration 2
}
server {
#Configuration 3
}
Configuration example:
server {
listen 80;
root /var/www/yourdomain.com/web;
server_name yourdomain.com www.yourdomain.com;
add_header X-UA-Compatible "IE=Edge,chrome=1";
location ~* \.(css|js|gif|jpe?g|png)$ {
expires 1y;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app_dev.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;
}
error_log /var/log/nginx/yourdomain.com.error.log;
access_log /var/log/nginx/yourdomain.com.access.log;
}
server {
listen 80;
root /var/www/yourdomain.com/anotherproject/web;
server_name sub1.yourdomain.com www.sub1.yourdomain.com;
add_header X-UA-Compatible "IE=Edge,chrome=1";
location ~* \.(css|js|gif|jpe?g|png)$ {
expires 1y;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app_dev.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;
}
error_log /var/log/nginx/sub1.yourdomain.com.error.log;
access_log /var/log/nginx/sub1.yourdomain.com.access.log;
}
source to share