如何让Clojure Compojure应用程序通过Docker容器中的编译jar运行无头?

更新 :这个问题已经改变,因为最初的一组评论者留下了回应。 对任何混淆道歉。


这是我的代码库https://github.com/Integralist/spurious-clojure-example你可以用它作为我正在使用的例子。

请注意,上面的回购依赖于我还没有发布到Clojars的库(因为我还在testing它 – 因此打开了这个问题)。 你可以在这里看到库的源代码: https : //github.com/Integralist/spurious-clojure-aws-sdk-helper

我有一个用Compojure编写的“hello world”Clojurenetworking应用程序,当使用lein ring server lein runlein run (因为我现在创build了一个-main函数),我工作的很好。 当编译成jar时,它也运行到一定程度,我运行java -jar app.jar

我现在的问题是,如果我尝试从Docker容器中运行默认的java -jar app.jar ,我得到以下错误告诉我…

 spurious-clojure-example is starting 2015-02-14 00:58:03.812:INFO:oejs.Server:jetty-7.xy-SNAPSHOT 2015-02-14 00:58:03.854:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080 Started server on port 8080 Exception in thread "main" java.awt.HeadlessException: 

我的代码目前正在使用一个-main函数就像这样…

 (ns spurious-clojure-example.repl (:use spurious-clojure-example.handler ring.server.standalone [ring.middleware file-info file]) (:gen-class)) (defonce server (atom nil)) (defn get-handler [] (-> #'app (wrap-file "resources") (wrap-file-info))) (defn start-server "used for starting the server in development mode from REPL" [& [port]] (let [port (if port (Integer/parseInt port) 8080)] (reset! server (serve (get-handler) {:port port :init init :auto-reload? true :destroy destroy :join true})) (println (str "You can view the site at http://localhost:" port)))) (defn stop-server [] (.stop @server) (reset! server nil)) (defn -main [] (start-server)) 

…但是如何让服务器开始无头呢? 我不能完全遵循Compojure样板代码来解密何时或如何知道什么时候无头或通过浏览器运行?

我知道在命令行你可以做lein ring server-headless那么程序的等价性是什么?

由于ring-server主要用于开发,它试图在服务器启动时打开浏览器。 这在没有GUI的平台上发生java.awt.HeadlessException失败。 你会想要设置:open-browser? 选项为false以防止这种情况。

从EXPOSE官方Docker文档

EXPOSE指令通知Docker,容器将在运行时监听指定的networking端口。 Docker使用此信息通过链接互连容器(请参阅“Docker用户指南”),并确定在使用-P标志时要向主机公开哪些端口。 注意:EXPOSE不定义哪些端口可以暴露给主机,或者默认情况下允许从主机访问端口。 要将端口暴露给主机,请在运行时使用-p标志或-P标志

所以如果你在你的project.clj手动设置环服务器端口,请确保你在Dockerfile中也使用相同的端口,然后在启动docker时通过-p或-P提供一个映射。

我不能肯定地说,但我相信你的无头的错误信息不会导致你的问题。