代码之家  ›  专栏  ›  技术社区  ›  Alex

将多个nginx配置合并为一个配置

  •  0
  • Alex  · 技术社区  · 5 年前

    这是我现在正在使用的配置“模板”:

    server {
      server_name {:primaryDomain};
      listen 443 ssl;
      ssl_certificate /etc/letsencrypt/live/{:primaryDomain}/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/{:primaryDomain}/privkey.pem;
      include /etc/letsencrypt/options-ssl-nginx.conf;
      ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
      root {:siteRoot};
      index index.php index.html;
    
      recursive_error_pages off;
      error_page 403 = /HTTP_ERRORS/403.html;
      error_page 404 = /HTTP_ERRORS/404.html;
      error_page 500 = /HTTP_ERRORS/500.html;
      
      location ^~ /HTTP_ERRORS/ {
        alias {:sharedHtmlRoot}/;
        internal;
      }  
      
      location / {
        try_files $uri $uri/ /index.php?$query_string;
      }
    
      location /manage {
        root {:siteRoot}/manage;  
        try_files $uri $uri/ /manage/index.php?$query_string;
      }
    
      location ~* \.php$ {
        fastcgi_pass unix:/run/php/php{:phpVer}-fpm-{:user}.sock;
        include         fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
      }
    
      location /assets/ {
        alias /public/assets/;
      }     
    }
    
    server {
      server_name {:primaryDomain} www.{:primaryDomain};
      listen 80;
      return 301 https://{:primaryDomain}$request_uri;
    }
    
    server {
      server_name www.{:primaryDomain};
      listen 443 ssl;
      ssl_certificate /etc/letsencrypt/live/{:primaryDomain}/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/{:primaryDomain}/privkey.pem;
      include /etc/letsencrypt/options-ssl-nginx.conf;
      ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;  
      return 301 https://{:primaryDomain}$request_uri;
    }
    

    请注意 {:keywords} 。这些是我用生成nginx最终配置的脚本替换的字符串。 它工作得很好,但我有大约300个网站,脚本将使用这个模板生成300个这样的配置,所以最终的nginx.conf文件相当大。 我能以某种方式为所有网站使用一个nginx配置吗?

    0 回复  |  直到 5 年前
        1
  •  4
  •   emptyhua    4 年前

    这是一个 all in one 我已验证的配置 nginx/1.18.0 ,但仍需要生成域列表文件 /etc/nginx/mydomains

    /etc/nginx/sites-enabled/default

    map $http_host $vhost_config {
        hostnames;
        default "";
        include /etc/nginx/mydomains;
    }
    
    map $vhost_config $vhost_root {
        default "";
        ~^([^:]+):([^:]+):([^:]+)$ $1;
    }
    
    map $vhost_config $php_version {
        default "";
        ~^([^:]+):([^:]+):([^:]+)$ $2;
    }
    
    map $vhost_config $php_user {
        default "";
        ~^([^:]+):([^:]+):([^:]+)$ $3;
    }
    
    map $ssl_server_name $my_cert_name {
        default "";
        ~^(www\.)?(.+)$ $2;
    }
    
    server {
        listen 80 default_server;
        listen 443 ssl default_server;
    
        ssl_certificate /etc/letsencrypt/live/$my_cert_name/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/$my_cert_name/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
        server_name ~^(?<www>(www\.)?)(?<domain>.+)$;
    
        recursive_error_pages off;
        error_page 403 = /HTTP_ERRORS/403.html;
        error_page 404 = /HTTP_ERRORS/404.html;
        error_page 500 = /HTTP_ERRORS/500.html;
    
        location ^~ /HTTP_ERRORS/ {
            alias {:sharedHtmlRoot}/;
            internal;
        }
    
        # redirect www.abc.com to abc.com
        if ($www != '') {
            return 301 https://$domain$request_uri;
        }
    
        # redirect http to https
        if ($scheme = 'http') {
            return 301 https://$domain$request_uri;
        }
    
        # if domain not exist in mydomains, return 404
        if ($vhost_root = '') {
            return 404;
        }
    
        root $vhost_root;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        location /manage {
            root $vhost_root/manage;
            try_files $uri $uri/ /manage/index.php?$query_string;
        }
    
        location ~* \.php$ {
            fastcgi_pass unix:/run/php/php$php_version-fpm-$php_user.sock;
            include         fastcgi_params;
            fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
            fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
        }
    
        location /assets/ {
            alias /public/assets/;
        }
    }
    

    的内容 /etc/nginx/mydomains

    # domain.name "<site root>:<php version>:<php user>";
    abc.com "/var/www/html/abc:7.4:user1";
    efg.com "/var/www/html/efg:7.0:user2";
    

    笔记

    1. Nginx支持使用中的变量 ssl_certificate 指令自 1.15.9 和 $ssl_server_name 被引入 nginx/1.70 。因为http变量 $http_host 在建立https连接之前不会被初始化, $ssl_server_name 在此配置中无法替换。
    2. 你可以替换 {:sharedHtmlRoot} 在里面 server 用你的真实路径阻塞。
    3. 一体化 服务器 块被延迟为默认块,如果你的nginx配置中已经有一个默认的服务器块,你需要覆盖旧的块。