From 47bb94a66675ca68597b7341e0a049a8c6297a18 Mon Sep 17 00:00:00 2001 From: Anthony Campolo <12433465+ajcwebdev@users.noreply.github.com> Date: Wed, 1 Jan 2025 18:28:23 -0600 Subject: [PATCH 1/2] remove whisperDocker and use node slim base image --- .github/Dockerfile | 19 ++++--- src/cli/commander.ts | 1 - src/transcription/whisper.ts | 98 ++++++------------------------------ test/all.test.ts | 80 +++++++++++++---------------- test/bench/base.test.ts | 2 +- test/bench/large.test.ts | 2 +- test/bench/medium.test.ts | 2 +- test/bench/small.test.ts | 2 +- test/bench/tiny.test.ts | 2 +- test/bench/turbo.test.ts | 2 +- 10 files changed, 70 insertions(+), 140 deletions(-) diff --git a/.github/Dockerfile b/.github/Dockerfile index da96ce0..731da43 100644 --- a/.github/Dockerfile +++ b/.github/Dockerfile @@ -1,14 +1,16 @@ # .github/Dockerfile # --------------------------------------------------- -# 1) Node base image +# 1) Node base image - Using Debian slim for smaller footprint # --------------------------------------------------- -FROM node:22 AS base +FROM node:22-slim AS base -RUN apt-get update && apt-get install -y \ - ffmpeg git make curl docker.io ca-certificates cmake \ - libopenblas-dev && rm -rf /var/lib/apt/lists/* +# Install only required system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + ffmpeg git make curl ca-certificates cmake python3 python3-pip \ + libopenblas-dev g++ build-essential && rm -rf /var/lib/apt/lists/* \ + && apt-get clean RUN update-ca-certificates @@ -25,7 +27,9 @@ RUN npm install -g tsx # Install whisper.cpp and download models RUN git clone https://github.com/ggerganov/whisper.cpp.git && \ cd whisper.cpp && \ - make && \ + cmake -B build && \ + cmake --build build -j --config Release && \ + # ./models/download-ggml-model.sh large-v3-turbo && \ ./models/download-ggml-model.sh base && \ ./models/download-ggml-model.sh tiny @@ -48,7 +52,8 @@ WORKDIR /root/.ollama # Start Ollama server and pull models RUN ollama serve & \ sleep 10 && \ - ollama pull llama2 && \ + ollama pull llama3.2:1b && \ + # ollama pull llama3.2:3b && \ pkill ollama # --------------------------------------------------- diff --git a/src/cli/commander.ts b/src/cli/commander.ts index 89bc4d3..3721bde 100644 --- a/src/cli/commander.ts +++ b/src/cli/commander.ts @@ -67,7 +67,6 @@ program .option('--info', 'Skip processing and write metadata to JSON objects (supports --urls, --rss, --playlist, --channel)') // Transcription service options .option('--whisper [model]', 'Use Whisper.cpp for transcription with optional model specification') - .option('--whisperDocker [model]', 'Use Whisper.cpp in Docker for transcription with optional model specification') .option('--deepgram', 'Use Deepgram for transcription') .option('--assembly', 'Use AssemblyAI for transcription') .option('--speakerLabels', 'Use speaker labels for AssemblyAI transcription') diff --git a/src/transcription/whisper.ts b/src/transcription/whisper.ts index 2d681d4..5cd54c4 100644 --- a/src/transcription/whisper.ts +++ b/src/transcription/whisper.ts @@ -1,12 +1,8 @@ // src/transcription/whisper.ts /** - * This file manages transcription using various Whisper-based methods: - * - `whisper`: Local whisper.cpp (recommended for single-container approach) - * - `whisperDocker`: Whisper.cpp inside Docker (legacy / fallback) - * - * In a single-container setup, you'll typically ONLY use `whisper`. - * The `whisperDocker` runner here is kept for backward compatibility. + * This file manages transcription using local Whisper.cpp. + * It provides a streamlined, single-container approach for audio transcription. */ import { readFile, writeFile } from 'node:fs/promises' @@ -15,68 +11,50 @@ import { lrcToTxt } from '../utils/format-transcript' import { WHISPER_MODELS, execPromise } from '../utils/globals' import { l, err } from '../utils/logging' import type { ProcessingOptions } from '../types/process' -import type { WhisperModelType, WhisperTranscriptServices, WhisperRunner } from '../types/transcription' +import type { WhisperModelType, WhisperRunner } from '../types/transcription' /** - * Main function to handle transcription using various Whisper-based methods. - * @param {ProcessingOptions} options - Additional processing options that determine how transcription is run. + * Main function to handle transcription using local Whisper.cpp. + * @param {ProcessingOptions} options - Processing options that determine how transcription is run. * @param {string} finalPath - The base filename (without extension) for input and output files. - * @param {WhisperTranscriptServices} transcriptServices - The chosen Whisper-based transcription method to use. * @returns {Promise} - The formatted transcript content as a string. */ export async function callWhisper( options: ProcessingOptions, - finalPath: string, - transcriptServices: WhisperTranscriptServices + finalPath: string ): Promise { - l.wait(`\n Using ${transcriptServices} for transcription...`) + l.wait('\n Using local whisper.cpp for transcription...') try { - // Config object: each property points to a different runner - const serviceConfig = { - whisper: { - option: options.whisper, // e.g. '--whisper base' - modelList: WHISPER_MODELS, - runner: runWhisperCpp, // Local runner - }, - whisperDocker: { - option: options.whisperDocker, // e.g. '--whisperDocker base' - modelList: WHISPER_MODELS, - runner: runWhisperDocker, // Docker runner (NOT recommended in single-container approach) - }, - } as const - - const config = serviceConfig[transcriptServices] - // Determine which model was requested (default to "base" if `--whisper` is passed with no model) - const whisperModel = typeof config.option === 'string' - ? config.option - : config.option === true + const whisperModel = typeof options.whisper === 'string' + ? options.whisper + : options.whisper === true ? 'base' - : (() => { throw new Error(`Invalid ${transcriptServices} option`) })() + : (() => { throw new Error('Invalid whisper option') })() // Validate that the requested model is in our known model list - if (!(whisperModel in config.modelList)) { + if (!(whisperModel in WHISPER_MODELS)) { throw new Error(`Unknown model type: ${whisperModel}`) } l.wait(`\n - whisperModel: ${whisperModel}`) - // Execute the appropriate runner function (local or Docker) - await config.runner(finalPath, whisperModel) + // Execute the local whisper.cpp runner + await runWhisperCpp(finalPath, whisperModel) // Read the newly created .txt file const txtContent = await readFile(`${finalPath}.txt`, 'utf8') return txtContent } catch (error) { - err(`Error in callWhisper with ${transcriptServices}:`, (error as Error).message) + err('Error in callWhisper:', (error as Error).message) process.exit(1) } } /** - * Runs transcription using the **local** whisper.cpp build inside this container. + * Runs transcription using the local whisper.cpp build inside this container. * * Steps: * 1. If whisper.cpp is not cloned/built locally, do so. @@ -117,48 +95,4 @@ const runWhisperCpp: WhisperRunner = async (finalPath, whisperModel) => { const txtContent = lrcToTxt(lrcContent) await writeFile(`${finalPath}.txt`, txtContent) l.success(` Transcript transformation successfully completed:\n - ${finalPath}.txt\n`) -} - -/** - * Runs transcription by calling Whisper.cpp in a separate Docker container. - * - * In a single-container approach, this is typically unused. If you keep this around - * for legacy reasons, you’ll see that it tries to `docker exec autoshow-whisper-1 ...`. - * - * If you’re no longer spinning up the separate `whisper` container, do NOT use `--whisperDocker`. - */ -const runWhisperDocker: WhisperRunner = async (finalPath, whisperModel) => { - // *** This is mostly for reference/legacy *** - const modelGGMLName = WHISPER_MODELS[whisperModel as WhisperModelType] - const CONTAINER_NAME = 'autoshow-whisper-1' - const modelPathContainer = `/app/models/${modelGGMLName}` - - l.wait(` - modelGGMLName: ${modelGGMLName}`) - l.wait(` - CONTAINER_NAME: ${CONTAINER_NAME}`) - l.wait(` - modelPathContainer: ${modelPathContainer}`) - - // Check if container is running; if not, we try to do `docker-compose up -d whisper` - await execPromise(`docker ps | grep ${CONTAINER_NAME}`) - .catch(() => execPromise('docker-compose up -d whisper')) - - // Check if model is present inside container; if not, download it - await execPromise(`docker exec ${CONTAINER_NAME} test -f ${modelPathContainer}`) - .catch(() => execPromise(`docker exec ${CONTAINER_NAME} /app/models/download-ggml-model.sh ${whisperModel}`)) - - // Run the CLI inside the whisper container - await execPromise( - `docker exec ${CONTAINER_NAME} ` + - `/app/build/bin/whisper-cli ` + - `-m ${modelPathContainer} ` + - `-f "/app/content/${finalPath.split('/').pop()}.wav" ` + - `-of "/app/content/${finalPath.split('/').pop()}" ` + - `--output-lrc` - ) - l.success(`\n Transcript LRC file successfully created:\n - ${finalPath}.lrc`) - - // Back on the host side, read .lrc and convert to .txt - const lrcContent = await readFile(`${finalPath}.lrc`, 'utf8') - const txtContent = lrcToTxt(lrcContent) - await writeFile(`${finalPath}.txt`, txtContent) - l.success(` Transcript transformation successfully completed:\n - ${finalPath}.txt\n`) } \ No newline at end of file diff --git a/test/all.test.ts b/test/all.test.ts index 72e8ab6..3fd300d 100644 --- a/test/all.test.ts +++ b/test/all.test.ts @@ -129,148 +129,140 @@ const commands = [ { cmd: 'npm run docker-cli -- --playlist "https://www.youtube.com/playlist?list=PLCVnrVv4KhXPz0SoAVu8Rc1emAdGPbSbr" --prompt titles --whisper tiny --chatgpt', expectedFiles: [ - { file: '2024-09-24-ep1-fsjam-podcast-chatgpt-shownotes.md', newName: '27-docker-prompt-whisper-chatgpt-shownotes.md' }, - { file: '2024-09-24-ep0-fsjam-podcast-chatgpt-shownotes.md', newName: '28-docker-prompt-whisper-chatgpt-shownotes.md' } + { file: '2024-09-24-ep1-fsjam-podcast-chatgpt-shownotes.md', newName: '26-docker-prompt-whisper-chatgpt-shownotes.md' }, + { file: '2024-09-24-ep0-fsjam-podcast-chatgpt-shownotes.md', newName: '27-docker-prompt-whisper-chatgpt-shownotes.md' } ] }, { cmd: 'npm run docker-cli -- --urls "content/example-urls.md" --prompt titles --whisper tiny --claude', expectedFiles: [ - { file: '2024-09-24-ep1-fsjam-podcast-claude-shownotes.md', newName: '29-docker-prompt-whisper-claude-shownotes.md' }, - { file: '2024-09-24-ep0-fsjam-podcast-claude-shownotes.md', newName: '30-docker-prompt-whisper-claude-shownotes.md' } + { file: '2024-09-24-ep1-fsjam-podcast-claude-shownotes.md', newName: '28-docker-prompt-whisper-claude-shownotes.md' }, + { file: '2024-09-24-ep0-fsjam-podcast-claude-shownotes.md', newName: '39-docker-prompt-whisper-claude-shownotes.md' } ] }, { cmd: 'npm run docker-cli -- --rss "https://ajcwebdev.substack.com/feed" --whisper base', expectedFile: '2021-05-10-thoughts-on-lambda-school-layoffs-prompt.md', - newName: '31-docker-rss-default.md' + newName: '30-docker-rss-default.md' }, { cmd: 'npm run docker-cli -- --rss "https://ajcwebdev.substack.com/feed" --info', expectedFile: 'ajcwebdev_info.json', - newName: '32-docker-ajcwebdev-rss-info.json', + newName: '31-docker-ajcwebdev-rss-info.json', }, { // Process local audio file with Dockerized Whisper 'base' model. cmd: 'npm run as -- --file "content/audio.mp3" --whisper base', expectedFile: 'audio-prompt.md', - newName: '33-docker-whisper-docker-base.md' - }, - { - // Process multiple YouTube videos from URLs with title prompts, Whisper 'tiny' model, and ChatGPT GPT_4o_MINI model. - cmd: 'npm run as -- --urls "content/example-urls.md" --prompt titles --whisper tiny --chatgpt GPT_4o_MINI', - expectedFiles: [ - { file: '2024-09-24-ep1-fsjam-podcast-chatgpt-shownotes.md', newName: '34-chatgpt-gpt-4o-mini.md' }, - { file: '2024-09-24-ep0-fsjam-podcast-chatgpt-shownotes.md', newName: '35-chatgpt-gpt-4o-mini.md' } - ] + newName: '32-docker-whisper-docker-base.md' }, { // Process a video using ChatGPT for LLM operations. cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --chatgpt', expectedFile: '2024-09-24-ep0-fsjam-podcast-chatgpt-shownotes.md', - newName: '36-chatgpt-default.md' + newName: '33-chatgpt-default.md' }, { // Process video with ChatGPT using GPT_4o_MINI model. cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --chatgpt GPT_4o_MINI', expectedFile: '2024-09-24-ep0-fsjam-podcast-chatgpt-shownotes.md', - newName: '37-chatgpt-gpt-4o-mini.md' + newName: '34-chatgpt-gpt-4o-mini.md' }, { // Process a video using Claude for LLM operations. cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --claude', expectedFile: '2024-09-24-ep0-fsjam-podcast-claude-shownotes.md', - newName: '38-claude-default.md' + newName: '35-claude-default.md' }, { // Process video with Claude using CLAUDE_3_SONNET model. cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --claude CLAUDE_3_SONNET', expectedFile: '2024-09-24-ep0-fsjam-podcast-claude-shownotes.md', - newName: '39-claude-shownotes.md' + newName: '36-claude-shownotes.md' }, { // Process a video using Gemini for LLM operations. cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --gemini', expectedFile: '2024-09-24-ep0-fsjam-podcast-gemini-shownotes.md', - newName: '40-gemini-shownotes.md' + newName: '37-gemini-shownotes.md' }, { // Process video with Gemini using GEMINI_1_5_FLASH model. cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --gemini GEMINI_1_5_FLASH', expectedFile: '2024-09-24-ep0-fsjam-podcast-gemini-shownotes.md', - newName: '41-gemini-shownotes.md' + newName: '38-gemini-shownotes.md' }, { // Process a video using Cohere for LLM operations cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --cohere', expectedFile: '2024-09-24-ep0-fsjam-podcast-cohere-shownotes.md', - newName: '42-cohere-shownotes.md' + newName: '39-cohere-shownotes.md' }, { - // Process video with Cohere using COMMAND_R_PLUS model. - cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --cohere COMMAND_R_PLUS', + // Process video with Cohere using COMMAND_R model. + cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --cohere COMMAND_R', expectedFile: '2024-09-24-ep0-fsjam-podcast-cohere-shownotes.md', - newName: '43-cohere-shownotes.md' + newName: '40-cohere-shownotes.md' }, { // Process a video using Mistral for LLM operations cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --mistral', expectedFile: '2024-09-24-ep0-fsjam-podcast-mistral-shownotes.md', - newName: '44-mistral-shownotes.md' + newName: '41-mistral-shownotes.md' }, { - // Process video with Mistral using MIXTRAL_8x7b model. - cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --mistral MIXTRAL_8x7b', + // Process video with Mistral using MINISTRAL_3B model. + cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --mistral MINISTRAL_3B', expectedFile: '2024-09-24-ep0-fsjam-podcast-mistral-shownotes.md', - newName: '45-mistral-shownotes.md' + newName: '42-mistral-shownotes.md' }, { // Process a video using Fireworks for LLM operations cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --fireworks', expectedFile: '2024-09-24-ep0-fsjam-podcast-fireworks-shownotes.md', - newName: '46-fireworks-shownotes.md' + newName: '43-fireworks-shownotes.md' }, { // Process a video using Together for LLM operations cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --together', expectedFile: '2024-09-24-ep0-fsjam-podcast-together-shownotes.md', - newName: '47-together-shownotes.md' + newName: '44-together-shownotes.md' }, { - // Process a video using BLANK for LLM operations + // Process a video using Groq for LLM operations cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --groq', expectedFile: '2024-09-24-ep0-fsjam-podcast-groq-shownotes.md', - newName: '48-groq-shownotes.md' + newName: '45-groq-shownotes.md' }, { // Process a video using Deepgram for transcription cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --deepgram', expectedFile: '2024-09-24-ep0-fsjam-podcast-prompt.md', - newName: '49-deepgram-prompt.md' + newName: '46-deepgram-prompt.md' }, { - // Process video using Deepgram and Llama. - cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --deepgram --ollama LLAMA_3_2_1B', - expectedFile: '2024-09-24-ep0-fsjam-podcast-ollama-shownotes.md', - newName: '50-deepgram-ollama-shownotes.md' + // Process video using Deepgram and Mistral's Ministral 3B model. + cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --deepgram --mistral MINISTRAL_3B', + expectedFile: '2024-09-24-ep0-fsjam-podcast-mistral-shownotes.md', + newName: '47-deepgram-mistral-shownotes.md' }, { // Process a video using AssemblyAI for transcription cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --assembly', expectedFile: '2024-09-24-ep0-fsjam-podcast-prompt.md', - newName: '51-assembly-prompt.md' + newName: '48-assembly-prompt.md' }, { - // Process video using AssemblyAI and Llama. - cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --assembly --ollama LLAMA_3_2_1B', - expectedFile: '2024-09-24-ep0-fsjam-podcast-ollama-shownotes.md', - newName: '52-assembly-ollama-shownotes.md' + // Process video using AssemblyAI and Mistral's Ministral 3B model. + cmd: 'npm run as -- --video "https://www.youtube.com/watch?v=MORMZXEaONk" --assembly --mistral MINISTRAL_3B', + expectedFile: '2024-09-24-ep0-fsjam-podcast-mistral-shownotes.md', + newName: '49-assembly-mistral-shownotes.md' }, { // Process an audio file using AssemblyAI with speaker labels cmd: 'npm run as -- --video "https://ajc.pics/audio/fsjam-short.mp3" --assembly --speakerLabels', expectedFile: '2024-05-08-fsjam-short-prompt.md', - newName: '53-assembly-speaker-labels-prompt.md' + newName: '50-assembly-speaker-labels-prompt.md' } ] diff --git a/test/bench/base.test.ts b/test/bench/base.test.ts index bac9385..913c7ca 100644 --- a/test/bench/base.test.ts +++ b/test/bench/base.test.ts @@ -19,7 +19,7 @@ const commands: Command[] = [ newName: '01_BASE_WHISPERCPP.md' }, { - cmd: 'npm run as -- --file "content/audio.mp3" --whisperDocker base', + cmd: 'npm run docker-cli -- --file "content/audio.mp3" --whisper base', expectedFile: 'audio-prompt.md', newName: '02_BASE_WHISPERCPP_DOCKER.md' }, diff --git a/test/bench/large.test.ts b/test/bench/large.test.ts index cc939f2..30514a4 100644 --- a/test/bench/large.test.ts +++ b/test/bench/large.test.ts @@ -19,7 +19,7 @@ const commands: Command[] = [ newName: '01_TINY_WHISPERCPP.md' }, { - cmd: 'npm run as -- --file "content/audio.mp3" --whisperDocker large-v2', + cmd: 'npm run docker-cli -- --file "content/audio.mp3" --whisper large-v2', expectedFile: 'audio-prompt.md', newName: '02_TINY_WHISPERCPP_DOCKER.md' }, diff --git a/test/bench/medium.test.ts b/test/bench/medium.test.ts index df13716..f488435 100644 --- a/test/bench/medium.test.ts +++ b/test/bench/medium.test.ts @@ -19,7 +19,7 @@ const commands: Command[] = [ newName: '01_TINY_WHISPERCPP.md' }, { - cmd: 'npm run as -- --file "content/audio.mp3" --whisperDocker medium', + cmd: 'npm run docker-cli -- --file "content/audio.mp3" --whisper medium', expectedFile: 'audio-prompt.md', newName: '02_TINY_WHISPERCPP_DOCKER.md' }, diff --git a/test/bench/small.test.ts b/test/bench/small.test.ts index b7de94d..2b26625 100644 --- a/test/bench/small.test.ts +++ b/test/bench/small.test.ts @@ -19,7 +19,7 @@ const commands: Command[] = [ newName: '01_TINY_WHISPERCPP.md' }, { - cmd: 'npm run as -- --file "content/audio.mp3" --whisperDocker small', + cmd: 'npm run docker-cli -- --file "content/audio.mp3" --whisper small', expectedFile: 'audio-prompt.md', newName: '02_TINY_WHISPERCPP_DOCKER.md' }, diff --git a/test/bench/tiny.test.ts b/test/bench/tiny.test.ts index 6bc3f64..454594b 100644 --- a/test/bench/tiny.test.ts +++ b/test/bench/tiny.test.ts @@ -19,7 +19,7 @@ const commands: Command[] = [ newName: '01_TINY_WHISPERCPP.md' }, { - cmd: 'npm run as -- --file "content/audio.mp3" --whisperDocker tiny', + cmd: 'npm run docker-cli -- --file "content/audio.mp3" --whisper tiny', expectedFile: 'audio-prompt.md', newName: '02_TINY_WHISPERCPP_DOCKER.md' }, diff --git a/test/bench/turbo.test.ts b/test/bench/turbo.test.ts index dc2c2bd..3194d85 100644 --- a/test/bench/turbo.test.ts +++ b/test/bench/turbo.test.ts @@ -19,7 +19,7 @@ const commands: Command[] = [ newName: '01_BASE_WHISPERCPP.md' }, { - cmd: 'npm run as -- --file "content/audio.mp3" --whisperDocker large-v3-turbo', + cmd: 'npm run docker-cli -- --file "content/audio.mp3" --whisper large-v3-turbo', expectedFile: 'audio-prompt.md', newName: '02_BASE_WHISPERCPP_DOCKER.md' }, From a2db52305bd2daae24e623029bc918f8b8de5f65 Mon Sep 17 00:00:00 2001 From: Anthony Campolo <12433465+ajcwebdev@users.noreply.github.com> Date: Wed, 1 Jan 2025 18:48:33 -0600 Subject: [PATCH 2/2] more dockerfile optimizations and fix fastify host --- .github/Dockerfile | 16 +++++++++++----- src/server/index.ts | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/Dockerfile b/.github/Dockerfile index 731da43..766545c 100644 --- a/.github/Dockerfile +++ b/.github/Dockerfile @@ -25,17 +25,18 @@ RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp \ RUN npm install -g tsx # Install whisper.cpp and download models -RUN git clone https://github.com/ggerganov/whisper.cpp.git && \ +RUN git clone --depth=1 https://github.com/ggerganov/whisper.cpp.git && \ cd whisper.cpp && \ cmake -B build && \ cmake --build build -j --config Release && \ - # ./models/download-ggml-model.sh large-v3-turbo && \ + ./models/download-ggml-model.sh large-v3-turbo && \ ./models/download-ggml-model.sh base && \ - ./models/download-ggml-model.sh tiny + ./models/download-ggml-model.sh tiny && \ + rm -rf .git # Copy package files and install deps COPY package*.json ./ -RUN npm ci +RUN npm ci --production && npm cache clean --force # Copy source code COPY src ./src @@ -53,7 +54,6 @@ WORKDIR /root/.ollama RUN ollama serve & \ sleep 10 && \ ollama pull llama3.2:1b && \ - # ollama pull llama3.2:3b && \ pkill ollama # --------------------------------------------------- @@ -69,6 +69,12 @@ COPY --from=ollama /root/.ollama /root/.ollama # Create content directory RUN mkdir -p content +# Set proper permissions +# RUN chown -R node:node /usr/src/app + +# Use non-root user +# USER node + EXPOSE 3000 ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"] CMD ["--help"] \ No newline at end of file diff --git a/src/server/index.ts b/src/server/index.ts index d19b841..f6dfdd1 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -40,7 +40,7 @@ async function start() { // Start the server await fastify.listen({ port, // Use configured port - host: '0.0.0.0', // Listen on all network interfaces + host: '::', // Listen on all network interfaces }) // Log successful server start