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
- 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)));
- 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.