【问题标题】:Docker - Connect Apache Tomcat web server to MySQL serverDocker - 将 Apache Tomcat Web 服务器连接到 MySQL 服务器
【发布时间】:2015-06-06 00:07:26
【问题描述】:

我试图将在 Apache Tomcat 容器中运行的 Web 服务器连接到运行另一个容器的 MySQL 数据库。为此,我使用了 Docker 的链接机制。

docker run -it --name ${CONTAINER_NAME} --link db:db -p 8080:8080 -d tomcat

运行容器后,我可以看到容器已链接,并且环境变量已正确暴露。

为了将 Tomcat 容器中运行的 Web 应用程序连接到数据库,我使用了以下配置文件:

<Context>
  <Resource
    name="jdbc/MYDB"
    type="javax.sql.DataSource"
    auth="Container"
    username="user"
    password="password"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://${DB_PORT_3306_TCP_ADDR}:${DB_PORT_3306_TCP_PORT}/epcis?autoReconnect=true">
  </Resource>
</Context>

现在的问题是我无法建立与数据库的连接,因为 Docker 暴露的环境变量在 Tomcat 环境中无法识别。

有没有办法让 Docker 公开的这些环境变量对 Apache Tomcat 环境可见?

【问题讨论】:

  • 检查 mysql 容器是否暴露了 3306 端口。然后您可以进入容器并使用例如 telnet 来查看容器是否可以相互通信。
  • 他们可以互相交谈,我确认使用telnet。问题是 JDBC 驱动程序不知道 ${DB_PORT_3306_TCP_ADDR} 和其他环境变量的值。我的网络应用程序的 tomcat 日志中报告了该错误。
  • 您可以使用 env 属性来传递环境变量:docs.docker.com/reference/run/#env-environment-variables
  • 我也已经这样做了,但它不起作用,但我从 Dockerfile 传递了 env 变量。我将尝试从 Docker 运行命令中传递 env 变量,以测试这些变量是否在 Tomcat 环境中被识别。
  • 奇怪...,您可以尝试的另一个选项是导出 CATALINA_OPTS。在那里你可以指定另一个可用于 tomcat 的环境变量。

标签: java mysql tomcat docker jndi


【解决方案1】:

您可以使用 db 的 dns 声明并对引用进行硬编码吗?我认为 /etc/hosts 文件是用 db 更新的,当你 --link 时它是 IP 地址。所以你可以:

<Context>
  <Resource
    name="jdbc/MYDB"
    type="javax.sql.DataSource"
    auth="Container"
    username="user"
    password="password"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql:db:3306/epcis?autoReconnect=true">
  </Resource>
</Context>

我使用的另一种技术是 skydns 和注册器,然后您可以在 DNS srv 记录中获取 ip 和端口。

我不记得 Tomcat,但它应该可以访问变量。您确定 Tomcat 在使用之前会评估 url 定义吗?

【讨论】:

  • 谢谢格雷格,你是对的。 /etc/hosts 包含来自 db 容器的 IP,这解决了我的问题。
  • 我尝试在我的 META-INF/context.xml 中使用此方法,但我在“mysql:db:3306”周围的 Tomcat 启动时遇到错误,因为它没有将“db”解析为 IP .
  • 查看您的 /etc/hosts 文件。它将包含错误的 IP 地址。如果您尝试将另一个容器连接到它,则需要使用您定义的 docker-machine IP 地址和外部端口。
  • 非常好的答案,谢谢 Greg。
【解决方案2】:

事实上,这些环境变量并没有暴露在运行 tomcat 的环境中。解决方案是基于 tomcat 创建自己的 Dockerfile(即“FROM tomcat”)并创建自己的启动脚本,将相关的环境变量传递到 /etc/tomcat/tomcat.conf:

echo DB_PORT_3306_TCP_ADDR=${DB_PORT_3306_TCP_ADDR} >> /etc/tomcat/tomcat.conf

有关完整工作的 tomcat6/postgres 示例,请参阅 this Dockerfilethis startup script

【讨论】: