1

I am new to the docker world and I have some issues regarding how to connect 2 docker services tougher.

I am using https://memgraph.com/ as my database and when I am running it locally I am running it like this

docker run -it -p 7687:7687 -p 3000:3000 memgraph/memgraph-platform

I wrote my program which is going to connect to the database using mgclient and when I am running it locally everything is working fine.

Now I am trying to put in inside the docker container and running it using docker-compose.yaml

My docker-compose.yaml is:

version: "3.5"
services:
  memgraph:
    image: memgraph/memgraph-platform:2.1.0
    container_name: memgraph_container
    restart: unless-stopped
    ports:
      - "7687:7687"
      - "3000:3000"
  my_app:
    image: memgraph_docker
    container_name: something
    restart: unless-stopped
    command: python main.py

and when I am trying to run it with this command:

docker-compose up

I am getting an error regarding the connection to the server. Could anyone tell me what I am missing regarding the docker-compose.yaml?

KWriter
  • 1,024
  • 4
  • 22
Mircea
  • 1,671
  • 7
  • 25
  • 41
  • According to docker-compose nothing is wrong – Jinna Balu Jan 06 '22 at 19:45
  • That seems fine; the `container_name:` settings are unnecessary and you probably shouldn't need to override your application's `command:`, but networking-wise there's nothing specifically wrong with it. What's the actual error? How is the application connecting to the database? Have you read background material like [Networking in Compose](https://docs.docker.com/compose/networking/) in the Docker documentation? – David Maze Jan 06 '22 at 20:12

1 Answers1

1

How does your my_app connect to the database?

Are you using a connection string of the form localhost:7687 (or perhaps localhost:3000)? This would work locally because you are publishing (--publish=7687:7687 --publish=3000:3000) the container's ports 7687 and 3000 to the host port's (using the same ports).

NOTE You can remap ports when your docker run. For example, you could --publish=9999:7686 and then you would need to use port 9999 on your localhost to access the container's port 7687.

When you combine the 2 containers using Docker Compose, each container is given a name that matches the service name. In this case, your Memgraph database is called memgraph (matching the service name).

Using Docker Compose, localhost takes on a different mean. From my_app, localhost is my_app. So, using localhost under Docker Compose, my_app would try connecting to itself not the database.

Under Docker Compose, for my_app (the name for your app), you need to refer to Memgraph by its service name (memgraph). The ports will be unchanged as both 7687 and 3000 (whichever is correct).

NOTE The ports statement in your Docker Compose config is possibly redundant *unless you want to be able to access the database from your (local)host (which you may for debugging). From a best practice standpoint, once my_app is able to access the database correctly, you don't need to expose the database's ports to the host.

Update

It is good practice to externalize configuration (from your app). So that you can configure your app dynamically. An easy way to do this is to use environment variables.

For example:

main.py:

import os


conn = connect(
    host=os.getenv("HOST"),
    port=os.getenv("PORT"),
)

Then, when you run under e.g. Docker, you need to set these values:

docker run ... --env=HOST="localhost" --env=PORT="7687" ...

And under Docker Compose, you can:

version: "3.5"
services:
  memgraph:
    image: memgraph/memgraph-platform:2.1.0
    container_name: memgraph_container
    restart: unless-stopped

  my_app:
    image: memgraph_docker
    container_name: something
    restart: unless-stopped
    command: python main.py
    environment:
      HOST: memgraph
      PORT: 7687
DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • Ok so I'm a bit confuse because I am new to docker but when you said `Under Docker Compose, for my_app (the name for your app), you need to refer to Memgraph by its service name (memgraph). The ports will be unchanged as both 7687 and 3000 (whichever is correct).` this so far as I understand means basically to write `hostname: "memgraph"` under my_app? Because if so, it is still not working – Mircea Jan 06 '22 at 19:36
  • How does your app connect to Memgraph when it works correctly on your host? There must be some form of so-called connection string and I assume it's currently set to something like `localhost`, `localhost:7687` or `127.0.0.1:7687`? – DazWilkin Jan 06 '22 at 19:39
  • And if I will need to use other localhost, I need to write something custom when I am calling my scrip from docker? I mean I was guessing the at the moment when I am writing 'docker-compose up' I will start the exectuion of my application, or do I need to do this just to start everything and after that I have to do 'docker run MY_APP -h SOMETHING -p SOME_PORT'? – Mircea Jan 06 '22 at 19:39
  • regarding about the connection `conn = connect(host=host, port=port)` where host is `127.0.0.1` and port is `7687` – Mircea Jan 06 '22 at 19:40
  • According to the Memgraph [docs](https://memgraph.com/docs/memgraph/connect-to-memgraph/methods/building-applications/python), you probably have something like `connection = mgclient.connect(host='127.0.0.1', port=7687)`, right? – DazWilkin Jan 06 '22 at 19:40
  • this is by default, I didn't custom here – Mircea Jan 06 '22 at 19:41
  • yes, exactly, this is it – Mircea Jan 06 '22 at 19:41
  • Exactly.... So, when you run using Docker Compose, you can't use `127.0.0.1`. That corresponds to localhost but that's not the name of Memgraph under Docker Compose. Its name will be `memgraph`. So you need to ensure `host` value is `memgraph` – DazWilkin Jan 06 '22 at 19:42
  • oh, right, now I get it. I will test it right away, give me few moments – Mircea Jan 06 '22 at 19:43
  • I did that and is still not working. So if I get it correctly I should just replace the localhost with the memgraph, which if this is the case I use this command `docker run memgraphproject_my_app python main.py network "www.googl.com" --host memgraph` which it has my `memgraph` as hostname but is still not working. – Mircea Jan 06 '22 at 20:04
  • No. Your question said that you want to run this under Docker Compose. When you use Docker Compose, you run `docker-compose up` (not `docker run`). – DazWilkin Jan 06 '22 at 20:06
  • I'm not sure that I understand but... when I am running docker-compose.yaml I am just going to build my_app. And when I will run it afterwards will be with docker run my_docker_app, or not? – Mircea Jan 06 '22 at 20:08
  • or if not, how can I run it via docker compose but with the ability to run different parameters at each run? so for example if in my local machine I can say `python main.py COMMAND_1 PARAMETER` and also `python main.py COMMAND_2 PARAMETER` how can I do that in docker compose? – Mircea Jan 06 '22 at 20:09
  • Basically what I am trying to do as I've tried to explain it above, I want to run docker-compose in order to start the server and also in order to create my image. After that I want to run different command with my image – Mircea Jan 06 '22 at 20:11
  • 1
    I think I've answered your question and that you would benefit from reading Docker's documentation. Good luck! – DazWilkin Jan 06 '22 at 20:19