部署也是 CLI 应用程序的 compojure 应用程序

deploy compojure app that is also a CLI app

我有一个 Clojure 应用程序,既可以从命令行使用,也可以作为 Compojure 应用程序使用。 我通过在我的 leiningen project.clj.

中放置一个环处理程序和一个主要函数 (clojure.tools.cli) 来做到这一点

{... :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,而且我对要使用的容器很灵活。

lein ring server 启动 jetty 来为您构建的网络应用程序提供服务。它通过使用您在 :ring 中指定的选项启动服务器来完成此操作。如果您在环境中指定 LEIN_NO_DEV,则服务器将在生产模式下 运行。 Jetty 是否适合您的制作需求,由您决定。

如果您想 运行 您的 Web 应用程序在不同的服务器上,有多种选择。其中之一是 运行ning 在 Tomcat 上。再看一下 lein ring, in particular the section on war files. Basically, you would call lein war or lein uberwar to generate a war 文件的文档。然后你可以例如将 war 文件放入 Tomcat.

webapps 目录中

另一种选择是使用 immutant,它有大量关于安装和 运行ning 应用程序的文档。

这是我用于新项目的一种默认模板。它允许您将依赖注入到环形应用程序中,并从命令行 运行 将应用程序作为 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 配置文件。