Reputation: 28529
We have about 30+ client projects(some are vue projects and other are static html projects), each projects have seperate root directory.
For now nginx is config like, each project has a location
.
location ^~ /workspaces/ {
root /var/www/workspace/;
index index.html index.htm;
}
location ^~ /offical/ {
root /var/www/official/;
index index.html index.htm;
}
...
Each time a new client project released, a new location
will add to nginx file. I'm afraid of too many location
in the nginx file will affect the efficiency of nginx.
How can I simplify the nginx config file for all the client projects. For example with one location location ^~ /web/
, then put all the projects under web path.
Upvotes: 2
Views: 1436
Reputation: 602
I usually use dynamic vhosts for ngninx. Therefore you can create a serving directory e.g. /var/www/
and inside define a directory for e.g. every domain of the client projects you want to deploy.
/var/www/domain.tld
/var/www/subdomain.domain.tld
/var/www/otherproject.tld
/var/www/project.tld/public
and then in nginx you define your server-block as follows
server {
# SSL configuration
listen 443 ssl http2 default_server; # managed by Certbot
listen [::]:443 ssl http2 default_server;
set $basepath "/var/www";
server_name ~^(\w+\.)?(?<base>\w+\.\w+)$;
if ( -d $basepath/$host) {
set $rootpath $basepath/$host;
}
if ( -d $basepath/$host/public ) {
set $rootpath $basepath/$host/public;
}
if ( !-d $basepath/$host ) {
set $rootpath $basepath/$base;
return 301 https://$base$request_uri;
}
root $rootpath;
access_log "/var/log/nginx/${host}.access.log";
error_log "/var/log/nginx/error.log" debug;
index index.php index.html index.htm index.nginx-debian.html;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
This first sets the basepath to /var/www
and then tries in order directories in that basepath. If a directory with the domain from which project is accessed exists and serves them from there, if inside is a public folder this one is preferred. If both are not available it redirects to another defined URL.
Furthermore, for every host a different access.log
is generated. Unfortunately for the error.log
this does not work, hence all errors are gathered in the common error.log
.
for specific files you can then filter for extensions etc. to specify how they are served, in the example above of PHP
-files, those are served using the php7.2-fpm
.
Upvotes: 1
Reputation: 27218
The best practice is to use separate domain names for each app. This is important from the security perspective, to guard against a cross-site scripting vulnerability in one app having any ill effects on all the other apps, and cookie management.
However, from the performance perspective, nginx is already highly efficient for such common use cases that you shouldn't worry about having a few extra location
or server_name
directives:
location
I'd imagine that the prefix-based location
search would be done on a prefix-based search tree — https://en.wikipedia.org/wiki/Trie — e.g., it would be highly efficient, where, effectively, each input character in the URL would only be examined once, and each level on the tree would only have a certain limited number of branches.
If you're instead move to use a regex-based approach, then that would be noticeable slower (at least from the performance analysis, you probably won't notice any difference in real use), because then each regular expression would have to be re-evaluated, potentially on the whole input, until a match is found; the complexity being a multiple of the number of regular expressions, times the size of the input URL.
server_name
If you instead move to a server
-based definition, based on non-regex server_name
specifications, then the matching would be done through a hash-table, which, likewise, is a very efficient operation, where the search would take constant time even on an infinite number of individual server
definitions.
Which one is more efficient, location
or server_name
? It is difficult to say for sure without getting into too many details; but I'd imagine that a hash-based search would be more friendly insofar as CPU branch prediction is concerned — https://en.wikipedia.org/wiki/Branch_predictor; but this is getting really into the weeds here, you don't really need to worry about these sorts of things for a webapp. However, I'd still recommend moving to a server-based configuration for security reasons, even if the extra performance benefits are negligible.
tl;dr: nginx is already highly efficient for your use case as-is, and no further optimisation is required; the best you could do is to make sure that you don't use any regex-based location
directives (either at all, or use a ^~
modifier for your prefix-based location
directives), because those would be slower than the prefix-based ones; it would also be advisable to switch to server-based configuration for extra security.
Upvotes: 4