Home > Net >  Can't connect to Redis Stack from ASP.NET application inside a container
Can't connect to Redis Stack from ASP.NET application inside a container

Time:05-17

I have an asp.net webApi application and using redis stack as the main database. I was able to connect to the database and perform operations normally till I made a docker image from my application and tried to run it on docker. The application cannot connect to the redis stack even that I have changed "localhost" to the "container name" and set it as an environment variable in my docker-compose file. Here is my code to connect and my docker-compose file for reference.

Connection to Redis Stack Code (Using Redis OM Package):

builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration[Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)]));
builder.Services.AddHostedService<IndexCreationService>();

Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["API/API.csproj", "API/"]
COPY ["Core/Core.csproj", "Core/"]
COPY ["Persistence/Persistence.csproj", "Persistence/"]
COPY ["Service/Service.csproj", "Service/"]
RUN dotnet restore "API/API.csproj"
COPY . .
WORKDIR "/src/API"
RUN dotnet build "API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "API.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API.dll"]

Docker-compose.yaml

version: '3.7'

services:
  redis:
    image: redis/redis-stack
    container_name: redis
    volumes:
      - db-data:/data/redis
    ports:
      - "6379:6379"
      - "8001:8001"
    restart: unless-stopped
    networks:
      - course-network
    
  CourseService:
    image: dexam/course-service
    container_name: course-service
    volumes:
      - course-service-data:/data/course_service
    ports:
      - "443:443"
    environment:
      - REDIS_CONNECTION_STRING=redis://redis:6379
    restart: unless-stopped
    depends_on:
      - "redis"
    links:
      - "redis"
    networks:
      - course-network

volumes:
  db-data:
  course-service-data:

networks:
  course-network:
  driver: bridge

The error message I get:

Unhandled exception. StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s). Error connecting right now. To allow this multiplexer to continue retrying until it's able to connect, use abortConnect=false in your connection string or AbortOnConnectFail=false; in your code. at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(ConfigurationOptions configuration, TextWriter log) in //src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1162 at StackExchange.Redis.ConnectionMultiplexer.Connect(ConfigurationOptions configuration, TextWriter log) in //src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1028 at Redis.OM.RedisConnectionProvider..ctor(String connectionString) at Program.$(String[] args) in /src/API/Program.cs:line 17

Can anyone spot the problem?

CodePudding user response:

It looks like there's a bit of confusion in whether you're pulling your connection string out of your environment or configuration:

builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration[Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)]));

This line doesn't really make sense, you are trying to pull a configuration variable from your appsettings file whose name is the VALUE of your REDIS_CONNECTION_STRING environment variable (which you've set in the docker-compose as redis://redis:6379) - this is most likely coming up as an empty string and hence, failing to parse-correctly and connect - the default behavior when Redis OM encounters an empty string in the config is to connect to redis://localhost:6379, since there's no redis instance there it will fail like the way you've shown.

You're looking for 1 of two things

  1. You want to pull the connection string out of the environment variable, if you change that line to the following, given your docker-compose file, this ought to just work
builder.Services.AddSingleton(new RedisConnectionProvider(Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)));
  1. You really do want to pull the connection string out of the configuration, this is valid, but you'll want to make sure that you are setting the connection string in your configuration before you build the image:
builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration["REDIS_CONNECTION_STRING"]));

Both methods are valid, but they won't play nice together which is why you're getting a bit of heartburn here.

  • Related