feat: add basic production Dockerfiles

closes #8
This commit is contained in:
Felix Spöttel
2023-02-28 20:22:58 +01:00
parent 4eed77bfa7
commit 74879df442
9 changed files with 140 additions and 20 deletions

View File

@@ -1,9 +1,9 @@
clean:
docker-compose -f docker/dev/docker-compose.yml down --volumes --remove-orphans
docker compose -f docker/dev/docker-compose.yml down --volumes --remove-orphans
dev:
docker-compose -f docker/dev/docker-compose.yml build --progress tty
docker-compose -f docker/dev/docker-compose.yml up --remove-orphans
docker compose -f docker/dev/docker-compose.yml build
docker compose -f docker/dev/docker-compose.yml up --remove-orphans
fmt:
black app
@@ -17,5 +17,5 @@ test:
pytest
run:
docker-compose -f docker/prod/docker-compose.yml build --progress tty
docker-compose -f docker/prod/docker-compose.yml up --remove-orphans
docker compose -f docker/prod/docker-compose.yml build
docker compose -f docker/prod/docker-compose.yml up --remove-orphans

View File

@@ -1,6 +1,5 @@
from typing import Any, Generator
from sqlalchemy.engine import Connection
from sqlalchemy import create_engine, event
from sqlalchemy.orm import Session, sessionmaker
@@ -10,7 +9,7 @@ engine = create_engine(settings.DATABASE_URI, connect_args={"check_same_thread":
@event.listens_for(engine, "connect")
def set_sqlite_pragma(conn: Connection, _: Any) -> None:
def set_sqlite_pragma(conn: Any, _: Any) -> None:
cursor = conn.cursor()
cursor.execute("PRAGMA journal_mode=WAL")
cursor.close()

View File

@@ -1,13 +1,11 @@
FROM python:3.10 AS compile-image
FROM python:3.10
WORKDIR /code
ENV PYTHONIOENCODING=utf-8
ENV PATH=/root/.local/bin:$PATH
COPY pyproject.toml .
RUN pip install --no-cache-dir --user .[web]
ENV PYTHONIOENCODING=utf-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PATH=/root/.local/bin:$PATH
CMD alembic upgrade head && uvicorn app.web.main:app --reload --host ${HOST:-0.0.0.0} --port ${PORT:-80} --log-level info

View File

@@ -1,9 +1,12 @@
FROM python:3.10 AS compile-image
FROM python:3.10
ARG WHISPER_MODEL
WORKDIR /code
ENV PYTHONIOENCODING=utf-8
ENV PATH=/root/.local/bin:$PATH
COPY --from=mwader/static-ffmpeg:5.1.2 /ffmpeg /usr/local/bin/
COPY --from=mwader/static-ffmpeg:5.1.2 /ffprobe /usr/local/bin/
@@ -13,9 +16,4 @@ RUN pip install --no-cache-dir --user .[worker,worker_dev]
COPY scripts/download_model.py .
RUN chmod +x download_model.py && python download_model.py ${WHISPER_MODEL}
ENV PYTHONIOENCODING=utf-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PATH=/root/.local/bin:$PATH
ENTRYPOINT ["watchmedo", "auto-restart", "-d" , "app/worker", "-p", "*.py", "--recursive", "celery", "--", "--app=app.worker.main.celery", "worker", "--loglevel=info", "--concurrency=1"]

2
docker/prod/.env.example Normal file
View File

@@ -0,0 +1,2 @@
API_SECRET="change_me"
WHISPER_MODEL="small"

View File

@@ -0,0 +1,69 @@
version: "3.8"
x-app-variables: &app-variables
DATABASE_URI: sqlite:////etc/whisperbox/data/whisperbox.sqlite
ENVIRONMENT: production
BROKER_URL: redis://redis:6379/0
services:
redis:
container_name: whisperbox_redis
image: redis:7-alpine
ports:
- 6379:6379
networks:
- app
deploy:
resources:
limits:
memory: 128M
worker:
container_name: whisperbox_worker
build:
context: ../../
# ENABLE GPU SUPPORT
# dockerfile: docker/prod/worker.gpu.Dockerfile
dockerfile: docker/prod/worker.Dockerfile
environment: *app-variables
env_file: .env
volumes:
- whisperbox-data:/etc/whisperbox/data
networks:
- app
depends_on:
- redis
# ENABLE GPU SUPPORT
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# TODO: reverse proxy
web:
container_name: whisperbox_web
build:
context: ../../
dockerfile: docker/prod/web.Dockerfile
environment: *app-variables
env_file: .env
ports:
- "8000:8000"
networks:
- app
depends_on:
- worker
volumes:
- whisperbox-data:/etc/whisperbox/data
- whisper-models:/models
volumes:
whisperbox-data:
whisper-models:
networks:
app:
driver: bridge

View File

@@ -0,0 +1,23 @@
FROM python:3.10 as python-build
WORKDIR /etc/whisperbox
COPY pyproject.toml .
RUN python -m venv /opt/venv && \
/opt/venv/bin/pip install -U pip wheel && \
/opt/venv/bin/pip install -U .[web]
FROM python:3.10 as python-deploy
WORKDIR /etc/whisperbox
COPY --from=python-build /opt/venv /opt/venv
COPY app ./app
COPY alembic.ini ./
ENV VIRTUAL_ENV /opt/venv
ENV PATH /opt/venv/bin:$PATH
CMD alembic upgrade head && gunicorn -k uvicorn.workers.UvicornWorker app.web.main:app --bind ${HOST:-0.0.0.0}:${PORT:-8000} --log-level info

View File

@@ -0,0 +1,30 @@
FROM python:3.10 AS python-build
WORKDIR /etc/whisperbox
COPY pyproject.toml .
RUN python -m venv /opt/venv && \
/opt/venv/bin/pip install -U pip wheel && \
/opt/venv/bin/pip install -U .[worker]
FROM python:3.10 as python-deploy
ARG WHISPER_MODEL
WORKDIR /etc/whisperbox
COPY --from=python-build /opt/venv /opt/venv
COPY --from=mwader/static-ffmpeg:latest /ffmpeg /usr/local/bin/
COPY --from=mwader/static-ffmpeg:latest /ffprobe /usr/local/bin/
COPY app ./app
ENV VIRTUAL_ENV /opt/venv
ENV PATH /opt/venv/bin:$PATH
# COPY scripts/download_model.py .
# RUN chmod +x download_model.py && python download_model.py ${WHISPER_MODEL:-small}
CMD celery --app=app.worker.main.celery worker --loglevel=info --concurrency=1

View File

@@ -13,7 +13,8 @@ dependencies=[
web=[
"alembic ==1.9.3",
"fastapi ==0.90.0",
"uvicorn[standard] ==0.20.0"
"uvicorn[standard] ==0.20.0",
"gunicorn ==20.1.0"
]
worker=[