lein ring服务器在docker容器中抛出java.io.FileNotFoundException

我在docker里装了我的clojure项目。 容器已经成功构build,并且运行了java 1.8.0_151和lein 2.8.1。 但是,当我尝试启动一个环服务器时,我得到这个exception。 然而,当我在mac环境中运行相同的代码,一切正常运行。

例外:

$ docker-compose up Starting clojurejournal_clojure_journal_1 ... Starting clojurejournal_clojure_journal_1 ... done Attaching to clojurejournal_clojure_journal_1 clojure_journal_1 | --> INFO: starting lein ring server clojure_journal_1 | Nov 09, 2017 12:16:18 PM com.mchange.v2.log.MLog <clinit> clojure_journal_1 | INFO: MLog clients using java 1.4+ standard logging. clojure_journal_1 | 2017-11-09 12:16:20.027:INFO:oejs.Server:jetty-7.6.1.v20120215 clojure_journal_1 | 2017-11-09 12:16:20.084:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:3000 clojure_journal_1 | Started server on port 3000 clojure_journal_1 | Exception in thread "main" java.io.FileNotFoundException: http://localhost:3000, compiling:(/tmp/form-init462348242831821276.clj:1:71) clojure_journal_1 | at clojure.lang.Compiler.load(Compiler.java:7142) clojure_journal_1 | at clojure.lang.Compiler.loadFile(Compiler.java:7086) clojure_journal_1 | at clojure.main$load_script.invoke(main.clj:274) clojure_journal_1 | at clojure.main$init_opt.invoke(main.clj:279) clojure_journal_1 | at clojure.main$initialize.invoke(main.clj:307) clojure_journal_1 | at clojure.main$null_opt.invoke(main.clj:342) clojure_journal_1 | at clojure.main$main.doInvoke(main.clj:420) clojure_journal_1 | at clojure.lang.RestFn.invoke(RestFn.java:421) clojure_journal_1 | at clojure.lang.Var.invoke(Var.java:383) clojure_journal_1 | at clojure.lang.AFn.applyToHelper(AFn.java:156) clojure_journal_1 | at clojure.lang.Var.applyTo(Var.java:700) clojure_journal_1 | at clojure.main.main(main.java:37) clojure_journal_1 | Caused by: java.io.FileNotFoundException: http://localhost:3000 clojure_journal_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) clojure_journal_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) clojure_journal_1 | at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) clojure_journal_1 | at java.lang.reflect.Constructor.newInstance(Constructor.java:423) clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1944) clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1939) clojure_journal_1 | at java.security.AccessController.doPrivileged(Native Method) clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1938) clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1508) clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) clojure_journal_1 | at javax.swing.JEditorPane.getStream(JEditorPane.java:768) clojure_journal_1 | at javax.swing.JEditorPane.setPage(JEditorPane.java:432) clojure_journal_1 | at javax.swing.JEditorPane.setPage(JEditorPane.java:880) clojure_journal_1 | at javax.swing.JEditorPane.<init>(JEditorPane.java:274) clojure_journal_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) clojure_journal_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) clojure_journal_1 | at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) clojure_journal_1 | at java.lang.reflect.Constructor.newInstance(Constructor.java:423) clojure_journal_1 | at clojure.lang.Reflector.invokeConstructor(Reflector.java:180) clojure_journal_1 | at clojure.java.browse_ui$open_url_in_swing.invoke(browse_ui.clj:15) clojure_journal_1 | at clojure.lang.Var.invoke(Var.java:379) clojure_journal_1 | at clojure.java.browse$open_url_in_swing.invoke(browse.clj:64) clojure_journal_1 | at clojure.java.browse$browse_url.invoke(browse.clj:76) clojure_journal_1 | at ring.server.standalone$open_browser_to.invoke(standalone.clj:39) clojure_journal_1 | at ring.server.standalone$serve$fn__1676.invoke(standalone.clj:102) clojure_journal_1 | at ring.server.standalone$try_port.invoke(standalone.clj:16) clojure_journal_1 | at ring.server.standalone$serve.doInvoke(standalone.clj:95) clojure_journal_1 | at clojure.lang.RestFn.invoke(RestFn.java:423) clojure_journal_1 | at ring.server.leiningen$serve.invoke(leiningen.clj:20) clojure_journal_1 | at user$eval3389.invoke(form-init462348242831821276.clj:1) clojure_journal_1 | at clojure.lang.Compiler.eval(Compiler.java:6703) clojure_journal_1 | at clojure.lang.Compiler.eval(Compiler.java:6693) clojure_journal_1 | at clojure.lang.Compiler.load(Compiler.java:7130) clojure_journal_1 | ... 11 more clojure_journal_1 | Caused by: java.io.FileNotFoundException: http://localhost:3000 clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1890) clojure_journal_1 | at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) clojure_journal_1 | at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) clojure_journal_1 | at javax.swing.JEditorPane.getStream(JEditorPane.java:733) clojure_journal_1 | ... 33 more 

dockerfile:

 FROM ubuntu:xenial LABEL maintainer=freid ENV WORK_DIR /var/www # install dependancies RUN apt-get update RUN apt-get install -y default-jre curl wget RUN wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein RUN chmod +x lein RUN mv lein /usr/local/bin # copy to /var/www COPY . $WORK_DIR # make it a working directory WORKDIR $WORK_DIR # fix permissions RUN chmod a+x /var/www/entrypoint.sh # expose port 3000 EXPOSE 3000 # make entrypoint ENTRYPOINT ["/bin/sh", "/var/www/entrypoint.sh"] 

泊坞窗 – 撰写:

 clojure_journal: image: clojure_journal:latest command: run ports: - 3000:3000 volumes: - .:/opt/clojure_journal 

entrypoint.sh

 #!/usr/bin/env bash start(){ echo "--> INFO: starting lein ring server" lein ring server } case $1 in run) shift 1 start $@ ;; *) >&2 echo "---> INFO: running: '$1'." ;; esac 

看看exception堆栈跟踪,它看起来像你的代码试图打开浏览器http:// localhost:3000在启动过程中,这可能不是你想要在容器内。 我假设你只想从容器中运行HTTP服务器。 在你的entrypoint.sh脚本中试试lein ring server-headless ,这将防止它试图打开浏览器

另外,还可以(并且容易) lein uberjar项目,并将独立的JAR复制到容器中,并使用java运行,假设您没有将Docker镜像用作开发环境。 这样你就不需要安装Leiningen,这意味着你可以使用一个OpenJDK的图像 ,你的Dockerfile可以简单得多:

 FROM java:8-alpine ADD path/to/your.jar /your-app/app.jar EXPOSE 3000 CMD ["java", "-jar", "/your-app/app.jar"] 

根据@Taylor Wood的评论,使用lein ring server-headless解决了这个问题。

Interesting Posts