如何将传出主机/端口从容器映射到其他端口

时间:2017-08-28 19:19:45

标签: tomcat docker mariadb

我有一个连接到mariadb数据库的小型webapp。我让Tomcat在一个容器中运行,而mariadb在另一个容器中运行。 Tomcat引用具有在Context.xml文件中指定的JDBC url的mariadb实例,指定当前的fqhn和端口3306。

我现在必须复制这个配置,这样我在盒子上有两个webapp实例,包括四个容器,两个运行Tomcat,两个运行Mariadb。在“docker run”上进行简单端口映射很容易,因此每个Tomcat实例都可以通过不同的端口访问,类似于mariadb实例。

我不清楚如何将OUTGOING主机:端口引用从Tomcat容器映射到mariadb实例。映像中的Context.xml文件使用当前的完全限定主机名和默认端口3306指定数据库的JDBC URL。

我能够更改单个图像,因此它可以与两个实例一起使用,但我仍然需要一个带有单个JDBC URL的图像。对于第一个容器对,它必须到达3306上运行的原始mariadb实例。第二个容器对,即使它指定端口3306,也必须连接到端口3307。

这是用“--link”命令行选项以某种方式完成的吗?

更新

如果现有的应用程序没有运行,这会更容易,我可以直接破解它直到它正常工作。我必须确保我仔细检查这一点,以尽量减少干扰。我必须对图像源代码进行一次更改,作为context.xml文件中的JDBC URL。我将其更改为“jdbc:mysql://db:3306/estimatordb”。

虽然我在桌面(或Jenkins实例)上使用Gradle构建应用程序WAR文件,但Docker镜像仅构建在Jenkins实例上。我一直在系统文件中运行目标主机上的容器,只是做“docker run ...”。在Jenkins构建中,通过ssh我对图像名称执行“docker pull”,然后使用“docker stop”来停止现有容器,以便它将使用新图像重新启动。

在此期间,我将更改我构建的图像名称(只是在名称中添加“2”),而我现在正在评论“ssh docker stop”。我不确定这会转化为什么。显然,“docker-compose stop”是一个起点,但如果我在这个版本中对compose文件进行更改,那就会让人感到困惑。

我的“docker-compose.yml”文件是我项目中的一个源文件,所以我想我会在我的撰写文件中使用“ssh docker-compose -f - ”。

以下是我为“docker-compose.yml”文件抛出的内容,但我还没有对此进行验证:

version: '2'
services:
  estimator:
    image: tomcat-estimator2
    ports:
      - "8889:8080"
      - "445:443"
    volumes:
      - /etc/localtime:/etc/localtime
    depends_on:
      - db
    links:
      - db:db
  db:
    image:  mariadb:10.1.22
    ports:
      - "3307:3306"
    volumes:
      - /etc/localtime:/etc/localtime
      - /opt/app/estimator/databases/estimator/mysql:/var/lib/mysql  
  estimator-automation:
    image: tomcat-estimator2
    ports:
      - "8890:8080"
      - "446:443"
    volumes:
      - /etc/localtime:/etc/localtime
    depends_on:
      - db-automation
    links:
      - db-automation:db
  db-automation:
    image:  mariadb:10.1.22
    ports:
      - "3308:3306"
    volumes:
      - /etc/localtime:/etc/localtime
      - /opt/app/estimator/databases/estimator-automation/mysql:/var/lib/mysql

请注意,端口号是现有应用程序端口的1+,因为在我确定这将起作用之前我不希望这样做。

对此有任何意见都很有用。

2 个答案:

答案 0 :(得分:1)

一般而言,通常通过提供传递命令行参数或环境等信息的方式来处理(例如,在docker上下文中)指定运行应用程序所需的资源等用例。有关此问题的详细信息,请查看the great manifesto of the 12 factor app,尤其是the section on configuration

对于您的具体问题,我确信有办法将此信息注入tomcat配置,例如在this question中。因此,您可以通过在不同端口上运行两个数据库容器并将相应的连接字符串传递给两个tomcat容器来解决您的问题。

但这还不是完整的解决方案。当您考虑将tomcat容器与数据库组合为一个部署时,您可以使用docker虚拟网络并连接此类设置,甚至无需将数据库端口发布到外部世界。当两个容器位于同一网络中时,您可以使用其给定的名称引用它们,以便您的数据库始终可以在docker虚拟网络中以mydatabase:3306的形式访问。当使用诸如docker-compose之类的系统为您处理这样的命名空间并允许您将整个堆栈定义为一个撰写文件时,这非常简单。请查看使用访问redis实例的python应用程序执行此操作的the getting started for docker-compose

答案 1 :(得分:0)

您可以使用context.xml选项将每个容器装入一个唯一的-v

例如在主持人身上:

$ mkdir /tmp/container
$ cd /tmp/container
$ vi container1_context.xml # Edit JDBC url
$ vi container2_context.xml # Edit JDBC url
$ docker run ... -v /tmp/container/container1_context.xml:<path/to/context.xml> tomcat
$ docker run ... -v /tmp/container/container2_context.xml:<path/to/context.xml> tomcat