enhancement: Docker image consolidation

This commit is contained in:
pluja
2023-11-21 17:29:16 +01:00
parent 7dc703c335
commit 8dca6cc897
12 changed files with 353 additions and 308 deletions

37
.dockerignore Normal file
View File

@@ -0,0 +1,37 @@
# General files
*.yml
*.log
*.bat
*.md
*.txt
.env*
Dockerfile
.gitignore
.eslintignore
.eslintrc.js
.prettierrc
# Directories
.github
.git
node_modules
.svelte-kit
__pycache__
.ruff_cache
.venv
.vscode
whisper_models
whishper_data
misc
# Recursive patterns
**/node_modules/
**/__pycache__/
**/.ruff_cache
**/.venv
**/.vscode
**/whisper_models
**/whishper_data
**/.github
**/.git
**/.svelte-kit

76
Dockerfile Normal file
View File

@@ -0,0 +1,76 @@
# YT-DLP Download and setup
FROM --platform=$BUILDPLATFORM golang:bookworm AS ytdlp_cache
ARG TARGETOS
ARG TARGETARCH
RUN apt update && apt install -y wget
RUN wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp
RUN chmod a+rx /usr/local/bin/yt-dlp
# Backend setup
FROM devopsworks/golang-upx:latest as backend-builder
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /app
COPY ./backend /app
RUN go mod tidy
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o whishper . && \
upx whishper
RUN chmod a+rx whishper
# Frontend setup
FROM node:alpine as frontend
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY ./frontend /app
WORKDIR /app
FROM frontend AS frontend-prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
FROM frontend AS frontend-build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
ENV BODY_SIZE_LIMIT=0
RUN pnpm run build
# Base container
FROM python:3.11-slim as base
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get -qq update \
&& apt-get -qq install --no-install-recommends \
ffmpeg curl nodejs nginx supervisor \
&& rm -rf /var/lib/apt/lists/*
# Python service setup
COPY ./transcription-api /app/transcription
WORKDIR /app/transcription
RUN pip3 install -r requirements.txt
RUN pip3 install python-multipart
# Node.js service setup
ENV BODY_SIZE_LIMIT=0
COPY ./frontend /app/frontend
COPY --from=frontend-build /app/build /app/frontend
COPY --from=frontend-prod-deps /app/node_modules /app/frontend/node_modules
# Golang service setup
COPY --from=backend-builder /app/whishper /bin/whishper
RUN chmod a+rx /bin/whishper
COPY --from=ytdlp_cache /usr/local/bin/yt-dlp /bin/yt-dlp
# Nginx setup
COPY ./nginx.conf /etc/nginx/nginx.conf
# Set workdir and entrypoint
WORKDIR /app
RUN mkdir /app/uploads
# Cleanup to make the image smaller
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* ~/.cache /var/cache
COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ENTRYPOINT ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
# Expose ports for each service and Nginx
EXPOSE 8080 3000 5000 80

94
Dockerfile.gpu Normal file
View File

@@ -0,0 +1,94 @@
# YT-DLP Download and setup
FROM --platform=$BUILDPLATFORM golang:bookworm AS ytdlp_cache
ARG TARGETOS
ARG TARGETARCH
RUN apt update && apt install -y wget
RUN wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp
RUN chmod a+rx /usr/local/bin/yt-dlp
# Backend setup
FROM devopsworks/golang-upx:latest as backend-builder
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /app
COPY ./backend /app
RUN go mod tidy
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o whishper . && \
upx whishper
RUN chmod a+rx whishper
# Frontend setup
FROM node:alpine as frontend
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY ./frontend /app
WORKDIR /app
FROM frontend AS frontend-prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
FROM frontend AS frontend-build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
ENV BODY_SIZE_LIMIT=0
RUN pnpm run build
# Base container
FROM nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 as base
ENV PYTHON_VERSION=3.10
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get -qq update \
&& apt-get -qq install --no-install-recommends \
python${PYTHON_VERSION} \
python${PYTHON_VERSION}-venv \
python3-pip \
ffmpeg \
curl wget xz-utils \
ffmpeg nginx supervisor \
&& rm -rf /var/lib/apt/lists/*
RUN ln -s -f /usr/bin/python${PYTHON_VERSION} /usr/bin/python3 && \
ln -s -f /usr/bin/python${PYTHON_VERSION} /usr/bin/python && \
ln -s -f /usr/bin/pip3 /usr/bin/pip
# Python service setup
COPY ./transcription-api /app/transcription
WORKDIR /app/transcription
RUN pip install -r requirements.txt && \
pip install python-multipart && \
pip3 install torch --index-url https://download.pytorch.org/whl/cu118
# Node.js service setup
RUN wget https://nodejs.org/dist/v20.9.0/node-v20.9.0-linux-x64.tar.xz && \
tar -xf node-v20.9.0-linux-x64.tar.xz && \
mv node-v20.9.0-linux-x64 /usr/local/lib/node && \
rm node-v20.9.0-linux-x64.tar.xz
ENV PATH="/usr/local/lib/node/bin:${PATH}"
ENV BODY_SIZE_LIMIT=0
COPY ./frontend /app/frontend
COPY --from=frontend-build /app/build /app/frontend
COPY --from=frontend-prod-deps /app/node_modules /app/frontend/node_modules
# Golang service setup
COPY --from=backend-builder /app/whishper /bin/whishper
RUN chmod a+rx /bin/whishper
COPY --from=ytdlp_cache /usr/local/bin/yt-dlp /bin/yt-dlp
# Nginx setup
COPY ./nginx.conf /etc/nginx/nginx.conf
# Set workdir and entrypoint
WORKDIR /app
RUN mkdir /app/uploads
# Cleanup to make the image smaller
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* ~/.cache /var/cache
COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ENTRYPOINT ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
# Expose ports for each service and Nginx
EXPOSE 8080 3000 5000 80

View File

@@ -22,7 +22,6 @@ ARG TARGETARCH
WORKDIR /app WORKDIR /app
COPY --from=builder /app/whishper ./whishper COPY --from=builder /app/whishper ./whishper
RUN chmod a+rx ./whishper RUN chmod a+rx ./whishper
COPY --from=ytdlp_cache /usr/local/bin/yt-dlp /bin/yt-dlp COPY --from=ytdlp_cache /usr/local/bin/yt-dlp /bin/yt-dlp
RUN mkdir /app/uploads RUN mkdir /app/uploads

View File

@@ -32,7 +32,8 @@ func NewMongoDb() *MongoDb {
} }
// Set auth method to PLAIN if using FerretDB // Set auth method to PLAIN if using FerretDB
if os.Getenv("FERRETDB_MONGO_URL") != "" { if os.Getenv("FERRETDB_ENABLED") != "" {
log.Printf("FerretDB enabled, setting auth mechanism to PLAIN...")
credentials.AuthMechanism = "PLAIN" credentials.AuthMechanism = "PLAIN"
} }

View File

@@ -19,7 +19,7 @@ func main() {
listenAddr := flag.String("addr", ":8080", "server listen address") listenAddr := flag.String("addr", ":8080", "server listen address")
uploadDir := flag.String("updir", "/app/uploads", "upload directory") uploadDir := flag.String("updir", "/app/uploads", "upload directory")
asrEndpoint := flag.String("asr", "transcription-api:8000", "asr endpoint, i.e. localhost:9888") asrEndpoint := flag.String("asr", "127.0.0.1:8000", "asr endpoint, i.e. localhost:9888")
dbHost := flag.String("db", "mongo:27017", "database endpoint host, i.e. localhost:27017") dbHost := flag.String("db", "mongo:27017", "database endpoint host, i.e. localhost:27017")
dbUser := flag.String("dbuser", "root", "database user") dbUser := flag.String("dbuser", "root", "database user")
dbPass := flag.String("dbpass", "example", "database password") dbPass := flag.String("dbpass", "example", "database password")

View File

@@ -1,33 +1,14 @@
version: '3.9' version: '3.9'
services: services:
transcription-api-gpu: translate-cpu:
build:
context: ./transcription-api
dockerfile: Dockerfile.gpu
ports: ports:
- 8000:8000 - 5000:5000
transcription-api-cpu: translate-gpu:
build:
context: ./transcription-api
dockerfile: Dockerfile
ports:
- 8000:8000
translate:
ports: ports:
- 5000:5000 - 5000:5000
mongo: mongo:
ports: ports:
- 27017:27017 - 27017:27017
#whishper-backend:
# build: ./backend
# ports:
# - 8080:8080
#whishper-frontend:
# build:
# context: ./frontend

View File

@@ -15,160 +15,14 @@ services:
mongo: mongo:
image: ghcr.io/ferretdb/ferretdb image: ghcr.io/ferretdb/ferretdb
restart: on-failure restart: on-failure
ports: expose:
- 27017:27017 - 27017
environment:
- FERRETDB_POSTGRESQL_URL=postgres://postgres:5432/whishper
translate-cpu:
container_name: whisper-libretranslate
profiles: ["cpu"]
image: libretranslate/libretranslate:latest
restart: unless-stopped
volumes:
- ./whishper_data/libretranslate/data:/home/libretranslate/.local/share
- ./whishper_data/libretranslate/cache:/home/libretranslate/.local/cache
env_file: env_file:
- .env - .env
tty: true
environment: environment:
LT_DISABLE_WEB_UI: True - FERRETDB_POSTGRESQL_URL=postgres://${DB_USER:-whishper}:${DB_PASS:-whishper}@postgres:5432/whishper
#LT_UPDATE_MODELS: True command: ["--telemetry=disable"]
expose:
- 5000
networks:
default:
aliases:
- translate
healthcheck:
test: ['CMD-SHELL', './venv/bin/python scripts/healthcheck.py']
interval: 2s
timeout: 3s
retries: 5
translate-gpu: whishper:
container_name: whisper-libretranslate
image: libretranslate/libretranslate:latest-cuda
profiles: ["gpu"]
restart: unless-stopped
volumes:
- ./whishper_data/libretranslate/data:/home/libretranslate/.local/share
- ./whishper_data/libretranslate/cache:/home/libretranslate/.local/cache
env_file:
- .env
user: root
tty: true
environment: environment:
LT_DISABLE_WEB_UI: True FERRETDB_ENABLED: "true"
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,fr,es}
#LT_UPDATE_MODELS: True
expose:
- 5000
networks:
default:
aliases:
- translate
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
healthcheck:
test: ['CMD-SHELL', './venv/bin/python scripts/healthcheck.py']
interval: 2s
timeout: 3s
retries: 5
transcription-api-cpu:
container_name: whisper-api
profiles: ["cpu"]
image: pluja/whishper-transcription-api:latest
env_file:
- .env
volumes:
- ./whishper_data/whisper_models:/app/models
- ./whishper_data/uploads:/app/uploads
environment:
- WHISPER_MODELS_DIR=/app/models
- UPLOAD_DIR=/app/uploads
networks:
default:
aliases:
- transcription-api
restart: unless-stopped
expose:
- 8000
transcription-api-gpu:
container_name: whisper-api
profiles: ["gpu"]
image: pluja/whishper-transcription-api:latest-gpu
env_file:
- .env
volumes:
- ./whishper_data/whisper_models:/app/models
- ./whishper_data/uploads:/app/uploads
environment:
WHISPER_MODELS_DIR: /app/models
UPLOAD_DIR: /app/uploads
restart: unless-stopped
expose:
- 8000
networks:
default:
aliases:
- transcription-api
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
whishper-backend:
container_name: whishper-backend
image: pluja/whishper-backend:latest
env_file:
- .env
volumes:
- ./whishper_data/uploads:/app/uploads
restart: unless-stopped
depends_on:
mongo:
condition: service_healthy
healthcheck:
test: curl --fail http://localhost:8080/api/transcriptions || exit 1
interval: 2s
timeout: 2s
retries: 5
expose:
- 8080
whishper-frontend:
container_name: whishper-web
image: pluja/whishper-frontend:latest
env_file:
- .env
restart: unless-stopped
environment:
PUBLIC_INTERNAL_API_HOST: "http://nginx:80"
PUBLIC_TRANSLATION_API_HOST: ""
PUBLIC_API_HOST: ${WHISHPER_HOST:-}
PUBLIC_WHISHPER_PROFILE: ${COMPOSE_PROFILES:-false}
expose:
- 3000
nginx:
image: nginx:1
restart: unless-stopped
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./whishper_data/uploads:/app/uploads
depends_on:
whishper-backend:
condition: service_healthy
ports:
- 8082:80

80
docker-compose.gpu.yml Normal file
View File

@@ -0,0 +1,80 @@
version: "3.9"
services:
mongo:
image: mongo
env_file:
- .env
restart: unless-stopped
volumes:
- ./whishper_data/db_data:/data/db
- ./whishper_data/db_data/logs/:/var/log/mongodb/
environment:
MONGO_INITDB_ROOT_USERNAME: ${DB_USER:-whishper}
MONGO_INITDB_ROOT_PASSWORD: ${DB_PASS:-whishper}
expose:
- 27017
command: ['--logpath', '/var/log/mongodb/mongod.log']
translate:
container_name: whisper-libretranslate
image: libretranslate/libretranslate:latest-cuda
restart: unless-stopped
volumes:
- ./whishper_data/libretranslate/data:/home/libretranslate/.local/share
- ./whishper_data/libretranslate/cache:/home/libretranslate/.local/cache
env_file:
- .env
user: root
tty: true
environment:
LT_DISABLE_WEB_UI: True
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,fr,es}
LT_UPDATE_MODELS: True
expose:
- 5000
networks:
default:
aliases:
- translate
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
whishper:
pull_policy: always
image: pluja/whishper:${WHISHPER_VERSION:-latest-gpu}
env_file:
- .env
volumes:
- ./whishper_data/uploads:/app/uploads
- ./whishper_data/logs:/var/log/whishper
container_name: whishper
restart: unless-stopped
networks:
default:
aliases:
- whishper
ports:
- 8082:80
depends_on:
- mongo
- translate
environment:
PUBLIC_INTERNAL_API_HOST: "http://127.0.0.1:80"
PUBLIC_TRANSLATION_API_HOST: ""
PUBLIC_API_HOST: ${WHISHPER_HOST:-}
PUBLIC_WHISHPER_PROFILE: gpu
WHISPER_MODELS_DIR: /app/models
UPLOAD_DIR: /app/uploads
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]

View File

@@ -15,15 +15,9 @@ services:
expose: expose:
- 27017 - 27017
command: ['--logpath', '/var/log/mongodb/mongod.log'] command: ['--logpath', '/var/log/mongodb/mongod.log']
healthcheck:
test: mongosh --eval 'db.runCommand("ping").ok' --quiet
interval: 2s
timeout: 3s
retries: 5
translate-cpu: translate:
container_name: whisper-libretranslate container_name: whisper-libretranslate
profiles: ["cpu"]
image: libretranslate/libretranslate:latest image: libretranslate/libretranslate:latest
restart: unless-stopped restart: unless-stopped
volumes: volumes:
@@ -34,7 +28,7 @@ services:
tty: true tty: true
environment: environment:
LT_DISABLE_WEB_UI: True LT_DISABLE_WEB_UI: True
#LT_UPDATE_MODELS: True LT_UPDATE_MODELS: True
expose: expose:
- 5000 - 5000
networks: networks:
@@ -47,129 +41,29 @@ services:
timeout: 3s timeout: 3s
retries: 5 retries: 5
translate-gpu: whishper:
container_name: whisper-libretranslate pull_policy: always
image: libretranslate/libretranslate:latest-cuda image: pluja/whishper:${WHISHPER_VERSION:-latest}
profiles: ["gpu"]
restart: unless-stopped
volumes:
- ./whishper_data/libretranslate/data:/home/libretranslate/.local/share
- ./whishper_data/libretranslate/cache:/home/libretranslate/.local/cache
env_file: env_file:
- .env - .env
user: root volumes:
tty: true - ./whishper_data/uploads:/app/uploads
environment: - ./whishper_data/logs:/var/log/whishper
LT_DISABLE_WEB_UI: True container_name: whishper
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,fr,es} restart: unless-stopped
#LT_UPDATE_MODELS: True
expose:
- 5000
networks: networks:
default: default:
aliases: aliases:
- translate - whishper
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
healthcheck:
test: ['CMD-SHELL', './venv/bin/python scripts/healthcheck.py']
interval: 2s
timeout: 3s
retries: 5
transcription-api-cpu:
container_name: whisper-api
profiles: ["cpu"]
image: pluja/whishper-transcription-api:latest
env_file:
- .env
volumes:
- ./whishper_data/whisper_models:/app/models
- ./whishper_data/uploads:/app/uploads
environment:
- WHISPER_MODELS_DIR=/app/models
- UPLOAD_DIR=/app/uploads
networks:
default:
aliases:
- transcription-api
restart: unless-stopped
expose:
- 8000
transcription-api-gpu:
container_name: whisper-api
profiles: ["gpu"]
image: pluja/whishper-transcription-api:latest-gpu
env_file:
- .env
volumes:
- ./whishper_data/whisper_models:/app/models
- ./whishper_data/uploads:/app/uploads
environment:
WHISPER_MODELS_DIR: /app/models
UPLOAD_DIR: /app/uploads
restart: unless-stopped
expose:
- 8000
networks:
default:
aliases:
- transcription-api
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
whishper-backend:
container_name: whishper-backend
image: pluja/whishper-backend:latest
env_file:
- .env
volumes:
- ./whishper_data/uploads:/app/uploads
restart: unless-stopped
depends_on:
mongo:
condition: service_healthy
healthcheck:
test: curl --fail http://localhost:8080/api/transcriptions || exit 1
interval: 2s
timeout: 2s
retries: 5
expose:
- 8080
whishper-frontend:
container_name: whishper-web
image: pluja/whishper-frontend:latest
env_file:
- .env
restart: unless-stopped
environment:
PUBLIC_INTERNAL_API_HOST: "http://nginx:80"
PUBLIC_TRANSLATION_API_HOST: ""
PUBLIC_API_HOST: ${WHISHPER_HOST:-}
PUBLIC_WHISHPER_PROFILE: ${COMPOSE_PROFILES:-false}
expose:
- 3000
nginx:
image: nginx:1
restart: unless-stopped
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./whishper_data/uploads:/app/uploads
depends_on:
whishper-backend:
condition: service_healthy
ports: ports:
- 8082:80 - 8082:80
depends_on:
- mongo
- translate
environment:
PUBLIC_INTERNAL_API_HOST: "http://127.0.0.1:80"
PUBLIC_TRANSLATION_API_HOST: ""
PUBLIC_API_HOST: ${WHISHPER_HOST:-}
PUBLIC_WHISHPER_PROFILE: cpu
WHISPER_MODELS_DIR: /app/models
UPLOAD_DIR: /app/uploads

View File

@@ -18,18 +18,18 @@ http {
location /api { location /api {
client_max_body_size 0; client_max_body_size 0;
proxy_pass http://whishper-backend:8080; proxy_pass http://127.0.0.1:8080;
} }
location /ws { location /ws {
proxy_pass http://whishper-backend:8080; proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
} }
location / { location / {
proxy_pass http://whishper-frontend:3000; proxy_pass http://127.0.0.1:3000;
} }
} }
} }

29
supervisord.conf Normal file
View File

@@ -0,0 +1,29 @@
[supervisord]
nodaemon=true
[program:transcription]
command=python3 /app/transcription/main.py
directory=/app/transcription
autorestart=true
stderr_logfile=/var/log/whishper/transcription.err.log
stdout_logfile=/var/log/whishper/transcription.out.log
[program:frontend]
command=node /app/frontend/index.js
directory=/app/frontend
autorestart=true
stderr_logfile=/var/log/whishper/frontend.err.log
stdout_logfile=/var/log/whishper/frontend.out.log
[program:backend]
command=/bin/whishper -addr :8080
directory=/app/
autorestart=true
stderr_logfile=/var/log/whishper/backend.err.log
stdout_logfile=/var/log/whishper/backend.out.log
[program:nginx]
command=nginx -g 'daemon off;'
autorestart=true
stderr_logfile=/var/log/whishper/nginx.err.log
stdout_logfile=/var/log/whishper/nginx.out.log