docker run mongo image on a different port

33,906

Solution 1

Default communication between different containers running on the same host

I solved the problem, not by running the container in a different port though, but by learning one new feature in docker-compose version 2 and that is we do not need to specify links or networks. The newly created containers by default will be part of docker0 network and hence they can communicate with each other.

As Matt mentioned, we can run processes inside containers on the same port. They should be isolated. So the problem can not be that the docker container and the host are using the same port. The problem is perhaps there is an attempt to forward a used port in host to another port in container.

Below is a working docker-compose file:

version: '2'
services:
    webapp:
        image: myimage
        ports:
            - 3000:3000

    mongo:
        image: mongo:latest

I looked at the mongo:latest docker file in github, and realized they exposed 27017. So we do not need to change the port or forward host ports to the running mongo container. And the mongo url can stay on the same port:

monog_url = 'mongodb://mongo:27017'
client = MongoClient(monog_url, 27017)

Docker run an image on a different port

So the above solution solved the problem, but as for the question title 'docker run mongo image on a different port', the simplest way is just to change the docker-compose to:

version: '2'
services:
web:
    image: myimage

mongo:
    image: mongo:latest
    command: mongod --port 27018

Mongo is now running on 27018 and the following url is still accessible inside the web:

monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url, 27018)

Solution 2

You can tell MongoDB to listen on a different port in the configuration file, or by using a command-line parameter:

services:
  mongo:
    image: 'mongo:latest'
    command: mongod --port 27018
    ports:
        - '27018:27018'

Solution 3

You can run processes inside a container and outside on the same port. You can even run multiple containers using the same port internally. What you can't do is map the one port from the host to a container. Or in your case, map a port that is already in use to a container.

For example, this would work on your host:

services:
    webapp:
        image: myimage
        ports:
            - '3000:3000'

    mongo:
        image: 'mongo:latest'
        ports:
            - '27018:27017'

    mongo2:
        image: mongo:latest
        ports:
            - '27019:27017'

The host mongo listens on 27017. The host also maps ports 27018 and 27019 to the container mongo instances, both listening on 27017 inside the container.

Each containers has its own network namespace and has no concept of what is running in another container or on the host.

Networks

The webapp needs to be able to connect to the mongo containers internal port. You can do this over a container network which allows connections between the container and also name resolution for each service

services:
    webapp:
        image: myimage
        ports:
          - '3000:3000'
        networks:
          - myapp
        depends_on:
          - mongo

    mongo:
        image: 'mongo:latest'
        ports:
          - '27018:27017'
        networks:
          - myapp

networks:
    myapp:
        driver: bridge

From your app the url mongo://mongo:27017 will then work.

From your host need to use the mapped port and an address on the host, which is normally localhost: mongo://localhost:27018

Share:
33,906
Mahshid Zeinaly
Author by

Mahshid Zeinaly

my Company my Linkedin

Updated on January 12, 2022

Comments

  • Mahshid Zeinaly
    Mahshid Zeinaly over 2 years

    The short question is can I run mongo from mongo:latest image on a different port than 27017 (for example on 27018?)

    If yes, how can I do this inside a docker-compose.yml file in order ro be able to type the following command:

    docker-compose run
    

    The longer story:

    I have an app running in AWS EC2 instance. The app consists of a mongodb and a web application. Now I decided to separate part of this app into its own microservice running in the same AWS inside docker container (two containers one for another mongo and one for a web app). I think the problem is I can not have mongodb running on port 27017 and at the same time another mongodb running inside a docker container on port 27017. Right? I have this assumption because when I stop the first mongo (my app mongo), my docker mongo works.

    So I am trying to make the second mongo (the one that is inside the docker container), to run in a different port and my second web app (the one inside another docker conianter), to listen to mongo on a different port. Here is my attempt to change the docker-compose file:

    version: '2'
    services:
        webapp:
            image: myimage
            ports:
                - 3000:3000
    
        mongo:
            image: mongo:latest
            ports:
                - 27018:27018
    

    And inside my new app, I changed the mongo url to:

    monog_url = 'mongodb://mongo:27018'
    client = MongoClient(monog_url, 27018)
    

    Well, the same if I say:

    monog_url = 'mongodb://mongo:27018'
    client = MongoClient(monog_url)
    

    But when I run docker-compose run, it still does not work, and I get the following errors:

    ERROR: for mongo  driver failed programming external
    connectivity on endpoint: Error starting userland proxy:
    listen tcp 0.0.0.0:27017: bind: address already in use
    

    Or

    pymongo.errors.ServerSelectionTimeoutError:
    mongo:27018: [Errno -2] Name or service not known