#Issue with state store using docker-compose

1 messages · Page 1 of 1 (latest)

proud loom
#

Hey, I have an issue that I'm hoping has a simple solution 🙂 I'm working on a POC to showcase the deployment process of Dapr to a kubernetes cluster. First step is to try out the solution locally in a Docker Compose setup. Everything seems to spin up fine, but the Redis State Store component is complaining that is has no configuration file defined. I've tried shuffling the components folder around to no avail.

Let me list out the different parts:

Dockerfile

WORKDIR /app
EXPOSE 5000

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY /src /src
RUN dotnet restore "DaprStateStoreAPI.csproj"
RUN dotnet build "./DaprStateStoreAPI.csproj" -c Release -o /app/build
COPY /src/Components /app/build/Components

FROM build AS publish
RUN dotnet publish "DaprStateStoreAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false
COPY --from=build /app/build/Components /app/publish/components

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS=https://+:5000
ENV DOTNET_EnableDiagnostics=1
ENV ASPNETCORE_ENVIRONMENT=Development
ENTRYPOINT ["dotnet", "DaprStateStoreAPI.dll"]```

**docker-compose.yml**
```version: '3.4'

services:
  placement:
    image: "daprio/dapr:latest"
    command: ["./placement", "--port", "50006", "--log-level", "debug"]

  redis:
    image: redis:latest
    hostname: dapr-statestore
    ports:
      - "6390:6379"

  dapr-statestore-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:5000
    depends_on:
      - redis
      - placement
    image: dapr-statestore-api:latest
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "5000:5000"

  dapr-statestore-api-dapr:
    image: "daprio/daprd:edge"
    command: [
     "./daprd",
     "--app-id", "dapr-statestore-api",
     "--app-port", "5000",
     "--placement-host-address", "placement:50006", # Dapr's placement service can be reach via the docker DNS entry
     "--log-level", "debug",
     "--resources-path", "./components"
     ]
    volumes:
      - "./components/:/components" # Mount our components folder for the runtime to use. The mounted location must match the --resources-path argument.
    depends_on:
      - dapr-statestore-api
    network_mode: "service:dapr-statestore-api" # Attach the daprstatestoreapi service to the network namespace

./arc/Components/statestore.yml

kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  metadata:
  - name: redisHost
    value: redis:6379
  - name: redisPassword
    value: ""
  - name: actorStateStore
    value: "true"

The full console output from docker compose up attached, but the impoartant part:

daprstatestoreapi-redis-1                     | 1:C 11 Sep 2023 18:59:11.931 * Redis version=7.2.1, bits=64, commit=00000000, modified=0, pid=1, just started
daprstatestoreapi-redis-1                     | 1:C 11 Sep 2023 18:59:11.931 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf```

Hopefully you are able to easily spot the issue.
proud loom
#

And the error message from a call to http://localhost:5000

 ---> Grpc.Core.RpcException: Status(StatusCode="FailedPrecondition", Detail="state store is not configured")
   at Dapr.Client.DaprClientGrpc.MakeSaveStateCallAsync[TValue](String storeName, String key, TValue value, String etag, StateOptions stateOptions, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at Dapr.Client.DaprClientGrpc.MakeSaveStateCallAsync[TValue](String storeName, String key, TValue value, String etag, StateOptions stateOptions, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
   at Dapr.Client.DaprClientGrpc.SaveStateAsync[TValue](String storeName, String key, TValue value, StateOptions stateOptions, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
   at DaprStateStoreAPI.Controllers.WeatherForecastController.Get() in /src/Controllers/WeatherForecastController.cs:line 36
   at lambda_method5(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:5000
User-Agent: PostmanRuntime/7.32.3
Accept-Encoding: gzip, deflate, br
Postman-Token: a93fa3c4-a860-4781-894f-69a26787f03f
urban rapids
#

Hey @proud loom

In your statestore.yaml, can you try changing the redishost value to host.docker.internal:6390

proud loom
#

Hey @urban rapids ! Thanks for your reply! Unfortunately it didn't make a difference. I searched the issue and found this https://github.com/docker-library/redis/issues/111 which led me to changing the redis entry in the docker-compose file to:

    image: redis
    command: ["redis-server", "--appendonly", "yes"]
    ports:
      - "6390:6379"```

This got rid of the warning in the dapr redis log file:
```daprstatestoreapi-redis-1                     | 1:C 11 Sep 2023 22:03:44.832 * Redis version=7.2.1, bits=64, commit=00000000, modified=0, pid=1, just started
daprstatestoreapi-redis-1                     | 1:C 11 Sep 2023 22:03:44.832 * Configuration loaded```

However, a Postman call to http://localhost:5000 still renders the same 500 Internal Server Error issue as before:
```Dapr.DaprException: State operation failed: the Dapr endpoint indicated a failure. See InnerException for details.
 ---> Grpc.Core.RpcException: Status(StatusCode="FailedPrecondition", Detail="state store is not configured")```
GitHub

Hi. I've got redis operational for my application using this snippet in my docker-compose.yml file. redis: container_name: redis image: redis ports: - "6379:6379" volumes: - ../data/r...

urban rapids
# proud loom Hey <@689445553360470042> ! Thanks for your reply! Unfortunately it didn't make ...

Hmm interesting.

I’ve got a docker compose example here which uses redis as a state store.

Might be worth comparing with yours

https://github.com/olitomlinson/dapr-workflow-examples/blob/91b2bc881def633e49c65656a9a68436c7f9aaea/compose.yml#L86

GitHub

Contribute to olitomlinson/dapr-workflow-examples development by creating an account on GitHub.

proud loom
#

Finally figured it out! I had my components folder in src/components but noticed I had a root components folder that was empty. I just copied the statestore.yml in the rool components folder and it works - wow. Guess I'm not totally comfortable with the docker-compose file and the --resources-path definition and how it relates to the volumes definition.

    image: "daprio/daprd:edge"
    command: [
     "./daprd",
     "--app-id", "dapr-statestore-api",
     "--app-port", "5000",
     "--placement-host-address", "placement:50006", # Dapr's placement service can be reach via the docker DNS entry
     "--log-level", "debug",
     "--resources-path", "./components"
     ]
    volumes:
      - "./components/:/components" # Mount our components folder for the runtime to use. The mounted location must match the --resources-path argument.
    depends_on:
      - dapr-statestore-api
    network_mode: "service:dapr-statestore-api" # Attach the daprstatestoreapi service to the network namespace```

Is the left side of the volumes definition local and the right side internal to the sidecar?
#

Either way, thanks a lot @urban rapids for giving me something to compare against - that was very useful!