2014-09-21 88 views
0

我一直在試圖找出一種方法來首先捕獲環境變量HOSTNAME,然後使用MySQL查詢來獲取並返回到我們的虛擬主機的Nginx配置文件根目錄。我們將它們用於目前在Apache中的動態文檔根目錄,但正在遷移到Nginx。如何在Nginx中使用MySQL動態文檔根目錄?

例如nginx.conf(可能是這個樣子):

server { 
    listen 80; 
    # grab Environment variable HOSTNAME 
    $hostname= ENV(HOSTNAME); 
    # execute mysql query 
    $doc_root = mysql(select docroot from table where host = '$hostname'); 
    # set document root 
    root   /var/www/$doc_root; 

..... 我使用Lua和https://github.com/openresty/lua-resty-mysql探索,但一直無法弄清楚如何做才能捕捉HOSTNAME和mysql查詢作爲變量並返回結果。

回答

0

首先,使用數據庫進行基本路由聽起來不是一個好主意 - 我建議將結果緩存在內存中,並可能定期從數據庫刷新它們。其次,基本的Nginx配置文件只會讓你目前爲止 - 爲了獲得更高級的功能,你需要在它上面使用腳本語言(比如Lua)。這允許你閱讀環境變量之一。我寫了一篇關於如何在這裏做到這一點:

https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html

的常用方法得到的Lua對Nginx的工作是利用Openresty,Nginx的版本附帶了幾個模塊預裝,包括Lua的一個。您可以將lua-resty-mysql添加到混音中,然後直接從Lua中完成您想要的任何內容。我從來沒有使用lua-resty-mysql,所以我無法爲你編寫代碼。如果你使用Mysql,你將不得不研究它的文檔。看看Redis,看看它,它可能比Mysql更合適。

0

感謝您的幫助。它不適合我,但經過很多工作,我終於有了一些工作。這是爲別人,如果他們需要它

事實證明$ http_host已在nginx全局定義 - 所以這是固定的。

 set $httphost $http_host; # create and initialize var 
     set $docroot ""; 

    # begin LUA scripting 
    rewrite_by_lua ' 
        -- make sure http host is defined 
        if not ngx.var.httphost then 
         ngx.log(ngx.ERR,"ERROR - no httphost defined") 
         return 
        end 

         -- begin mysql 
        local mysql = require "resty.mysql" 
        local db, err = mysql:new() 

        db:set_timeout(1000) -- 1 sec 

        local ok, err, errno, sqlstate = db:connect 
        { 
          host = "127.0.0.1", 
          port = 3306, 
          database = "db", 
          user = "user", 
          password = "password", 
          max_packet_size = 1024 * 1024 
        } 

        if not ok then 
         ngx.log(ngx.ERR,"MySQL failed to connect: ", err, ": ", errno, " ", sqlstate) 
         return 
        end 

        -- prevent injection attack 
        local hname = ngx.unescape_uri(client) 
        local quoted_name = ngx.quote_sql_str(hname) 

        local sql = "select docroot from users where customer =" .. quoted_name 
        result,err,errno,sqlstate = db:query(sql,1) 
        if not result then 
         ngx.log(ngx.ERR,"MySQL bad result: ", err, ": ", errno, ": ", sqlstate, ".") 
         return 
        end 

        if not result[1].docroot then 
         ngx.log(ngx.ERR,"MySQL ERROR - no docroot was returned") 
         return 
        end 

        ngx.var.docroot = result[1].docroot 
      '; 
      # now we can set the docroot for this host 
      root   /var/www/$docroot; 
相關問題