2015-06-17 61 views
0

我有一個Clojure應用程序,可以使用命令行和Compojure應用程序。 我通過在我的leiningen project.clj中放置一個環形處理程序和一個主函數(clojure.tools.cli)來做到這一點。部署也是CLI應用程序的compojure應用程序

{... :main my-app.core :ring {:handler my-app.handler/handler }}

handler定義(defroutes handler ...)

現在,如果我想運行CLI應用程序,則可以運行lein uberjar,然後運行java -jar arguments。 我也可以通過lein ring server PORT運行Compojure應用程序。

現在,我該如何在生產服務器上將該東西部署爲Compojure應用程序(而不是CLI應用程序)? (用於解釋lein ring server如何工作的獎勵積分。)

注意:如果可以提供幫助,我已經使用nginx,並且我對使用的容器很靈活。

+0

https://github.com/boot-clj/boot可以成爲解決方案嗎?不知道它還有什麼... – nha

+0

部署的哪個部分是你遇到的問題,只是lein/project.clj語法? 「作爲一個compojure應用程序」是什麼意思? Compojure只是一個路由庫,所以即使以CLI的方式運行,它仍然是組合的,對嗎? (我個人不喜歡在開發或產品中使用lein ring server,因爲它使得依賴注入和REPL開發變得困難)。 –

+0

@DaxFohl通過CLI我的意思是作爲一個jar,然後它進入-main入口點,它使用tools.cli。 CLI應用程序用於執行任務的代碼由REST API使用,我使用'lein ring server 8888'運行,但它是相同的代碼。我希望能夠部署該jar並在端口8888上運行。 – nha

回答

2

這裏是我用於新項目的默認模板。它允許你在環形應用程序中執行依賴注入並作爲uberjar從命令行運行應用程序。你可以在這裏閱讀更多:http://www.sparxeng.com/blog/software/improved-clojure-workflow

; handler.clj  
(defn wrap-inject-deps 
    "Ring middleware that injects the dependencies into each ring request map" 
    [handler deps] 
    (fn [req] 
    (handler (assoc req :deps deps)))) 

(defn create-handler 
    "Similar to the default ring 'handler', but with a parameter to let you inject dependencies" 
    [deps] 
    (-> (routes 
     api-routes 
     web-routes 
     (route/resources "/")) 
     (kwp/wrap-keyword-params) 
     (params/wrap-params) 
     (json/wrap-json-params) 
     (json/wrap-json-response) 
     (wrap-inject-deps deps))) ; this injects dependencies 

(defn start-jetty 
    "Launch the Jetty instance" 
    [deps] 
    (let [port (Integer. (or (-> system :env :port) 5000)) 
     handler (create-handler deps)] 
    (jetty/run-jetty handler {:port port :join? false}))) 


; system.clj 
(defn get-env 
    "Initialize configuration vars" 
    [] 
    {:aws-access-key-id  (System/getenv "AWS_ACCESS_KEY_ID") 
    :aws-secret-access-key (System/getenv "AWS_SECRET_ACCESS_KEY") 
    :mongo-url    (System/getenv "MONGO_URL")) 

(defn start 
    "Launch dependencies such as DB connection and Jetty. Return these as a map, for use in REPL" 
    [& [env]] 
    (let [env (or env (get-env)) 
     deps {:env  env 
       :monger (db/init env)} 
     jetty (handler/start-jetty deps)] 
    (assoc deps :jetty jetty))) 


; program.clj 
(defn -main [& [port]] 
    "App entrypoint" 
    (let [env (system/get-env) ; "env" is just a map of config variables, that can be hard-coded, read from file, or whatever you want. 
     env (if port (assoc env :port port) env)] 
    (system/start env))) 

然後可以使用leiningen配置文件,如果你需要創建一個從你的代碼不同的入口點多個應用程序。

+0

嗯,我不確定我可以使用它,因爲我的CLI使用了'-main'函數app(解析輸入參數...)並且不啓動web服務器。 – nha

+0

@nha使用leiningen配置文件指定不同的入口點。 –

1

lein ring server啓動jetty爲您構建的Web應用程序提供服務。它通過使用您在:ring中指定的選項啓動服務器來完成此操作。如果您在您的環境中指定了LEIN_NO_DEV,則服務器將以生產模式運行。無論碼頭是否適合您的製作需求,都取決於您自己決定。

如果您想在不同的服務器上運行您的Web應用程序,有多個選項。其中一個在Tomcat上運行。再看看lein ring的文檔,特別是關於戰爭文件的部分。基本上,您可以撥打lein warlein uberwar來生成war文件。然後您可以將戰爭文件放到Tomcat的webapps目錄中。

另一種選擇是使用immutant,它具有關於安裝和運行應用程序的大量文檔。

+0

謝謝,這有幫助。現在,如果我用'lein ring server 8888'啓動我的服務器,我該如何使tomcat/jetty在端口888上爲我的compojure應用程序提供服務? – nha

+0

好吧,對於通過lein ring的Jetty,您已經有了答案。對於Tomcat來說,這更多的是關於配置Tomcat的問題,所以我建議你問一個新問題。但它基本上要求你在Tomcat的'server.xml'配置文件中設置'port'變量。 – schaueho

+0

順便說一句,如果這是你正在尋找的信息,隨時upvote /接受答案:-) – schaueho