I have a docker file with two services running on the same network. The purpose is to scrape data and store it in a database.
When I attempt to run the program db_connector.py
inside service block_scraper
I get an error (Timeout):
pymongo.errors.ServerSelectionTimeoutError: storage:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 64f24e6e941b3aa3dea67cc9, topology_type: Unknown, servers: [<ServerDescription ('storage', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('storage:27017: [Errno 111] Connection refused')>]>
As seen in the error, my most recent attempts are using the Docker service name, storage
, to refer to the service.
I was able to get this to work fine when running both services natively outside docker. How can I get them to talk to eachother inside docker?
Project Tree:
|-Dockerfile
|-docker-compose.yml
|-requirements.txt
|-app/
|-|-main.py
|-|-db_connector.py
The docker-compose.yml
file:
version: "3.2"
services:
storage:
image: mongo:7.0.1-rc0
container_name: mongodb
restart: unless-stopped
ports:
- 27017-27019:27017-27019
volumes:
- ./data:/data/db
networks:
- scraper_network
block_scraper:
build: .
depends_on:
- storage
volumes:
- ./app:/app
environment:
- STORAGE_CONNECTION_STR=mongodb://storage:27017
networks:
- scraper_network
networks:
scraper_network:
The Dockerfile (for block_scraper
service):
# Use the official Python 3.11 image as a parent image
FROM python:3.11-slim-buster
# Set the working directory inside the container
WORKDIR /app
# Copy in and install requirements
COPY ./requirements.txt /app/requirements.txt
RUN pip install -Ur requirements.txt
# Copy the application code into the container
COPY . /app
# Specify the command to run your main program
CMD ["python", "main.py"]
The db_connector.py
file:
import os
import pymongo
# Create a single MongoClient instance and reuse it across calls to get_collection
mongo_host = os.environ.get("STORAGE_CONNECTION_STR")
client = pymongo.MongoClient(mongo_host)
def get_collection(mongo_db_name="blocks101", mongo_collection_name="block"):
database = client[mongo_db_name]
return database[mongo_collection_name]
def close():
client.close()
For simplicity, lets say this is the main.py
program:
from db_connector import get_collection
get_collection()