feat(infra): add external redis (#3639)
This commit is contained in:
@@ -64,6 +64,7 @@ ENV DB_URL='/appdata/db/db.sqlite'
|
|||||||
ENV DB_DIALECT='sqlite'
|
ENV DB_DIALECT='sqlite'
|
||||||
ENV DB_DRIVER='better-sqlite3'
|
ENV DB_DRIVER='better-sqlite3'
|
||||||
ENV AUTH_PROVIDERS='credentials'
|
ENV AUTH_PROVIDERS='credentials'
|
||||||
|
ENV REDIS_IS_EXTERNAL='false'
|
||||||
ENV NODE_ENV='production'
|
ENV NODE_ENV='production'
|
||||||
|
|
||||||
ENTRYPOINT [ "/app/entrypoint.sh" ]
|
ENTRYPOINT [ "/app/entrypoint.sh" ]
|
||||||
|
|||||||
@@ -25,11 +25,11 @@
|
|||||||
"@homarr/boards": "workspace:^0.1.0",
|
"@homarr/boards": "workspace:^0.1.0",
|
||||||
"@homarr/certificates": "workspace:^0.1.0",
|
"@homarr/certificates": "workspace:^0.1.0",
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"@homarr/cron-job-status": "workspace:^0.1.0",
|
"@homarr/cron-job-status": "workspace:^0.1.0",
|
||||||
"@homarr/db": "workspace:^0.1.0",
|
"@homarr/db": "workspace:^0.1.0",
|
||||||
"@homarr/definitions": "workspace:^0.1.0",
|
"@homarr/definitions": "workspace:^0.1.0",
|
||||||
"@homarr/docker": "workspace:^0.1.0",
|
"@homarr/docker": "workspace:^0.1.0",
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
|
||||||
"@homarr/form": "workspace:^0.1.0",
|
"@homarr/form": "workspace:^0.1.0",
|
||||||
"@homarr/forms-collection": "workspace:^0.1.0",
|
"@homarr/forms-collection": "workspace:^0.1.0",
|
||||||
"@homarr/gridstack": "^1.12.0",
|
"@homarr/gridstack": "^1.12.0",
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { createEnv } from "@homarr/env";
|
import { createBooleanSchema, createEnv } from "@homarr/core/infrastructure/env";
|
||||||
import { createBooleanSchema } from "@homarr/env/schemas";
|
|
||||||
|
|
||||||
export const env = createEnv({
|
export const env = createEnv({
|
||||||
server: {
|
server: {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { describe, expect, test } from "vitest";
|
import { describe, expect, test } from "vitest";
|
||||||
|
|
||||||
import { createHomarrContainer } from "./shared/create-homarr-container";
|
import { createHomarrContainer } from "./shared/create-homarr-container";
|
||||||
|
import { createRedisContainer } from "./shared/redis-container";
|
||||||
|
|
||||||
describe("Health checks", () => {
|
describe("Health checks", () => {
|
||||||
test("ready and live should return 200 OK", async () => {
|
test("ready and live should return 200 OK with normal image and no extra configuration", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const homarrContainer = await createHomarrContainer().start();
|
const homarrContainer = await createHomarrContainer().start();
|
||||||
|
|
||||||
@@ -15,4 +16,31 @@ describe("Health checks", () => {
|
|||||||
expect(readyResponse.status).toBe(200);
|
expect(readyResponse.status).toBe(200);
|
||||||
expect(liveResponse.status).toBe(200);
|
expect(liveResponse.status).toBe(200);
|
||||||
}, 20_000);
|
}, 20_000);
|
||||||
|
|
||||||
|
test("ready and live should return 200 OK with external redis", async () => {
|
||||||
|
// Arrange
|
||||||
|
const redisContainer = await createRedisContainer().start();
|
||||||
|
const homarrContainer = await createHomarrContainer({
|
||||||
|
environment: {
|
||||||
|
REDIS_IS_EXTERNAL: "true",
|
||||||
|
REDIS_HOST: "host.docker.internal",
|
||||||
|
REDIS_PORT: redisContainer.getMappedPort(6379).toString(),
|
||||||
|
REDIS_PASSWORD: redisContainer.getPassword(),
|
||||||
|
},
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const readyResponse = await fetch(`http://localhost:${homarrContainer.getMappedPort(7575)}/api/health/ready`);
|
||||||
|
const liveResponse = await fetch(`http://localhost:${homarrContainer.getMappedPort(7575)}/api/health/live`);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(
|
||||||
|
readyResponse.status,
|
||||||
|
`Expected ready to return OK statusCode=${readyResponse.status} content=${await readyResponse.text()}`,
|
||||||
|
).toBe(200);
|
||||||
|
expect(
|
||||||
|
liveResponse.status,
|
||||||
|
`Expected live to return OK statusCode=${liveResponse.status} content=${await liveResponse.text()}`,
|
||||||
|
).toBe(200);
|
||||||
|
}, 20_000);
|
||||||
});
|
});
|
||||||
|
|||||||
5
e2e/shared/redis-container.ts
Normal file
5
e2e/shared/redis-container.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { RedisContainer } from "@testcontainers/redis";
|
||||||
|
|
||||||
|
export const createRedisContainer = () => {
|
||||||
|
return new RedisContainer("redis:latest").withPassword("homarr");
|
||||||
|
};
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
"@semantic-release/github": "^11.0.3",
|
"@semantic-release/github": "^11.0.3",
|
||||||
"@semantic-release/npm": "^12.0.2",
|
"@semantic-release/npm": "^12.0.2",
|
||||||
"@semantic-release/release-notes-generator": "^14.0.3",
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
||||||
|
"@testcontainers/redis": "^11.2.1",
|
||||||
"@turbo/gen": "^2.5.5",
|
"@turbo/gen": "^2.5.5",
|
||||||
"@vitejs/plugin-react": "^4.7.0",
|
"@vitejs/plugin-react": "^4.7.0",
|
||||||
"@vitest/coverage-v8": "^3.2.4",
|
"@vitest/coverage-v8": "^3.2.4",
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { createBooleanSchema, createDurationSchema, createEnv } from "@homarr/core/infrastructure/env";
|
||||||
import { supportedAuthProviders } from "@homarr/definitions";
|
import { supportedAuthProviders } from "@homarr/definitions";
|
||||||
import { createEnv } from "@homarr/env";
|
|
||||||
import { createBooleanSchema, createDurationSchema } from "@homarr/env/schemas";
|
|
||||||
|
|
||||||
const authProvidersSchema = z
|
const authProvidersSchema = z
|
||||||
.string()
|
.string()
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
"@auth/drizzle-adapter": "^1.10.0",
|
"@auth/drizzle-adapter": "^1.10.0",
|
||||||
"@homarr/certificates": "workspace:^0.1.0",
|
"@homarr/certificates": "workspace:^0.1.0",
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"@homarr/db": "workspace:^0.1.0",
|
"@homarr/db": "workspace:^0.1.0",
|
||||||
"@homarr/definitions": "workspace:^0.1.0",
|
"@homarr/definitions": "workspace:^0.1.0",
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
|
||||||
"@homarr/log": "workspace:^0.1.0",
|
"@homarr/log": "workspace:^0.1.0",
|
||||||
"@homarr/validation": "workspace:^0.1.0",
|
"@homarr/validation": "workspace:^0.1.0",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { randomBytes } from "crypto";
|
import { randomBytes } from "crypto";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createEnv } from "@homarr/env";
|
import { createEnv } from "@homarr/core/infrastructure/env";
|
||||||
|
|
||||||
const errorSuffix = `, please generate a 64 character secret in hex format or use the following: "${randomBytes(32).toString("hex")}"`;
|
const errorSuffix = `, please generate a 64 character secret in hex format or use the following: "${randomBytes(32).toString("hex")}"`;
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"@homarr/log": "workspace:^0.1.0",
|
"@homarr/log": "workspace:^0.1.0",
|
||||||
"@paralleldrive/cuid2": "^2.2.2",
|
"@paralleldrive/cuid2": "^2.2.2",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
import baseConfig from "@homarr/eslint-config/base";
|
import baseConfig from "@homarr/eslint-config/base";
|
||||||
|
|
||||||
/** @type {import('typescript-eslint').Config} */
|
/** @type {import('typescript-eslint').Config} */
|
||||||
export default [
|
export default [...baseConfig];
|
||||||
{
|
|
||||||
ignores: [],
|
|
||||||
},
|
|
||||||
...baseConfig,
|
|
||||||
];
|
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@homarr/env",
|
"name": "@homarr/core",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./index.ts",
|
"./infrastructure/redis": "./src/infrastructure/redis/client.ts",
|
||||||
"./schemas": "./src/schemas.ts"
|
"./infrastructure/env": "./src/infrastructure/env/index.ts",
|
||||||
|
".": "./src/index.ts"
|
||||||
},
|
},
|
||||||
"typesVersions": {
|
"typesVersions": {
|
||||||
"*": {
|
"*": {
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@t3-oss/env-nextjs": "^0.13.8",
|
"@t3-oss/env-nextjs": "^0.13.8",
|
||||||
|
"ioredis": "5.6.1",
|
||||||
"zod": "^3.25.76"
|
"zod": "^3.25.76"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -7,3 +7,6 @@ export const defaultEnvOptions = {
|
|||||||
} satisfies Partial<Parameters<typeof createEnvT3>[0]>;
|
} satisfies Partial<Parameters<typeof createEnvT3>[0]>;
|
||||||
|
|
||||||
export const createEnv: typeof createEnvT3 = (options) => createEnvT3({ ...defaultEnvOptions, ...options });
|
export const createEnv: typeof createEnvT3 = (options) => createEnvT3({ ...defaultEnvOptions, ...options });
|
||||||
|
|
||||||
|
export * from "./prefix";
|
||||||
|
export * from "./schemas";
|
||||||
13
packages/core/src/infrastructure/env/prefix.ts
vendored
Normal file
13
packages/core/src/infrastructure/env/prefix.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export const runtimeEnvWithPrefix = (prefix: `${string}_`) =>
|
||||||
|
Object.entries(process.env)
|
||||||
|
.filter(([key]) => key.startsWith(prefix))
|
||||||
|
.reduce(
|
||||||
|
(acc, [key, value]) => {
|
||||||
|
if (value === undefined) return acc;
|
||||||
|
|
||||||
|
const newKey = key.replace(prefix, "");
|
||||||
|
acc[newKey] = value;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string, string>,
|
||||||
|
);
|
||||||
26
packages/core/src/infrastructure/redis/client.ts
Normal file
26
packages/core/src/infrastructure/redis/client.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import type { RedisOptions } from "ioredis";
|
||||||
|
import { Redis } from "ioredis";
|
||||||
|
|
||||||
|
import { redisEnv } from "./env";
|
||||||
|
|
||||||
|
const defaultRedisOptions = {
|
||||||
|
connectionName: "homarr",
|
||||||
|
} satisfies RedisOptions;
|
||||||
|
|
||||||
|
export type { Redis as RedisClient } from "ioredis";
|
||||||
|
|
||||||
|
export const createRedisClient = () =>
|
||||||
|
redisEnv.IS_EXTERNAL
|
||||||
|
? new Redis({
|
||||||
|
...defaultRedisOptions,
|
||||||
|
host: redisEnv.HOST,
|
||||||
|
port: redisEnv.PORT,
|
||||||
|
tls: redisEnv.TLS_CA
|
||||||
|
? {
|
||||||
|
ca: redisEnv.TLS_CA,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
username: redisEnv.USERNAME,
|
||||||
|
password: redisEnv.PASSWORD,
|
||||||
|
})
|
||||||
|
: new Redis(defaultRedisOptions);
|
||||||
17
packages/core/src/infrastructure/redis/env.ts
Normal file
17
packages/core/src/infrastructure/redis/env.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
|
import { createEnv } from "../env";
|
||||||
|
import { runtimeEnvWithPrefix } from "../env/prefix";
|
||||||
|
import { createBooleanSchema } from "../env/schemas";
|
||||||
|
|
||||||
|
export const redisEnv = createEnv({
|
||||||
|
server: {
|
||||||
|
IS_EXTERNAL: createBooleanSchema(false),
|
||||||
|
HOST: z.string().optional(),
|
||||||
|
PORT: z.coerce.number().default(6379).optional(),
|
||||||
|
TLS_CA: z.string().optional(),
|
||||||
|
USERNAME: z.string().optional(),
|
||||||
|
PASSWORD: z.string().optional(),
|
||||||
|
},
|
||||||
|
runtimeEnv: runtimeEnvWithPrefix("REDIS_"),
|
||||||
|
});
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"@homarr/cron-jobs": "workspace:^0.1.0",
|
"@homarr/cron-jobs": "workspace:^0.1.0",
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
|
||||||
"@homarr/log": "workspace:^0.1.0",
|
"@homarr/log": "workspace:^0.1.0",
|
||||||
"@tanstack/react-query": "^5.83.0",
|
"@tanstack/react-query": "^5.83.0",
|
||||||
"@trpc/client": "^11.4.3",
|
"@trpc/client": "^11.4.3",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { z } from "zod/v4";
|
import { z } from "zod/v4";
|
||||||
|
|
||||||
import { env as commonEnv } from "@homarr/common/env";
|
import { env as commonEnv } from "@homarr/common/env";
|
||||||
import { createEnv } from "@homarr/env";
|
import { createEnv } from "@homarr/core/infrastructure/env";
|
||||||
|
|
||||||
export const env = createEnv({
|
export const env = createEnv({
|
||||||
server: {
|
server: {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { env as commonEnv } from "@homarr/common/env";
|
import { env as commonEnv } from "@homarr/common/env";
|
||||||
import { createEnv } from "@homarr/env";
|
import { createEnv } from "@homarr/core/infrastructure/env";
|
||||||
|
|
||||||
const drivers = {
|
const drivers = {
|
||||||
betterSqlite3: "better-sqlite3",
|
betterSqlite3: "better-sqlite3",
|
||||||
|
|||||||
@@ -40,8 +40,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth/core": "^0.40.0",
|
"@auth/core": "^0.40.0",
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"@homarr/definitions": "workspace:^0.1.0",
|
"@homarr/definitions": "workspace:^0.1.0",
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
|
||||||
"@homarr/log": "workspace:^0.1.0",
|
"@homarr/log": "workspace:^0.1.0",
|
||||||
"@homarr/server-settings": "workspace:^0.1.0",
|
"@homarr/server-settings": "workspace:^0.1.0",
|
||||||
"@mantine/core": "^8.1.3",
|
"@mantine/core": "^8.1.3",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/common": "workspace:^0.1.0",
|
"@homarr/common": "workspace:^0.1.0",
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"dockerode": "^4.0.7"
|
"dockerode": "^4.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createEnv } from "@homarr/env";
|
import { createBooleanSchema, createEnv } from "@homarr/core/infrastructure/env";
|
||||||
import { createBooleanSchema } from "@homarr/env/schemas";
|
|
||||||
|
|
||||||
export const env = createEnv({
|
export const env = createEnv({
|
||||||
server: {
|
server: {
|
||||||
|
|||||||
1
packages/env/index.ts
vendored
1
packages/env/index.ts
vendored
@@ -1 +0,0 @@
|
|||||||
export * from "./src";
|
|
||||||
@@ -24,8 +24,7 @@
|
|||||||
},
|
},
|
||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/env": "workspace:^0.1.0",
|
"@homarr/core": "workspace:^0.1.0",
|
||||||
"ioredis": "5.6.1",
|
|
||||||
"superjson": "2.2.2",
|
"superjson": "2.2.2",
|
||||||
"winston": "3.17.0",
|
"winston": "3.17.0",
|
||||||
"zod": "^3.25.76"
|
"zod": "^3.25.76"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createEnv } from "@homarr/env";
|
import { createEnv } from "@homarr/core/infrastructure/env";
|
||||||
|
|
||||||
import { logLevels } from "./constants";
|
import { logLevels } from "./constants";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { Redis } from "ioredis";
|
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
import Transport from "winston-transport";
|
import Transport from "winston-transport";
|
||||||
|
|
||||||
|
import type { RedisClient } from "@homarr/core/infrastructure/redis";
|
||||||
|
import { createRedisClient } from "@homarr/core/infrastructure/redis";
|
||||||
|
|
||||||
const messageSymbol = Symbol.for("message");
|
const messageSymbol = Symbol.for("message");
|
||||||
const levelSymbol = Symbol.for("level");
|
const levelSymbol = Symbol.for("level");
|
||||||
|
|
||||||
@@ -10,7 +12,7 @@ const levelSymbol = Symbol.for("level");
|
|||||||
// of the base functionality and `.exceptions.handle()`.
|
// of the base functionality and `.exceptions.handle()`.
|
||||||
//
|
//
|
||||||
export class RedisTransport extends Transport {
|
export class RedisTransport extends Transport {
|
||||||
private redis: Redis | null = null;
|
private redis: RedisClient | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log the info to the Redis channel
|
* Log the info to the Redis channel
|
||||||
@@ -21,7 +23,7 @@ export class RedisTransport extends Transport {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Is only initialized here because it did not work when initialized in the constructor or outside the class
|
// Is only initialized here because it did not work when initialized in the constructor or outside the class
|
||||||
this.redis ??= new Redis();
|
this.redis ??= createRedisClient();
|
||||||
|
|
||||||
this.redis
|
this.redis
|
||||||
.publish(
|
.publish(
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
"prettier": "@homarr/prettier-config",
|
"prettier": "@homarr/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@homarr/common": "workspace:^",
|
"@homarr/common": "workspace:^",
|
||||||
|
"@homarr/core": "workspace:^",
|
||||||
|
"@homarr/db": "workspace:^",
|
||||||
"@homarr/definitions": "workspace:^",
|
"@homarr/definitions": "workspace:^",
|
||||||
"@homarr/log": "workspace:^",
|
"@homarr/log": "workspace:^",
|
||||||
"ioredis": "5.6.1",
|
"ioredis": "5.6.1",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Redis } from "ioredis";
|
import type { RedisClient } from "@homarr/core/infrastructure/redis";
|
||||||
|
import { createRedisClient } from "@homarr/core/infrastructure/redis";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Redis connection
|
* Creates a new Redis connection
|
||||||
@@ -7,8 +8,8 @@ import { Redis } from "ioredis";
|
|||||||
export const createRedisConnection = () => {
|
export const createRedisConnection = () => {
|
||||||
if (Boolean(process.env.CI) || Boolean(process.env.DISABLE_REDIS_LOGS)) {
|
if (Boolean(process.env.CI) || Boolean(process.env.DISABLE_REDIS_LOGS)) {
|
||||||
// Return null if we are in CI as we don't want to connect to Redis
|
// Return null if we are in CI as we don't want to connect to Redis
|
||||||
return null as unknown as Redis;
|
return null as unknown as RedisClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Redis();
|
return createRedisClient();
|
||||||
};
|
};
|
||||||
|
|||||||
113
pnpm-lock.yaml
generated
113
pnpm-lock.yaml
generated
@@ -37,6 +37,9 @@ importers:
|
|||||||
'@semantic-release/release-notes-generator':
|
'@semantic-release/release-notes-generator':
|
||||||
specifier: ^14.0.3
|
specifier: ^14.0.3
|
||||||
version: 14.0.3(semantic-release@24.2.7(typescript@5.8.3))
|
version: 14.0.3(semantic-release@24.2.7(typescript@5.8.3))
|
||||||
|
'@testcontainers/redis':
|
||||||
|
specifier: ^11.2.1
|
||||||
|
version: 11.2.1
|
||||||
'@turbo/gen':
|
'@turbo/gen':
|
||||||
specifier: ^2.5.5
|
specifier: ^2.5.5
|
||||||
version: 2.5.5(@types/node@22.16.4)(typescript@5.8.3)
|
version: 2.5.5(@types/node@22.16.4)(typescript@5.8.3)
|
||||||
@@ -112,6 +115,9 @@ importers:
|
|||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../../packages/common
|
version: link:../../packages/common
|
||||||
|
'@homarr/core':
|
||||||
|
specifier: workspace:^0.1.0
|
||||||
|
version: link:../../packages/core
|
||||||
'@homarr/cron-job-status':
|
'@homarr/cron-job-status':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../../packages/cron-job-status
|
version: link:../../packages/cron-job-status
|
||||||
@@ -124,9 +130,6 @@ importers:
|
|||||||
'@homarr/docker':
|
'@homarr/docker':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../../packages/docker
|
version: link:../../packages/docker
|
||||||
'@homarr/env':
|
|
||||||
specifier: workspace:^0.1.0
|
|
||||||
version: link:../../packages/env
|
|
||||||
'@homarr/form':
|
'@homarr/form':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../../packages/form
|
version: link:../../packages/form
|
||||||
@@ -660,15 +663,15 @@ importers:
|
|||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../common
|
version: link:../common
|
||||||
|
'@homarr/core':
|
||||||
|
specifier: workspace:^0.1.0
|
||||||
|
version: link:../core
|
||||||
'@homarr/db':
|
'@homarr/db':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../db
|
version: link:../db
|
||||||
'@homarr/definitions':
|
'@homarr/definitions':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../definitions
|
version: link:../definitions
|
||||||
'@homarr/env':
|
|
||||||
specifier: workspace:^0.1.0
|
|
||||||
version: link:../env
|
|
||||||
'@homarr/log':
|
'@homarr/log':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../log
|
version: link:../log
|
||||||
@@ -823,9 +826,9 @@ importers:
|
|||||||
|
|
||||||
packages/common:
|
packages/common:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@homarr/env':
|
'@homarr/core':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../env
|
version: link:../core
|
||||||
'@homarr/log':
|
'@homarr/log':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../log
|
version: link:../log
|
||||||
@@ -870,17 +873,45 @@ importers:
|
|||||||
specifier: ^5.8.3
|
specifier: ^5.8.3
|
||||||
version: 5.8.3
|
version: 5.8.3
|
||||||
|
|
||||||
|
packages/core:
|
||||||
|
dependencies:
|
||||||
|
'@t3-oss/env-nextjs':
|
||||||
|
specifier: ^0.13.8
|
||||||
|
version: 0.13.8(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.76)
|
||||||
|
ioredis:
|
||||||
|
specifier: 5.6.1
|
||||||
|
version: 5.6.1
|
||||||
|
zod:
|
||||||
|
specifier: ^3.25.76
|
||||||
|
version: 3.25.76
|
||||||
|
devDependencies:
|
||||||
|
'@homarr/eslint-config':
|
||||||
|
specifier: workspace:^0.2.0
|
||||||
|
version: link:../../tooling/eslint
|
||||||
|
'@homarr/prettier-config':
|
||||||
|
specifier: workspace:^0.1.0
|
||||||
|
version: link:../../tooling/prettier
|
||||||
|
'@homarr/tsconfig':
|
||||||
|
specifier: workspace:^0.1.0
|
||||||
|
version: link:../../tooling/typescript
|
||||||
|
eslint:
|
||||||
|
specifier: ^9.31.0
|
||||||
|
version: 9.31.0
|
||||||
|
typescript:
|
||||||
|
specifier: ^5.8.3
|
||||||
|
version: 5.8.3
|
||||||
|
|
||||||
packages/cron-job-api:
|
packages/cron-job-api:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../common
|
version: link:../common
|
||||||
|
'@homarr/core':
|
||||||
|
specifier: workspace:^0.1.0
|
||||||
|
version: link:../core
|
||||||
'@homarr/cron-jobs':
|
'@homarr/cron-jobs':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../cron-jobs
|
version: link:../cron-jobs
|
||||||
'@homarr/env':
|
|
||||||
specifier: workspace:^0.1.0
|
|
||||||
version: link:../env
|
|
||||||
'@homarr/log':
|
'@homarr/log':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../log
|
version: link:../log
|
||||||
@@ -1056,12 +1087,12 @@ importers:
|
|||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../common
|
version: link:../common
|
||||||
|
'@homarr/core':
|
||||||
|
specifier: workspace:^0.1.0
|
||||||
|
version: link:../core
|
||||||
'@homarr/definitions':
|
'@homarr/definitions':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../definitions
|
version: link:../definitions
|
||||||
'@homarr/env':
|
|
||||||
specifier: workspace:^0.1.0
|
|
||||||
version: link:../env
|
|
||||||
'@homarr/log':
|
'@homarr/log':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../log
|
version: link:../log
|
||||||
@@ -1166,9 +1197,9 @@ importers:
|
|||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../common
|
version: link:../common
|
||||||
'@homarr/env':
|
'@homarr/core':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../env
|
version: link:../core
|
||||||
dockerode:
|
dockerode:
|
||||||
specifier: ^4.0.7
|
specifier: ^4.0.7
|
||||||
version: 4.0.7
|
version: 4.0.7
|
||||||
@@ -1192,31 +1223,6 @@ importers:
|
|||||||
specifier: ^5.8.3
|
specifier: ^5.8.3
|
||||||
version: 5.8.3
|
version: 5.8.3
|
||||||
|
|
||||||
packages/env:
|
|
||||||
dependencies:
|
|
||||||
'@t3-oss/env-nextjs':
|
|
||||||
specifier: ^0.13.8
|
|
||||||
version: 0.13.8(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.76)
|
|
||||||
zod:
|
|
||||||
specifier: ^3.25.76
|
|
||||||
version: 3.25.76
|
|
||||||
devDependencies:
|
|
||||||
'@homarr/eslint-config':
|
|
||||||
specifier: workspace:^0.2.0
|
|
||||||
version: link:../../tooling/eslint
|
|
||||||
'@homarr/prettier-config':
|
|
||||||
specifier: workspace:^0.1.0
|
|
||||||
version: link:../../tooling/prettier
|
|
||||||
'@homarr/tsconfig':
|
|
||||||
specifier: workspace:^0.1.0
|
|
||||||
version: link:../../tooling/typescript
|
|
||||||
eslint:
|
|
||||||
specifier: ^9.31.0
|
|
||||||
version: 9.31.0
|
|
||||||
typescript:
|
|
||||||
specifier: ^5.8.3
|
|
||||||
version: 5.8.3
|
|
||||||
|
|
||||||
packages/form:
|
packages/form:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
@@ -1461,12 +1467,9 @@ importers:
|
|||||||
|
|
||||||
packages/log:
|
packages/log:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@homarr/env':
|
'@homarr/core':
|
||||||
specifier: workspace:^0.1.0
|
specifier: workspace:^0.1.0
|
||||||
version: link:../env
|
version: link:../core
|
||||||
ioredis:
|
|
||||||
specifier: 5.6.1
|
|
||||||
version: 5.6.1
|
|
||||||
superjson:
|
superjson:
|
||||||
specifier: 2.2.2
|
specifier: 2.2.2
|
||||||
version: 2.2.2
|
version: 2.2.2
|
||||||
@@ -1740,6 +1743,12 @@ importers:
|
|||||||
'@homarr/common':
|
'@homarr/common':
|
||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
version: link:../common
|
version: link:../common
|
||||||
|
'@homarr/core':
|
||||||
|
specifier: workspace:^
|
||||||
|
version: link:../core
|
||||||
|
'@homarr/db':
|
||||||
|
specifier: workspace:^
|
||||||
|
version: link:../db
|
||||||
'@homarr/definitions':
|
'@homarr/definitions':
|
||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
version: link:../definitions
|
version: link:../definitions
|
||||||
@@ -4423,6 +4432,9 @@ packages:
|
|||||||
'@testcontainers/mysql@11.3.0':
|
'@testcontainers/mysql@11.3.0':
|
||||||
resolution: {integrity: sha512-5zOzAcsQUVbN9tCC6cbD0zkxOu/P8NdFsYc+w1YFctGUOf5DL0QBBwDv5LkFj92+eic4veggPlzVd2SX8LT3SQ==}
|
resolution: {integrity: sha512-5zOzAcsQUVbN9tCC6cbD0zkxOu/P8NdFsYc+w1YFctGUOf5DL0QBBwDv5LkFj92+eic4veggPlzVd2SX8LT3SQ==}
|
||||||
|
|
||||||
|
'@testcontainers/redis@11.2.1':
|
||||||
|
resolution: {integrity: sha512-Q5j+irNw0BLec3he30s2E0fhE06Zr9ROVutkyKUgcwQoZxEVW3xV69ke2AFCT5teEcIvTKqevObN4UDkq33Qow==}
|
||||||
|
|
||||||
'@tiptap/core@2.26.1':
|
'@tiptap/core@2.26.1':
|
||||||
resolution: {integrity: sha512-fymyd/XZvYiHjBoLt1gxs024xP/LY26d43R1vluYq7AHBL/7DE3ywzy+1GEsGyAv5Je2L0KBhNIR/izbq3Kaqg==}
|
resolution: {integrity: sha512-fymyd/XZvYiHjBoLt1gxs024xP/LY26d43R1vluYq7AHBL/7DE3ywzy+1GEsGyAv5Je2L0KBhNIR/izbq3Kaqg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -13172,6 +13184,13 @@ snapshots:
|
|||||||
- bare-buffer
|
- bare-buffer
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@testcontainers/redis@11.2.1':
|
||||||
|
dependencies:
|
||||||
|
testcontainers: 11.3.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bare-buffer
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@tiptap/core@2.26.1(@tiptap/pm@2.26.1)':
|
'@tiptap/core@2.26.1(@tiptap/pm@2.26.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/pm': 2.26.1
|
'@tiptap/pm': 2.26.1
|
||||||
@@ -16639,7 +16658,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@ioredis/commands': 1.2.0
|
'@ioredis/commands': 1.2.0
|
||||||
cluster-key-slot: 1.1.2
|
cluster-key-slot: 1.1.2
|
||||||
debug: 4.4.0
|
debug: 4.4.1
|
||||||
denque: 2.1.0
|
denque: 2.1.0
|
||||||
lodash.defaults: 4.2.0
|
lodash.defaults: 4.2.0
|
||||||
lodash.isarguments: 3.1.0
|
lodash.isarguments: 3.1.0
|
||||||
|
|||||||
@@ -25,8 +25,15 @@ envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
|
|||||||
nginx -g 'daemon off;' &
|
nginx -g 'daemon off;' &
|
||||||
NGINX_PID=$!
|
NGINX_PID=$!
|
||||||
|
|
||||||
redis-server /app/redis.conf &
|
if [ $REDIS_IS_EXTERNAL = "true" ]; then
|
||||||
REDIS_PID=$!
|
echo "Using external Redis server at redis://$REDIS_HOST:$REDIS_PORT"
|
||||||
|
else
|
||||||
|
echo "Starting internal Redis server"
|
||||||
|
redis-server /app/redis.conf &
|
||||||
|
REDIS_PID=$!
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
node apps/tasks/tasks.cjs &
|
node apps/tasks/tasks.cjs &
|
||||||
TASKS_PID=$!
|
TASKS_PID=$!
|
||||||
|
|||||||
Reference in New Issue
Block a user