On Linux Ubuntu 22.04 I have created a docker container with a simple python script that has to connect to a MongoDB instance working on the host and listening on localhost.
To have a reproducible example consider what follows.
The Dockerfile is:
FROM ubuntu
RUN apt-get update
RUN apt-get install curl pip micro netcat -y
COPY requirements.txt app/requirements.txt
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . /app
The requirements file contains:
fastapi==0.85.1
uvicorn==0.19.0
motor==3.1.0dev
black==22.10.0
python-dotenv==0.21.0
orjson==3.8.0
requests==2.28.1
While the python script (inside app/db directory) is mongodb.py and contains:
import asyncio
import requests
from motor.motor_asyncio import (
AsyncIOMotorClient,
AsyncIOMotorCollection,
)
from bson.codec_options import DEFAULT_CODEC_OPTIONS
def get_collection(
) -> AsyncIOMotorCollection:
# SET OPTION TO RETURN DATES AS TIMEZONE AWARE
options = DEFAULT_CODEC_OPTIONS.with_options(tz_aware=True)
motor_client = AsyncIOMotorClient(
"mongodb://usr:pwd@host.docker.internal:27020/?authSource=admin&replicaSet=Replica1"
)
database = motor_client["DBNAME"]
# APPLY OPTIONS TO RETURN DATETIMES AS TIMEZONE AWARE
return database.get_collection(collName, codec_options=options)
async def main():
# client = ClientMotor().client
coll = get_collection()
response=requests.get('http://host.docker.internal')
print(response.text)
async for doc in coll.find({}).limit(10):
print(doc)
if __name__ == "__main__":
try:
asyncio.run(
main()
)
except KeyboardInterrupt:
pass
On host, I have installed and started NGINX that forwards stream to MongoDB from PORT 27020 to default port 27017 (always localhost).
The previous code works fine if not within a docker container (specifying localhost instead of the host.docker.internal) and I can connect to MongoDB from Compose by specifying PORT 27020 in the connection string.
If I build the container with
docker build -t test_motor .
and thereafter run it with
docker run -it --add-host host.docker.internal:host-gateway test_motor bash
Running
python3 mongodb.py.
From within /app/db, I correctly get a response from NGINX but I’m not able to connect to MongoDB.
If I execute from within the docker container
nc -zvw10 host.docker.internal 27020
the host/port is reachable.
What’s the problem? I don’t want to run the container with host=net, the only working solution so far!