diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4b3aa27 --- /dev/null +++ b/.env.example @@ -0,0 +1,38 @@ +# Required +JELLYFIN_URL= +JELLYFIN_API_KEY= +JELLYFIN_USER_ID= +TMDB_API_KEY= + +# LLM (disabled by default — works with Ollama, OpenAI, LM Studio, etc.) +LLM_ENABLED=false +LLM_BASE_URL=http://localhost:11434/v1 +LLM_API_KEY= +LLM_MODEL=llama3 + +# Radarr (disabled by default) +RADARR_ENABLED=false +RADARR_URL= +RADARR_API_KEY= +RADARR_QUALITY_PROFILE_ID=1 +RADARR_ROOT_FOLDER=/movies + +# Cron auto-run (disabled by default) +CRON_ENABLED=false +CRON_SCHEDULE=0 3 * * * + +# HTTP API (enabled by default) +API_ENABLED=true +API_PORT=8080 +SECRET_KEY= + +# Tuning +RECOMMEND_COUNT=10 +RECOMMEND_MAX_RETRY=3 +MIN_RATED_MOVIES=5 + +# Langfuse (required by the TypeScript app) +LANGFUSE_PUBLIC_KEY= +LANGFUSE_SECRET_KEY= +LANGFUSE_BASE_URL= +LANGFUSE_PROMPT_CACHE_ENABLED=true diff --git a/Dockerfile.node b/Dockerfile.node new file mode 100644 index 0000000..3ea0847 --- /dev/null +++ b/Dockerfile.node @@ -0,0 +1,17 @@ +FROM node:22-alpine AS build +WORKDIR /app +RUN corepack enable +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --ignore-scripts +COPY tsconfig.json ./ +COPY src ./src +RUN pnpm build + +FROM node:22-alpine AS runtime +WORKDIR /app +ENV NODE_ENV=production +RUN corepack enable +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --prod +COPY --from=build /app/dist ./dist +ENTRYPOINT ["node", "dist/app/index.js"] diff --git a/docker-compose.node.yml b/docker-compose.node.yml new file mode 100644 index 0000000..400770f --- /dev/null +++ b/docker-compose.node.yml @@ -0,0 +1,40 @@ +services: + sugarr-node: + build: + context: . + dockerfile: Dockerfile.node + container_name: sugarr-node + restart: unless-stopped + ports: + - "${API_PORT}:${API_PORT}" + environment: + JELLYFIN_URL: ${JELLYFIN_URL} + JELLYFIN_API_KEY: ${JELLYFIN_API_KEY} + JELLYFIN_USER_ID: ${JELLYFIN_USER_ID} + TMDB_API_KEY: ${TMDB_API_KEY} + LLM_ENABLED: ${LLM_ENABLED} + LLM_BASE_URL: ${LLM_BASE_URL} + LLM_MODEL: ${LLM_MODEL} + LLM_API_KEY: ${LLM_API_KEY} + RADARR_ENABLED: ${RADARR_ENABLED} + RADARR_URL: ${RADARR_URL} + RADARR_API_KEY: ${RADARR_API_KEY} + RADARR_QUALITY_PROFILE_ID: ${RADARR_QUALITY_PROFILE_ID} + RADARR_ROOT_FOLDER: ${RADARR_ROOT_FOLDER} + CRON_ENABLED: ${CRON_ENABLED} + CRON_SCHEDULE: ${CRON_SCHEDULE} + API_ENABLED: ${API_ENABLED} + API_PORT: ${API_PORT} + SECRET_KEY: ${SECRET_KEY} + RECOMMEND_COUNT: ${RECOMMEND_COUNT} + RECOMMEND_MAX_RETRY: ${RECOMMEND_MAX_RETRY} + MIN_RATED_MOVIES: ${MIN_RATED_MOVIES} + LANGFUSE_PUBLIC_KEY: ${LANGFUSE_PUBLIC_KEY} + LANGFUSE_SECRET_KEY: ${LANGFUSE_SECRET_KEY} + LANGFUSE_BASE_URL: ${LANGFUSE_BASE_URL} + LANGFUSE_PROMPT_CACHE_ENABLED: ${LANGFUSE_PROMPT_CACHE_ENABLED} + networks: + - media + +networks: + media: