dockerdocker-composeredisfastapiredis-om

Redis Error 111: Connection Refused in Docker Compose with FastAPI


I'm working on a FastAPI project using Docker Compose and Redis (specifically redis-om-python), but I keep encountering a ConnectionError: Error 111 connecting to localhost:6379. Connection refused error when both the API and Redis are running in Docker containers.

My docker-compose looks like this:

services:
  api:
    build: .
    container_name: api
    command: uv run fastapi dev --host 0.0.0.0
    ports:
      - "8000:8000"
    env_file:
      - .env.dev
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis/redis-stack:latest
    container_name: redis
    ports:
      - "6379:6379"
      - "8001:8001"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      retries: 5
      start_period: 5s

And in the .env.dev file I have:

REDIS_HOST=redis
REDIS_PORT=6379

I'm using redis-om to store data in Redis as a NoSQL database. Here's how I'm initializing the connection:

from redis_om import get_redis_connection, JsonModel
from pydantic import BaseSettings, Field
import os

class Settings(BaseSettings):
    REDIS_HOST: str = "localhost"
    REDIS_PORT: int = 6379

    class Config:
        env_file = (".env.dev", ".env")

ENV = Settings()

redis_client = get_redis_connection(host=ENV.REDIS_HOST, port=ENV.REDIS_PORT)

class CustomerModel(JsonModel):
    first_name: str = Field(index=True)
    last_name: str = Field(index=True)
    email: str = Field(index=True)
    age: int = Field(index=True)
    bio: str | None = Field(index=True, full_text_search=True)

    class Meta:
        database = redis_client

NOTE: Settings and CustomerModel are in two separate files, I wrote them together just to simplify the explanation.

If I run Redis in a container and the FastAPI app locally, it works as expected. But if I run both API and Redis in containers, I get the error mentioned above. Even when I hardcode redis instead of localhost (host="redis"), the error still points to localhost:6379 in the logs.

What I've Tried:

  1. Confirmed .env.dev is properly loaded inside the container.
  2. Verified connectivity between the containers (ping redis and redis-cli -h redis -p 6379 ping → PONG).
  3. Hardcoded "redis" instead of using the environment variable.
  4. Checked the Redis health status (docker ps, docker logs redis).
  5. Pruned the docker system and rebuilt containers completely.

Therefore, I don't get...

  1. Why does redis-om still default to localhost:6379 despite explicitly passing the correct host (redis) and port (6379) to get_redis_connection?
  2. Is there something I'm missing in my Docker Compose setup or the way redis-om initializes the connection?

Solution

  • Since for some reason get_redis_connection does not use the arguments I gave it, I saw that in its implementation it also looks for an environment variable REDIS_OM_URL and if it finds it, it is used to create the connection. I then updated my .env.dev file with:

    REDIS_OM_URL=redis://redis:6379
    

    And I changed the connection setting to:

    redis_client = get_redis_connection()
    

    And now it works like a charm.