How to connect to Google Cloud Redis using AUTH and TLS/SSL, and provide a local development environment using Docker Compose. The API controller allows you to perform CRUD operations on the Redis database.
---
title: How to connect to GCP Redis Instance in .NET Core
subtitle: How to connect to Google Cloud Redis using AUTH and TLS/SSL, and provide a local development environment using Docker Compose. The API controller allows you to perform CRUD operations on the Redis database.
author: Jon LaBelle
date: September 18, 2024
snippet: https://jonlabelle.com/snippets/view/markdown/how-to-connect-to-gcp-redis-instance-in-net-core
notoc: false
---
Let's go through the steps to achieve this:
1. **Install Required Packages**: Install the `StackExchange.Redis` package.
2. **Configure Redis Connection**: Set up the connection to Google Cloud Redis using the AUTH string and TLS/SSL.
3. **Dependency Injection**: Create a Redis client class for CRUD operations and register it with the dependency injection container.
4. **Docker Compose**: Create a `docker-compose.yml` file for local development with services for Redis, PostgreSQL, .NET Core API, and Vue.js UI.
5. **Example `appsettings.json`**: Include the required Redis connection settings for SSL/TLS.
6. **API Controller**: Create an API controller for CRUD operations.
7. **Dispose of ConnectionMultiplexer**: Ensure the `ConnectionMultiplexer` is disposed of properly.
8. **Dockerfiles**: Create Dockerfiles for each service.
### Step 1: Install Required Packages
Run the following command to install the necessary package:
```sh
dotnet add package StackExchange.Redis
```
### Step 2: Configure Redis Connection
Create a configuration class and a service to manage the Redis connection.
#### RedisConfig.cs
```csharp
public class RedisConfig
{
public string ConnectionString { get; set; }
public string AuthString { get; set; }
public bool UseSsl { get; set; }
public bool ValidateServerCertificate { get; set; }
}
```
#### RedisService.cs
```csharp
using StackExchange.Redis;
using System;
using System.Security.Cryptography.X509Certificates;
public class RedisService : IDisposable
{
private readonly ConnectionMultiplexer _redis;
public RedisService(RedisConfig config)
{
var options = ConfigurationOptions.Parse(config.ConnectionString);
options.Password = config.AuthString;
options.Ssl = config.UseSsl;
options.CertificateValidation += (sender, certificate, chain, sslPolicyErrors) =>
{
if (config.ValidateServerCertificate)
{
// Implement your certificate validation logic here
return sslPolicyErrors == System.Net.Security.SslPolicyErrors.None;
}
return true;
};
_redis = ConnectionMultiplexer.Connect(options);
}
public IDatabase GetDatabase() => _redis.GetDatabase();
public void Dispose()
{
_redis?.Dispose();
}
}
```
### Step 3: Dependency Injection
Create a Redis client class for CRUD operations and register it with the dependency injection container.
#### RedisClient.cs
```csharp
using StackExchange.Redis;
public class RedisClient
{
private readonly IDatabase _database;
public RedisClient(RedisService redisService)
{
_database = redisService.GetDatabase();
}
public void Create(string key, string value)
{
_database.StringSet(key, value);
}
public string Read(string key)
{
return _database.StringGet(key);
}
public void Update(string key, string value)
{
_database.StringSet(key, value);
}
public void Delete(string key)
{
_database.KeyDelete(key);
}
}
```
#### Startup.cs
```csharp
public void ConfigureServices(IServiceCollection services)
{
var redisConfig = Configuration.GetSection("RedisConfig").Get<RedisConfig>();
services.AddSingleton(redisConfig);
services.AddSingleton<RedisService>();
services.AddSingleton<RedisClient>();
// Other service registrations
}
```
### Step 4: Docker Compose
Create a `docker-compose.yml` file for local development with services for
Redis, PostgreSQL, .NET Core API, and Vue.js UI.
#### docker-compose.yml
```yaml
version: '3.8'
services:
redis:
image: redis:alpine
ports:
- '6379:6379'
environment:
- REDIS_PASSWORD=yourpassword
command: ['redis-server', '--requirepass', 'yourpassword']
postgres:
image: postgres:alpine
environment:
POSTGRES_USER: yourusername
POSTGRES_PASSWORD: yourpassword
POSTGRES_DB: yourdatabase
ports:
- '5432:5432'
api:
build:
context: ./api
dockerfile: Dockerfile
ports:
- '5000:80'
environment:
- ASPNETCORE_ENVIRONMENT=Development
depends_on:
- redis
- postgres
ui:
build:
context: ./ui
dockerfile: Dockerfile
ports:
- '8080:8080'
depends_on:
- api
networks:
default:
driver: bridge
```
### Step 5: Example `appsettings.json`
Include the required Redis connection settings for SSL/TLS.
#### appsettings.json
```json
{
"RedisConfig": {
"ConnectionString": "your-redis-instance-ip:6379",
"AuthString": "your-auth-string",
"UseSsl": true,
"ValidateServerCertificate": true
},
"ConnectionStrings": {
"PostgresConnection": "Host=postgres;Database=yourdatabase;Username=yourusername;Password=yourpassword"
}
}
```
### Step 6: API Controller
Create an API controller for CRUD operations.
#### ExampleController.cs
```csharp
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class ExampleController : ControllerBase
{
private readonly RedisClient _redisClient;
public ExampleController(RedisClient redisClient)
{
_redisClient = redisClient;
}
[HttpPost]
public IActionResult Create([FromBody] KeyValuePair<string, string> item)
{
_redisClient.Create(item.Key, item.Value);
return Ok();
}
[HttpGet("{key}")]
public IActionResult Read(string key)
{
var value = _redisClient.Read(key);
if (string.IsNullOrEmpty(value))
{
return NotFound();
}
return Ok(value);
}
[HttpPut]
public IActionResult Update([FromBody] KeyValuePair<string, string> item)
{
if (string.IsNullOrEmpty(_redisClient.Read(item.Key)))
{
return NotFound();
}
_redisClient.Update(item.Key, item.Value);
return Ok();
}
[HttpDelete("{key}")]
public IActionResult Delete(string key)
{
if (string.IsNullOrEmpty(_redisClient.Read(key)))
{
return NotFound();
}
_redisClient.Delete(key);
return Ok();
}
}
```
### Step 7: Dockerfiles
Create Dockerfiles for each service.
#### api/Dockerfile
```Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /src
COPY ["YourApiProject.csproj", "./"]
RUN dotnet restore "./YourApiProject.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "YourApiProject.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "YourApiProject.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "YourApiProject.dll"]
```
#### ui/Dockerfile
```Dockerfile
FROM node:alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["npm", "run", "serve"]
```
### Final Code Structure
1. **RedisConfig.cs**: Configuration class for Redis.
2. **RedisService.cs**: Service class to manage Redis connection.
3. **RedisClient.cs**: Client class for Redis CRUD operations.
4. **Startup.cs**: Register Redis service and client with dependency injection.
5. **docker-compose.yml**: Docker Compose file for local development.
6. **appsettings.json**: Configuration file with Redis connection settings.
7. **ExampleController.cs**: API controller for CRUD operations.
8. **api/Dockerfile**: Dockerfile for .NET Core API.
9. **ui/Dockerfile**: Dockerfile for Vue.js UI.
This setup should help you connect to Google Cloud Redis with AUTH and TLS/SSL,
and also provide a local development environment using Docker Compose. The API
controller allows you to perform CRUD operations on the Redis database. The
`ConnectionMultiplexer` is properly disposed of when the singleton is disposed.
All services in the Docker Compose file can communicate with each other on the
same network using the respective Alpine variant for all Docker base images.