You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Clojure的Docker容器PostgreSQL库加载失败问题求助

PostgreSQL JDBC依赖缺失导致Clojure应用Docker运行失败的问题与解决

问题背景

我有一个访问本地数据库的Clojure应用,使用JDBC,依赖配置如下:

:dependencies [[org.clojure/clojure "1.10.0"]
                 ...
                 [org.clojure/java.jdbc "0.7.12"]
                 [org.postgresql/postgresql "42.3.3"]]

在安装了PostgreSQL的主机上直接运行时,哪怕连接远程数据库都能正常工作,但用clojure镜像构建Docker容器运行时却连接失败。

使用的Dockerfile:

# 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)
...(后续栈追踪省略)

我尝试过用多阶段构建从postgres镜像复制/usr/lib/postgresql/13/目录到clojure镜像,Dockerfile如下,但仍报错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

我的疑问:

  • 怎么确保Docker容器内具备所需依赖?
  • 是否需要用多阶段构建引入PostgreSQL镜像?
  • 能不能仅通过Java/Clojure添加所需依赖?

问题分析

报错的本质是:clojure镜像的基础系统(通常是Debian旧版本)自带的libstdc++.so.6版本过低,缺少GLIBCXX_3.4.30;而你复制的llvmjit.so依赖的libz3.so.4刚好需要这个高版本的系统库。单独复制PostgreSQL的库解决不了底层系统库的版本问题。


解决方案

方案1:升级容器内的libstdc++库

直接在clojure镜像中安装更新版本的libstdc++:

# syntax=docker/dockerfile:1
FROM clojure
WORKDIR /ui-service
# 安装更新的libstdc++6
RUN apt-get update && apt-get install -y --no-install-recommends libstdc++6
COPY . .
CMD ["lein", "ring", "server-headless", "3000"]
EXPOSE 3000

如果Debian默认源的版本还是不够,可以添加backports源(针对旧版Debian):

FROM clojure
WORKDIR /ui-service
# 添加backports源并安装更新的libstdc++6
RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list && \
    apt-get update && \
    apt-get install -y --no-install-recommends -t bullseye-backports libstdc++6
COPY . .
CMD ["lein", "ring", "server-headless", "3000"]
EXPOSE 3000

方案2:使用基于更新系统的Clojure镜像

换用基于Debian Bookworm或Ubuntu 22.04的Clojure镜像,这些系统自带的libstdc++版本更高:

# syntax=docker/dockerfile:1
FROM clojure:bookworm
WORKDIR /ui-service
COPY . .
CMD ["lein", "ring", "server-headless", "3000"]
EXPOSE 3000

方案3:关闭PostgreSQL的LLVM JIT功能

如果不需要LLVM JIT的性能优化,可以直接在JDBC连接参数中关闭它,这样就不会加载llvmjit.so了:

;; 示例DB配置
(def db-spec {:dbtype "postgresql"
              :dbname "your-db-name"
              :user "db-user"
              :password "db-pass"
              :host "db-host"
              :port 5432
              :options "-c jit=off"})

或者直接在连接URL中添加参数:jdbc:postgresql://host:5432/your-db?jit=off

方案4:复制完整依赖链(不推荐)

如果一定要保留LLVM JIT,需要用ldd /usr/lib/postgresql/13/lib/llvmjit.so查看所有依赖的系统库,然后从postgres镜像逐一复制到clojure镜像中。这种方法繁琐且容易出问题,不如前几种方案高效。


疑问解答

  • 是否需要多阶段构建引入PostgreSQL镜像?:不需要。你的应用只是连接远程数据库,复制PostgreSQL的库解决不了系统级依赖问题,反而徒增复杂度。
  • 能否仅通过Java/Clojure添加所需依赖?:不行。llvmjit.so是系统级动态链接库,不属于Java/Clojure的依赖生态,无法通过Lein或Clojars仓库引入。

内容的提问来源于stack exchange,提问作者ealfonso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:57:11