Patrick
Patrick

Reputation: 476

Docker tomcat7 container cannot connect to host activemq

I am admittedly relatively new to using Docker for environment isolation, but I've run into a problem I am yet to solve, and I'm looking for some advice on how to proceed. Apologies if this is dirt simple.

I have an image built with this Dockerfile:

FROM java:7-jre
MAINTAINER me <email redacted>

ENV CATALINA_HOME="/usr/local/tomcat" 
ENV PATH=$CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"

#Add tomcat tarball with configs 
#need to figure out if war files should be auto-deploy or manual-deploy via manager
ADD ./ $CATALINA_HOME

WORKDIR $CATALINA_HOME
RUN tar -xmvf tomcat.tar.gz --strip-components=1 \
    && rm bin/*.bat \
    && rm tomcat.tar.gz*

EXPOSE 8080
#quite possibly unnecessary to expose 61616
EXPOSE 61616

CMD catalina.sh run

Because my host is Mac OSX, I'm using the boot2docker package. The port forwarding is a real PITA, but for now I'm just binding host 8080 to container 8080 when I run the container (-p 8080:8080) and I have 8080 forwarded in the boot2docker networking setup.

This image runs a container just fine, and I am able to manually upload and deploy .war files to this container while it's running.

On my local machine, I am running ActiveMQ. Eventually I'll put this in a container but I need to get past this hurdle first. ActiveMQ is running with the default port 61616 listening, as shown in this netstat output:

14:14 $ netstat -a | grep 6161
tcp46      0      0  *.61616                *.*                    LISTEN

The problem I'm having is that deployed war files in my tomcat container are unable to talk to the physical host on 61616. Here is the actual error from the catalina.out log on the container (I added some line breaks to make it easier to read):

Could not refresh JMS Connection for destination 'request' - retrying in 5000 ms. 
Cause: Error while attempting to add new Connection to the pool; nested exception is javax.jms.JMSException: 
Could not connect to broker URL: tcp://localhost:61616. 
Reason: java.net.ConnectException: Connection refused

Admittedly, I think it's because the war file is configured to use localhost:61616 to connect to AMQ -- it doesn't feel right for localhost inside the container to "work" reaching back to the host. I'm not sure what variable value I should set that to, or if that's even the actual issue. I would think that if it's a dynamically-allocated black-magic IP address, it'd be relatively painful to keep reconfiguring inside war files.

Corollary: are there other considerations I would need to make beyond this configuration if I wanted to link this tomcat container with an AMQ one?

Thanks in advance for your attention. ~P

Upvotes: 2

Views: 2761

Answers (1)

Alex Nauda
Alex Nauda

Reputation: 4536

First, you shouldn't need to EXPOSE 61616 on the container. (That would allow the container to listen on port 61616, which is not what you want.)

What you do need though is to access docker's localhost (your boot2docker VM) from within the docker container. The best way I've found to do this, so far, from this answer, is to run inside your docker container:

export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')

That is going to give you the IP address of your boot2docker VM, as seen from within the current docker container. I'll leave it up to you to figure out how to configure your JMS client to connect to that IP address, but one idea that comes to mind is something like:

echo $DOCKER_HOST_IP my-jms-hostname >> /etc/hosts

And then you can hardcode your JMS configuration to hit my-jms-hostname:61616

I recommend that you put the above two commands into a start script that you use to startup your application server in the container.

Next, you will need to find a way to tunnel that port on your boot2docker VM to your local host OS. For example, on your local host OS, run

boot2docker ssh -R61616:localhost:61616

That will listen on the remote (boot2docker VM's) port 61616 and forward it to your local host OS's localhost:61616, which is where ActiveMQ is hopefully listening happily for an incoming connection from your application server's JMS client.

Upvotes: 2

Related Questions