我正在运行一个需要访问本地数据库的 clojure 应用程序。clojure 应用程序正在使用 jdbc:
:dependencies [[org.clojure/clojure "1.10.0"]
...
[org.clojure/java.jdbc "0.7.12"]
[org.postgresql/postgresql "42.3.3"]]
当直接在安装了 postgresql 版本的主机上运行时,即使连接到远程数据库,该应用程序也会按预期工作。
但是,当从基于映像的 docker 容器内运行时clojure
:
# syntax=docker/dockerfile:1
FROM clojure
WORKDIR /ui-service
COPY . .
CMD ["lein", "ring", "server-headless", "3000"]
EXPOSE 3000
连接失败:
lan-activity-ui-service-1 | org.postgresql.util.PSQLException: ERROR: could not load library "/usr/lib/postgresql/13/lib/llvmjit.so": /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /lib/x86_64-linux-gnu/libz3.so.4)
lan-activity-ui-service-1 | QueryExecutorImpl.java:2675 org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse
lan-activity-ui-service-1 | QueryExecutorImpl.java:2365 org.postgresql.core.v3.QueryExecutorImpl.processResults
lan-activity-ui-service-1 | QueryExecutorImpl.java:355 org.postgresql.core.v3.QueryExecutorImpl.execute
lan-activity-ui-service-1 | PgStatement.java:490 org.postgresql.jdbc.PgStatement.executeInternal
lan-activity-ui-service-1 | PgStatement.java:408 org.postgresql.jdbc.PgStatement.execute
lan-activity-ui-service-1 | PgPreparedStatement.java:166 org.postgresql.jdbc.PgPreparedStatement.executeWithFlags
lan-activity-ui-service-1 | PgPreparedStatement.java:118 org.postgresql.jdbc.PgPreparedStatement.executeQuery
lan-activity-ui-service-1 | jdbc.clj:1090 clojure.java.jdbc/execute-query-with-params
lan-activity-ui-service-1 | jdbc.clj:1084 clojure.java.jdbc/execute-query-with-params
lan-activity-ui-service-1 | jdbc.clj:1113 clojure.java.jdbc/db-query-with-resultset*
lan-activity-ui-service-1 | jdbc.clj:1093 clojure.java.jdbc/db-query-with-resultset*
lan-activity-ui-service-1 | jdbc.clj:1182 clojure.java.jdbc/query
lan-activity-ui-service-1 | jdbc.clj:1144 clojure.java.jdbc/query
lan-activity-ui-service-1 | jdbc.clj:1160 clojure.java.jdbc/query
lan-activity-ui-service-1 | jdbc.clj:1144 clojure.java.jdbc/query
lan-activity-ui-service-1 | db.clj:33 ui-service.db/all-devices
lan-activity-ui-service-1 | db.clj:32 ui-service.db/all-devices
lan-activity-ui-service-1 | handler.clj:21 ui-service.handler/fn
lan-activity-ui-service-1 | handler.clj:20 ui-service.handler/fn
lan-activity-ui-service-1 | core.clj:158 compojure.core/wrap-response[fn]
lan-activity-ui-service-1 | core.clj:128 compojure.core/wrap-route-middleware[fn]
lan-activity-ui-service-1 | core.clj:137 compojure.core/wrap-route-info[fn]
lan-activity-ui-service-1 | core.clj:146 compojure.core/wrap-route-matches[fn]
lan-activity-ui-service-1 | core.clj:185 compojure.core/routing[fn]
lan-activity-ui-service-1 | core.clj:2701 clojure.core/some
lan-activity-ui-service-1 | core.clj:2692 clojure.core/some
lan-activity-ui-service-1 | core.clj:185 compojure.core/routing
lan-activity-ui-service-1 | core.clj:182 compojure.core/routing
lan-activity-ui-service-1 | RestFn.java:139 clojure.lang.RestFn.applyTo
lan-activity-ui-service-1 | core.clj:667 clojure.core/apply
lan-activity-ui-service-1 | core.clj:660 clojure.core/apply
lan-activity-ui-service-1 | core.clj:192 compojure.core/routes[fn]
lan-activity-ui-service-1 | json.clj:102 ring.middleware.json/wrap-json-params[fn]
lan-activity-ui-service-1 | json.clj:143 ring.middleware.json/wrap-json-response[fn]
lan-activity-ui-service-1 | cors.clj:47 jumblerg.middleware.cors/allow-origins
lan-activity-ui-service-1 | cors.clj:41 jumblerg.middleware.cors/allow-origins
lan-activity-ui-service-1 | cors.clj:57 jumblerg.middleware.cors/wrap-cors[fn]
lan-activity-ui-service-1 | Var.java:384 clojure.lang.Var.invoke
lan-activity-ui-service-1 | reload.clj:39 ring.middleware.reload/wrap-reload[fn]
lan-activity-ui-service-1 | stacktrace.clj:26 ring.middleware.stacktrace/wrap-stacktrace-log[fn]
lan-activity-ui-service-1 | stacktrace.clj:96 ring.middleware.stacktrace/wrap-stacktrace-web[fn]
lan-activity-ui-service-1 | jetty.clj:25 ring.adapter.jetty/proxy-handler[fn]
lan-activity-ui-service-1 | (Unknown Source) ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle
lan-activity-ui-service-1 | HandlerWrapper.java:97 org.eclipse.jetty.server.handler.HandlerWrapper.handle
lan-activity-ui-service-1 | Server.java:499 org.eclipse.jetty.server.Server.handle
lan-activity-ui-service-1 | HttpChannel.java:311 org.eclipse.jetty.server.HttpChannel.handle
lan-activity-ui-service-1 | HttpConnection.java:258 org.eclipse.jetty.server.HttpConnection.onFillable
lan-activity-ui-service-1 | AbstractConnection.java:544 org.eclipse.jetty.io.AbstractConnection$2.run
lan-activity-ui-service-1 | QueuedThreadPool.java:635 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
lan-activity-ui-service-1 | QueuedThreadPool.java:555 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run
lan-activity-ui-service-1 | Thread.java:833 java.lang.Thread.run
如何确保 docker 容器中提供所需的依赖项?我是否需要使用多阶段 docker 构建来包含 postgresql 映像?或者是否可以纯粹在 java/clojure 中添加所需的依赖项?
我能够构建一个包含clojure 正在查找的/usr/lib/postgresql/13/
目录和文件的容器,但奇怪的是我仍然收到错误::/usr/lib/postgresql/13/lib/llvmjit.so
ERROR: could not load library "/usr/lib/postgresql/13/lib/llvmjit.so"
# syntax=docker/dockerfile:1
FROM postgres:13 as postgres
FROM clojure
WORKDIR /ui-service
COPY . .
COPY --from=postgres /usr/lib/postgresql/ /usr/lib/postgresql/
RUN ls -l /usr/lib/postgresql/13/lib/llvmjit.so
CMD ["lein", "ring", "server-headless", "3000"]
EXPOSE 3000
虽然可以使用Pomegranate之类的工具从 Clojure 通过网络引入依赖项,并且 Clojure 1.12 本身的 alpha 版本中也提供了类似的功能,但构建自己的容器来添加必要的依赖项可能要简单得多到您正在使用的那个。
我有一个演示项目,展示了如何通过 Clojure 中的 Docker 容器使用 Postgres 和 H2。它使用该
jdbc.next
库。请注意,我们在 Docker 容器中运行 Postgres。该演示从命令行运行 Clojure。当然,您也可以在容器中运行 Clojure,只要它可以正常通过端口 5432 访问 Postgres 即可。
Leiningen 正常用于定义 Clojure 项目及其依赖项:
一个简短的 BASH 脚本启动 Postgres:
然后使用以下命令运行演示
lein
:有关完整详细信息,请参阅自述文件。
我看到的错误与 JDBC 客户端无关,它是服务器端错误,可能与服务器上的 bullseye -> bookworm 升级有关。JDBC Postgresql确实是一个纯java客户端,不需要查找非java共享库。