在 docker 容器内使用带有 ssl 的自托管(Jetty)元数据库时出错

Posted

技术标签:

【中文标题】在 docker 容器内使用带有 ssl 的自托管(Jetty)元数据库时出错【英文标题】:Error when using selfhosted (Jetty) Metabase with ssl inside docker container 【发布时间】:2021-02-23 16:15:51 【问题描述】:

我正在尝试在启用 ssl 的 docker 容器内设置一个自托管 (Jetty) 元数据库。

首先我使用certbot 创建了fullchain.pemprivkey.pem,然后使用this gist 转换为keystore.jks

然后创建一个用于--env-file docker 标志的 .env 文件:

MB_DB_FILE=/metabase/metabase.db
MB_JETTY_SSL=true
MB_JETTY_SSL_PORT=443
MB_JETTY_SSL_KEYSTORE=./keystore.jks
MB_JETTY_SSL_KEYSTORE_PASSWORD=my-pass

并试图运行:

docker run -p 80:3000 -v ~/metabase:/metabase --env-file "./prod.env" --name metabase metabase/metabase

但我收到以下错误:

ERROR metabase.core :: Metabase Initialization FAILED
java.net.SocketException: Permission denied
    at sun.nio.ch.Net.bind0(Native Method) ~[?:?]
    at sun.nio.ch.Net.bind(Unknown Source) ~[?:?]
    at sun.nio.ch.Net.bind(Unknown Source) ~[?:?]
    at sun.nio.ch.ServerSocketChannelImpl.bind(Unknown Source) ~[?:?]
    at sun.nio.ch.ServerSocketAdaptor.bind(Unknown Source) ~[?:?]
    at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:345) ~[metabase.jar:?]
    at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:310) ~[metabase.jar:?]
    at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80) ~[metabase.jar:?]

通过将 SSL_PORT 更改为 8443 解决,所以新的 env 文件如下所示:

MB_DB_FILE=/metabase/metabase.db
MB_JETTY_SSL=true
MB_JETTY_SSL_PORT=8443
MB_JETTY_SSL_KEYSTORE=./keystore.jks
MB_JETTY_SSL_KEYSTORE_PASSWORD=my-pass

删除了旧容器并使用上面的 env 文件启动了一个新容器,但现在我遇到了这个错误:

ERROR metabase.core :: Metabase Initialization FAILED
java.lang.IllegalStateException: /"./keystore.jks" is not a valid keystore

我已经使用this 仔细检查了我的 .jks 文件是否有效。确实如此。

我的问题是:

    为什么我不能在 443 上运行它 为什么我的密钥库无效?

编辑 1:

遵循 Joakim 的建议:

改成绝对路径

MB_DB_FILE=/metabase-prod-data/metabase.db
MB_JETTY_SSL=true
MB_JETTY_SSL_PORT=8443
MB_JETTY_SSL_KEYSTORE=/root/services/metabase/setup/keystore.jks
MB_JETTY_SSL_KEYSTORE_PASSWORD=my-pass

收到此错误:

ERROR metabase.core :: Metabase Initialization FAILED
java.lang.IllegalStateException: /root/services/metabase/setup/keystore.jks is not a valid keystore

【问题讨论】:

【参考方案1】:

@Joakim 回答了为什么不使用端口 443

我在元数据库初始化时也遇到了这个问题。 我面临的错误是在 docker 容器内无法访问主机上的密钥库文件。

我使用了 docker-compose yml 文件。您也可以搜索基于终端的方式。

我通过使用卷属性在具有证书的主机上添加文件夹来使其可访问。

metabase:
   ...
    env_file:
      - ./config/metabase.env
    volumes:
      - <LOCAL_PATH>:<CONTAINER_PATH>

环境路径内:

MB_JETTY_SSL_KEYSTORE:<CONTAINER_PATH>/keystore.jks

【讨论】:

【参考方案2】:

443 是大多数操作系统上的受限端口,需要 root/超级用户/管理员权限才能绑定到它。

找不到您的密钥库,该路径无效。 这个错误只是令人困惑。

你的配置

MB_JETTY_SSL_KEYSTORE=./keystore.jks

尝试将其设为绝对路径,因为在您的情况下,元数据库显然只是将您提供的内容添加到其他路径 / 的末尾。

【讨论】:

感谢您的帮助。看看我刚刚添加到问题中的编辑 1。试过绝对路径还是不行

以上是关于在 docker 容器内使用带有 ssl 的自托管(Jetty)元数据库时出错的主要内容,如果未能解决你的问题,请参考以下文章

HTTPS 在带有 Docker 容器的 Service Fabric 中不起作用

使用 ssl 证书和带有卷的密钥部署 postgresql docker

带有点网核心的自托管进程内 Web API

javax.net.ssl.SSLHandshakeException:收到致命警报:docker容器内的handshake_failure

使用映射端口访问 docker 容器内的 JMX

Nginx 代理背后的 SSL SpringBoot App Docker 容器