Skip to content

Instantly share code, notes, and snippets.

@mreschke
Last active October 22, 2024 12:23
Show Gist options
  • Save mreschke/27bfafb84add38d3bab8 to your computer and use it in GitHub Desktop.
Save mreschke/27bfafb84add38d3bab8 to your computer and use it in GitHub Desktop.
Nginx config for multiple laravel sites based on /api/v1 url paths
# This config will host your main [Laravel] GUI application at /, and any additional [Lumen] webservices at /api/v1 and /api/v2...
# This also works perfectly for all static file content in all projects
# This is full of debug comments so you can see how to print debug output to browser! Took me hours to nail this perfect config.
# Example:
# http://example.com - Main Laravel site as usual
# http://example.com/about - Main Laravel site about page as usual
# http://example.com/robots.txt - Main Laravel site static content as usual
# http://example.com/api/v1 - Lumen v1 api default / route
# http://example.com/api/v1/ - Lumen v1 api default / route
# http://example.com/api/v1/users - Lumen v1 api users route
# http://example.com/api/v1/robots.txt - Lumen v1 api static content
# http://example.com/api/v2 - Lumen v2 api default / route
# http://example.com/api/v2/ - Lumen v2 api default / route
# http://example.com/api/v2/users - Lumen v2 api users route
# http://example.com/api/v2/robots.txt - Lumen v2 api static content
# Handles main / site plus plus additional /api/v1 sites
server {
# Listing port and host address
listen 80;
#listen 443;
server_name example.com;
# SSL certificates
#ssl on;
#ssl_certificate /etc/nginx/ssl/example.com.pem;
#ssl_certificate_key /etc/nginx/ssl/example.com.key;
# Enables server-side protection from BEAST attacks
# http://blog.ivanristic.com/2013/09/is-beast-still-a-threat.html
#ssl_prefer_server_ciphers on;
# Disable SSLv3(enabled by default since nginx 0.8.19) since it's less secure then TLS http://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_3.0
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Ciphers chosen for forward secrecy and compatibility
# http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
#ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# Default index pages
index index.php;
# Default character set
charset utf-8;
# Turn off /var/log/nginx/access.log writes
access_log off;
log_not_found off;
# Send file is an optimization, but does not work
# across unix sockets which I use for php fpm so is best
# used for local static content only
sendfile off;
# Dont send the nginx version number in error pages and server header
server_tokens off;
# Root for / project
root /var/www/example/public;
# If you have no root project, re-route /favicon and /robots
#location /favicon.ico { try_files $uri /api/v1$uri; }
#location /robots.txt { try_files $uri /api/v1$uri; }
# Handle main root / project
location / {
#deny all;
try_files $uri $uri/ /index.php?$args;
}
# Handle api/v1 sub project
location /api/v1 {
# Debug output
#return 200 $args; add_header Content-Type text/plain;
# Root for this sub project
root /var/www/api-v1/public;
# Rewrite $uri=/api/v1/xyz back to just $uri=/xyz
rewrite ^/api/v1/(.*)$ /$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 piont, $uri is /index.php, $args=any GET ?key=value
# and $request_uri = /api/v1/xyz. But we DONT want to pass
# /api/v1/xyz to PHP-FPM, we want just /xyz to pass to
# fastcgi REQUESTE_URI below. This allows laravel to see
# /api/v1/xyz as just /xyz in its router. So laravel route('/xyz') responds
# to /api/v1/xyz as you would expect.
set $newurl $request_uri;
if ($newurl ~ ^/api/v1(.*)$) {
set $newurl $1;
root /var/www/api-v1/public;
}
# Debug output
#return 200 $args; add_header Content-Type text/plain;
#return 200 $uri; add_header Content-Type text/plain;
#return 200 $document_root; add_header Content-Type text/plain;
#return 200 $request_uri; add_header Content-Type text/plain;
#return 200 $newurl; add_header Content-Type text/plain;
# No need for rewrite, as we will use $newurl above.
#rewrite ^/api/v1/index.php(.*)$ /$1 break;
#rewrite ^/index.php(.*)$ /$1 break;
#return 200 $uri; add_header Content-Type text/plain;
# Pass all PHP files to fastcgi php fpm unix socket
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#fastcgi_pass unix:/var/run/php5-fpm.sock; #debian php5
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; #debian php7
fastcgi_index index.php;
include fastcgi_params;
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;
}
}
# Redirect all http traffic to https
#server {
# listen 80;
# server_name rci-api.dynatronsoftware.com;
# return 301 https://$host$request_uri;
#}
@iceberg1369
Copy link

thanks, you saved my life!

@anil1712
Copy link

Thanks, Its very userful

@manjufy
Copy link

manjufy commented Nov 20, 2017

Awesome!. Thank you

@manjufy
Copy link

manjufy commented Nov 25, 2017

I tried this. I have two Laravel apps, both are websites
First app works fine... however in the second app, all css are pointing back to first url

Ex;
https://site1.com
https://site1.com/secondsite

https://site1.com/secondsite/css/all.css --> its 404
Unable to serve the resource files for second site

@vrusua
Copy link

vrusua commented Feb 3, 2018

@manju16832003

First app works fine... however in the second app, all css are pointing back to first url

I'm struggling with the same issue... Any solution?

Cheers,
Ruslan

@benlbot
Copy link

benlbot commented Feb 20, 2018

Thanks !

@benlbot
Copy link

benlbot commented Feb 20, 2018

@manju16832003 @vrusua

location ~ \.php$ {
                if ($newurl ~ ^/api/v1(.*)$) {
                        set $newurl $1;
                        root /var/www/api-v1/public;
                }
                if ($newurl ~ ^/api/v2(.*)$) {
                        set $newurl $1;
                        root /var/www/api-v2/public;
                }
                ...
}

I'm not an expert, it's an intuition

@leovolpatto
Copy link

Thank you!

@burgerleo
Copy link

Thank you! you saved my life!

@maxflex
Copy link

maxflex commented Feb 17, 2020

Thank you

@erssebaggala
Copy link

Thanks a bunch! Exactly what I have spent the last couple of hours looking for!!!

@zhaozhentao
Copy link

Thank you!

@ptheofan
Copy link

ptheofan commented Feb 3, 2022

wondefull! Thank you!

@Fiwi1265
Copy link

Like

@TranTuanManh
Copy link

nginx return 500 Internal Server Error immediately with any requests include Content-Type: multipart/form-data

Any solution?

@mcorkum
Copy link

mcorkum commented Jan 13, 2023

God bless you.

@DanielKaniu
Copy link

This has helped me a great deal, after some days of researching. Thank you so much.

@ellie-ochieno
Copy link

Lots of thanks form this great work! Saved my day too

@ellie-ochieno
Copy link

@TranTuanManh I advise if already deployed to a live server, alter the following in you .env file APP_ENV=local and APP_DEBUG=true to debug mode so that you can clearly see the actual errors then you'll revert back to safe setting when all error debug is done to APP_ENV=production and APP_DEBUG=false. It help me out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment