Search code examples
dockerdocker-composedockerfiledocker-network

Change containers host mappings Docker-compose


I am trying to create a network for 2 containers - my application and database, however, neo4j is started at localhost and an application container cannot connect to the database. How can I change this mapping and create a network for these containers?

The errors I get:

Exception in thread "main" org.neo4j.driver.v1.exceptions.ServiceUnavailableException: Unable to connect to localhost:7687, ensure the database is running and that there is a working network connection to it.
 Caused by: org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:7687

My docker-compose file:

version: '3.3'

services:
  benchmarks:
    image: "container-name"
    volumes:
      - ./:/workdir1
    working_dir: /workdir1
    links:
      - "neo4j_db"
    networks:
      - backend
  neo4j_db:
    image: neo4j:latest
    ports:
    - "7474:7474"
    - "7473:7473"
    - "7687:7687"
    volumes:
    - $HOME/neo4j/import:/var/lib/neo4j/import
    - $HOME/neo4j/data:/neo4j/data
    - $HOME/neo4j/conf:/neo4j/conf
    - $HOME/neo4j/logs:/neo4j/logs
    environment:
    - NEO4J_dbms_active__database=db.db
    networks:
      - backend

networks:
  backend:
    driver: "bridge"

And this is a Dockerfile for this application:

FROM java:8
ENV SCALA_VERSION 2.11.8
ENV SBT_VERSION 1.1.1
ENV SPARK_VERSION 2.2.0
ENV SPARK_DIST spark-$SPARK_VERSION-bin-hadoop2.6
ENV SPARK_ARCH $SPARK_DIST.tgz
ENV NEO4J_CONFIG neo4j_local
ENV BENCHMARK_NAME read_spark_single

WORKDIR /opt

# Install Scala
RUN \
  cd /root && \
  curl -o scala-$SCALA_VERSION.tgz http://downloads.typesafe.com/scala/$SCALA_VERSION/scala-$SCALA_VERSION.tgz && \
  tar -xf scala-$SCALA_VERSION.tgz && \
  rm scala-$SCALA_VERSION.tgz && \
  echo >> /root/.bashrc && \
  echo 'export PATH=~/scala-$SCALA_VERSION/bin:$PATH' >> /root/.bashrc

# Install SBT
RUN \
  curl -L -o sbt-$SBT_VERSION.deb https://dl.bintray.com/sbt/debian/sbt-$SBT_VERSION.deb && \
  dpkg -i sbt-$SBT_VERSION.deb && \
  rm sbt-$SBT_VERSION.deb

# Install Spark
RUN \
    cd /opt && \
    curl -o $SPARK_ARCH http://d3kbcqa49mib13.cloudfront.net/$SPARK_ARCH && \
    tar xvfz $SPARK_ARCH && \
    rm $SPARK_ARCH && \
    echo 'export PATH=$SPARK_DIST/bin:$PATH' >> /root/.bashrc

EXPOSE 9851 9852 4040 7474 7687 7473

VOLUME /workdir1

CMD /workdir1/runapp.sh "$NEO4J_CONFIG" "$BENCHMARK_NAME"

Solution

  • exacly as you said - docker allows you to connect to other hosts by their hostnames. your application is trying to connect to localhost, which always is mapped to 127.0.0.1 - this is the container in which the app is running.

    Simply Adjust your application configuration file to connect to the database on neo4j_db hostname. Docker will take care of pointing it to appropriate container IP. Also, you don't need to publish ports to the docker host.

    please remember, that localhost will always, in any circumstances (unless you deliberately modify it), mean the host, where calling command is running on.

    When using containers, each application is on their own host (container). This is why you cannot use localhost. You need to treat the host machine on which docker is running and all other containers as they were a distant machines on some network.