2 years ago
I have a Next.js app that uses ioredis for caching, and bullmq for background tasks (which also uses ioredis).
The problem is, when Next.js builds it tries to connect to the redis instance (part of static/server rendering functionality). It fails because the private redis connection is not available at built time.
In any case, I want to disable this at build time and just use default values, not reading from the cache until the container is actually running. I noticed in the docs there is a built-in CI=true env var available so I tried using that at build time to prevent the redis connection by creating a stub redis instance, which did work. However, that variable still appears to be true at runtime so I ended up using the stub redis instance in production. NODE_ENV is also production in both places, and all my custom env vars appears to be available and the same at build, deploy and runtime so there doesn't appear to be a way to distinguish between them.
Am I missing something? Is there a way I can achieve what I want by detecting which environment/stage the code it running in?
Thanks!
4 Replies
2 years ago
Could you set an environment variable in your build script?
{
"build": "BUILD=True <your original build script>"
}2 years ago
Seems to work! Simple as that. Seems obvious now you've said it. I was going round in circles before haha.
Slight tweak though - can't have the semicolon since that isolates the command. It needs to set the env var as part of the script that's being invoked.
{
"build": "BUILD=true next build"
}Thanks for the rapid response!
Also might as well share. If anyone else finds this problem, here's my implementation.
import { env } from "@/env";
import { Redis, type RedisOptions } from "ioredis";
let redis: Redis | null = null;
function _createClient(options?: RedisOptions) {
return new Redis(env.REDIS_URL, {
...options,
// Set to enable hosted application to choose between IPv4 or IPv6 family to work with Railway networking.
family: 0,
});
}
/** Create a stub redis client that is used just for Next.js build time. */
const _createStubClient = () => {
return {
options: {},
get: async () => null,
info: async () => "",
set: async () => null,
del: async () => null,
incr: async () => null,
expire: async () => null,
unlink: async () => null,
} as unknown as Redis;
};
/** Create a new Redis client. */
const createClient = (options?: RedisOptions) => {
return env.BUILD ? _createStubClient() : _createClient(options);
};
/** Get or create a singleton Redis client. */
const cache = () => {
if (!redis) {
redis = createClient();
}
return redis;
};
export { cache };
/** Usage */
import { cache } from "~/cache";
const value = await cache().get('SOME_KEY');Status changed to Solved brody • over 1 year ago
