1

So what I want to do is to have 2 docker container running(MongoDB and Postgres) both of these are working. Now what I want to do is to create 2 services(node.js instances) that will connect from separate containers that will query and exercise their database. Each service should only access a single database.

To show my docker-compose.yml

services:

  #mongodb set up
  web:
    image: node
    build: ./mongodb_service
    ports:
    - 4000:4000
    depends_on:
    - mongodb

  mongodb:
    image: mongo
    expose:
    - '27017'

  web_postgres:
    image: node
    build: ./postgres_service
    ports:
      - "3000:3000"
    depends_on:
    - postgresdb

  #postgres db definition the env vars should be put in a properties file and passed to it somehow
  postgresdb:
    image: postgres
    #the health check confirms that the db is ready to accept connections and not just the container
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - PGUSER=user
      - PGPASSWORD=1234
      - PGPORT=5432
      - PGDATABASE=customerdirectory
#   Maps port 54320 (localhost) to port 5432 on the container. You can change the ports to fix your needs.
    ports:
      - "54320:5432"

Currently what is breaking is my web_postgres service. When I run docker-compose up I notice that the console.log() commands from my web service end up in the web_postgres Here is what I mean web_postgres error. At the top of the image, my web_postgres_1 service is printing stuff from web service.

Is my docker-compose.yml set up correctly to have these containers run independently?

If there is something kind of missing piece please lmk will upload. Thanks a lot for all your help.

This is the server.js file from my web_postgres service.

const express = require("express");
const { Pool, Client } = require('pg')
const app = express()
// pools will use environment variables
// for connection information
const pool = new Pool({
  user: 'user',
  host: 'localhost',
  database: 'customerdirectory',
  password: '1234',
  port: 5432,
})

pool.query('SELECT NOW()', (err, res) => {
  console.log(err, res)
  pool.end()
})

app.get("/", (req, res) => {
  res.send("Hello from Node.js app \n");
});

app.listen('3000', () =>{
  console.log("I hate this damn thingy sometimes")
})

This is the web service server.js code that gets printed

const express = require("express");
var MongoClient = require('mongodb').MongoClient;
const app = express();

MongoClient.connect("mongodb://mongodb:27017", function(err, db) {
  if(err) throw err;
  db.close()
})

app.get("/", (req, res) => {
  res.send("Hello from Node.js app \n");
});

app.listen('4000', () =>{
  console.log("I hate this damn thingy sometimes")
})
2
  • I suspect the image: tags are causing a problem; you're telling Docker Compose that both services are running the same image (with two different Dockerfiles to build it). Showing the code that prints out the string web_postgres error from the wrong container would be helpful, though. Commented Oct 20, 2019 at 16:59
  • @DavidMaze uploaded, interesting when I ssh into the container somehow they both share the same filesystem!!! How is this possible? Commented Oct 20, 2019 at 17:10

1 Answer 1

2

You need to remove the image: from your docker-compose.yml file. When you specify that both containers have the same image:, Docker Compose takes you at face value and uses the same image for both, even if there are separate build: instructions.

The documentation for image: notes:

If the image does not exist, Compose attempts to pull it, unless you have also specified build, in which case it builds it using the specified options and tags it with the specified tag.

So what happens here is that Compose builds the first service's image, and tags it as node:latest (potentially conflicting with a standard Docker Hub image with this same name); and when the second container starts, it sees that image already exists, so it reuses it.

You can demonstrate this with a simple setup. Create a new empty directory with subdirectories a and b. Create a/Dockerfile:

FROM busybox
WORKDIR /app
RUN echo Hello from a > hello.txt
EXPOSE 80
CMD ["httpd", "-f"]

Similarly create b/Dockerfile with a different string.

Now create this docker-compose.yml file:

version: '3'
services:
  a:
    # image: image
    build: a
    ports: ['8000:80']
  b:
    # image: image
    build: b
    ports: ['8001:80']

You can start this as-is, and curl http://localhost:8000/hello.txt and similarly for port 8001 to see the two different responses. But, if you uncomment the two image: lines, they'll both return the same string. There are also some clues in the Docker Compose output where one path builds both images but the other only builds one, and there's a warning about the named image not existing when you specify the image names.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.