Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Redis connections to use Redis URL - closes #7421 #7736

Conversation

thomasmol
Copy link
Contributor

Closes #7421

This pull request consolidates Redis connection parameters into a single REDIS_URL environment variable across various configuration files and code modules. The most important changes include updates to environment variable files, Docker and Kubernetes configurations, and code modules to utilize the new REDIS_URL format.

Environment Variable Updates:

Docker and Kubernetes Configuration Updates:

Code Module Updates:

Documentation Updates:

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This PR consolidates Redis connection parameters into a single REDIS_URL environment variable across various configuration files and code modules, simplifying Redis connection handling and potentially enabling IPv6 support.

  • Replaced separate Redis connection parameters (host, port, username, password) with REDIS_URL in environment files and Kubernetes configurations
  • Updated cache-storage.module-factory.ts and message-queue.module-factory.ts to use REDIS_URL for connection
  • Modified environment-variables.ts to validate the new REDIS_URL format
  • Updated self-hosting documentation and upgrade guide to reflect the REDIS_URL change
  • Ensured consistency across Docker Compose, Kubernetes, and Terraform configurations

13 file(s) reviewed, 7 comment(s)
Edit PR Review Bot Settings | Greptile

@@ -5,8 +5,7 @@ TAG=latest
PG_DATABASE_HOST=db:5432

SERVER_URL=http://localhost:3000
# REDIS_HOST=redis
# REDIS_PORT=6379
# REDIS_URL=redis://localhost:6379
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Add a comment explaining the REDIS_URL format for clarity

@@ -25,8 +25,7 @@ services:
PG_DATABASE_URL: postgres://twenty:twenty@${PG_DATABASE_HOST}/default
SERVER_URL: ${SERVER_URL}
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
REDIS_PORT: ${REDIS_PORT:-6379}
REDIS_HOST: ${REDIS_HOST:-redis}
REDIS_URL: ${REDIS_URL:-redis://localhost:6379}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using the redis service name instead of localhost in the default URL

name = "REDIS_PORT"
value = 6379
name = "REDIS_URL"
value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The Redis URL format doesn't include authentication. If Redis requires auth, update the URL to include username and password

Comment on lines +62 to +63
name = "REDIS_URL"
value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using a separate variable for the Redis URL instead of constructing it inline. This would improve maintainability and allow for easier configuration changes.

throw new Error(
`${cacheStorageType} cache storage requires host: ${host} and port: ${port} to be defined, check your .env file`,
`${cacheStorageType} cache storage requires ${connectionString} to be defined, check your .env file`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Error message uses connectionString variable, which could be undefined. Use 'REDIS_URL' string instead

@@ -3,6 +3,7 @@ import {
MessageQueueDriverType,
MessageQueueModuleOptions,
} from 'src/engine/core-modules/message-queue/interfaces';
import IORedis from 'ioredis';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding a comment explaining why IORedis is being imported and used

const port = environmentService.get('REDIS_PORT');
const username = environmentService.get('REDIS_USERNAME');
const password = environmentService.get('REDIS_PASSWORD');
const connectionString = environmentService.get('REDIS_URL');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Validate REDIS_URL before using it to prevent potential runtime errors

Copy link
Member

@charlesBochet charlesBochet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean change! I'm testing that it's working as expected locally

@charlesBochet
Copy link
Member

charlesBochet commented Oct 16, 2024

When I don't have the environment variable REDIS_URL set in my .env, I'm getting: ERROR [ExceptionHandler] redis cache storage requires undefined to be defined, check your .env file

@charlesBochet
Copy link
Member

@thomasmol could you made the fix mentioned above and we are good to go :)

@charlesBochet
Copy link
Member

Actually, can you try to also leverage the @ValidateIf decorator in environment-variables.ts, it's our recommended way to ask for an env variable to be set

@charlesBochet
Copy link
Member

charlesBochet commented Oct 16, 2024

Also, when I run npx nx run twenty-server:command cache:flush, the command seems to be hanging forever

@charlesBochet
Copy link
Member

And the CI is red:

  • linter
  • a more serious issue (the server does not seem to properly boot on the CI)

username,
password,
},
connection: new IORedis(connectionString)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems wrong actually, we should not instanciate here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, i changed it to just pass the connection string here. It works but there is a type error. Unsure why that is since passing a string should be OK as per: https://redis.github.io/ioredis/classes/Redis.html#constructor

@thomasmol
Copy link
Contributor Author

thomasmol commented Oct 16, 2024

changed:

  • @ValidateIf decorator in environment-variables.ts, only validate if cache or message queue is set to Redis
  • fixed linting
  • flushing cache command does not hang anymore
  • validation error message updated
  • passing of connection string updated, but results in type error:

Do you know of a fix for the type error in message-queue.module-factory.ts @charlesBochet ?

Updating the bullmq factory options interface to

export interface BullMQDriverFactoryOptions {
 type: MessageQueueDriverType.BullMQ;
 options: BullMQDriverOptions & { connection: string };
}

would work

username,
password,
},
connection: connectionString as any,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get rid of this any type
@Weiko is taking a look

Copy link
Member

@charlesBochet charlesBochet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM to be merged once typing issue has been solved

@Weiko
Copy link
Member

Weiko commented Oct 16, 2024

@charlesBochet tried to fix typing but couldn't find a good solution, seems bullmq redis option works with a string but typing does not accept string. I've updated our custom type to avoid type assertion but this is not the perfect solution. Ideally we should open an issue on bullmq repo

@Weiko
Copy link
Member

Weiko commented Oct 16, 2024

/award 300

Copy link

oss-gg bot commented Oct 16, 2024

Awarding thomasmol: 300 points 🕹️ Well done! Check out your new contribution on oss.gg/thomasmol

@charlesBochet charlesBochet merged commit ba2ee0d into twentyhq:main Oct 16, 2024
8 checks passed
@FelixMalfait
Copy link
Member

Thanks a lot @thomasmol!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enable IPv6 Support for Redis Database Connections Over a Private Netwoork
4 participants