Skip to content

Adds support for Linux Docker. - #1

Open
MicahZoltu wants to merge 1 commit into
ventura8:mainfrom
MicahZoltu:main
Open

Adds support for Linux Docker.#1
MicahZoltu wants to merge 1 commit into
ventura8:mainfrom
MicahZoltu:main

Conversation

@MicahZoltu

@MicahZoltu MicahZoltu commented May 6, 2026

Copy link
Copy Markdown

The change in transcription.py is a bugfix that makes it work when the file is moving across volumes (disks). os.rename only works if the source/destination are on the same logical volume.

Pinned versions in requirements.txt were required to get this all working reliably, and is generally a good practice for reproducible builds and minimizing chance that something breaks suddenly. I spent about 2 days figuring out how to get this all working with the right version of things and I wouldn't want others to waste a similar amount of time.

The main addition is the Dockerfile, which works for amd64. It is ridiculously large, given how simple this project is and it doesn't even include any actual models, but that is pytorch and cuda for you.

It has to patch requirements.txt because faster-whisper will bring in the wrong version of onnx, so we have to manually install it and its dependencies.

It also has to patch modules/models.py because the codebase is built for a newer version of pytorch than I was able to get working. I would be happy to move this change into the main repository, but I wanted to minimize the chance that the PR broke something in other environments.

@ventura8

Copy link
Copy Markdown
Owner

Please update this pr

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: bb580be2-4dc4-4948-9a01-f57f393b18ea

📝 Summary

Summary by CodeRabbit

  • New Features

    • Added a reproducible GPU-enabled Docker environment for running the application with CUDA acceleration and audio-processing support.
    • Docker builds now include only the files required for deployment, reducing build context size.
  • Bug Fixes

    • Improved handling of separated audio tracks so files can be moved reliably across different storage locations.
  • Tests

    • Docker image builds now validate the application with automated tests.

Walkthrough

Adds a reproducible CUDA 12.9.1 GPU Docker image with pinned dependencies, build-context exclusions, test execution, Linux runtime configuration, and a cross-platform separator output move operation.

Changes

Container runtime and portability

Layer / File(s) Summary
GPU image and dependencies
.dockerignore, Dockerfile
The Docker build uses a CUDA 12.9.1 cuDNN base, pinned system and Python dependencies, and excludes non-runtime project files from the build context.
Application wiring and Linux runtime patch
Dockerfile
The image copies application and test assets, runs pytest with one Windows-only test excluded, disables an upstream Windows/CUDA-13 probe, and configures NVIDIA runtime variables and the entrypoint.
Portable separator output movement
modules/transcription.py
Separator output files are moved with shutil.move instead of os.rename.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

I’m a rabbit hopping through the build,
CUDA clouds above the field.
Pinned packages, tests in flight,
Tracks move safely left and right.
Container carrots packed just right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding Linux Docker support.
Description check ✅ Passed The description directly discusses the Dockerfile, file-move fix, and dependency pinning in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@MicahZoltu

Copy link
Copy Markdown
Author

Updated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
Dockerfile (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the Docker BuildKit syntax directive.

The Dockerfile uses the heredoc syntax (RUN <<EOF), which is a BuildKit feature introduced in Dockerfile 1.4. While newer Docker versions default to BuildKit, explicitly declaring the syntax directive ensures compatibility across all build clients and resolves linting errors (like the Hadolint parsing error on line 64).

🛠️ Proposed fix
+# syntax=docker/dockerfile:1
 # =============================================================================
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Dockerfile` at line 1, Add the Dockerfile BuildKit syntax directive for
Dockerfile version 1.4 or newer before all existing content, so the heredoc RUN
instructions parse correctly across build clients.

Source: Linters/SAST tools

.dockerignore (1)

4-4: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Ignore virtual environment directories to optimize build context.

It's highly recommended to add virtual environment directories (like venv/ and .venv/) to .dockerignore. If a local virtual environment exists, it will be copied into the Docker build context, which can drastically slow down the build process and bloat the build context size.

🚀 Proposed fix
 __pycache__
+venv/
+.venv/
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.dockerignore at line 4, Add virtual environment directory patterns such as
venv/ and .venv/ to .dockerignore alongside __pycache__, ensuring local Python
environments are excluded from the Docker build context.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Dockerfile`:
- Around line 64-80: Update the Dockerfile test stage to install pytest and
pytest-cov only for the test command, then remove the test dependencies and
assets after pytest completes. Combine test execution and cleanup in one RUN
instruction, removing pytest.ini and tests/ so the final image retains only
production files and dependencies.

In `@modules/transcription.py`:
- Line 49: Update the test covering the move operation in
test_transcription_behavior.py to patch modules.transcription.shutil.move
instead of os.rename, and assert that the mocked call receives the expected
destination path.
- Around line 47-49: Update the replacement flow around shutil.move in the
transcription output handling to preserve the existing dst_path until the new
file is fully staged. Copy or move src_path into a temporary path within
target_dir, then atomically install it with os.replace() only after staging
succeeds; remove the preemptive os.remove(dst_path) and retain the existing
output if staging fails.

---

Nitpick comments:
In @.dockerignore:
- Line 4: Add virtual environment directory patterns such as venv/ and .venv/ to
.dockerignore alongside __pycache__, ensuring local Python environments are
excluded from the Docker build context.

In `@Dockerfile`:
- Line 1: Add the Dockerfile BuildKit syntax directive for Dockerfile version
1.4 or newer before all existing content, so the heredoc RUN instructions parse
correctly across build clients.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4dd3f6db-19cc-47ea-a42e-82b0e2e7fd00

📥 Commits

Reviewing files that changed from the base of the PR and between 1760e9f and 2ff1173.

📒 Files selected for processing (3)
  • .dockerignore
  • Dockerfile
  • modules/transcription.py
📜 Review details
🧰 Additional context used
🪛 Hadolint (2.14.0)
Dockerfile

[error] 64-64: unexpected 'R'
expecting a new line followed by the next instruction

(DL1000)

🪛 Trivy (0.69.3)
Dockerfile

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)

🔇 Additional comments (2)
Dockerfile (1)

70-71: 🎯 Functional Correctness

The sed replacement is safe here — all dtype=dtype, occurrences in modules/models.py are from_pretrained(...) arguments, so this change doesn’t affect unrelated variables.

			> Likely an incorrect or invalid review comment.
modules/transcription.py (1)

6-6: LGTM!

Comment thread Dockerfile
Comment thread modules/transcription.py Outdated
Comment on lines +47 to +49
if os.path.exists(dst_path):
os.remove(dst_path)
os.rename(src_path, dst_path)
shutil.move(src_path, dst_path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' modules/transcription.py
printf '\n--- docs/instructions.md ---\n'
sed -n '1,120p' docs/instructions.md

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 7143


🏁 Script executed:

python3 - <<'PY'
import os, shutil, tempfile, pathlib

# Read-only probe of Python semantics: show that shutil.move falls back to copy+remove
# for cross-filesystem moves by monkeypatching os.rename and observing the fallback.
calls = []

orig_rename = os.rename
orig_copy2 = shutil.copy2
orig_rmtree = shutil.rmtree

def fake_rename(src, dst):
    calls.append(("rename", src, dst))
    raise OSError("cross-device link")

def fake_copy2(src, dst, *, follow_symlinks=True):
    calls.append(("copy2", src, dst))
    return dst

def fake_rmtree(path, *args, **kwargs):
    calls.append(("rmtree", path))
    return None

os.rename = fake_rename
shutil.copy2 = fake_copy2
shutil.rmtree = fake_rmtree

with tempfile.TemporaryDirectory() as td:
    src = pathlib.Path(td) / "src.txt"
    dst = pathlib.Path(td) / "dst.txt"
    src.write_text("hello")
    try:
        shutil.move(str(src), str(dst))
    except Exception as e:
        calls.append(("exception", type(e).__name__, str(e)))

print(calls)
PY

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 239


🏁 Script executed:

rg -n "atomic|separator output|shutil.move|transcription" -S docs modules

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 2524


🏁 Script executed:

sed -n '1,120p' modules/transcription.py

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 4091


🏁 Script executed:

python3 - <<'PY'
import inspect, shutil
print(inspect.getsource(shutil.move))
PY

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 2867


🏁 Script executed:

python3 - <<'PY'
import os, shutil, tempfile, pathlib, inspect

print("shutil.move source:")
print(inspect.getsource(shutil.move))

print("\n--- behavior probe ---")
calls = []

orig_rename = os.rename
orig_copy2 = shutil.copy2
orig_copytree = shutil.copytree
orig_rmtree = shutil.rmtree

def fake_rename(src, dst):
    calls.append(("rename", os.path.basename(src), os.path.basename(dst)))
    raise OSError(18, "Invalid cross-device link")

def fake_copy2(src, dst, *, follow_symlinks=True):
    calls.append(("copy2", os.path.basename(src), os.path.basename(dst)))
    # emulate successful overwrite
    pathlib.Path(dst).write_text("new")
    return dst

os.rename = fake_rename
shutil.copy2 = fake_copy2

with tempfile.TemporaryDirectory() as td:
    td = pathlib.Path(td)
    src = td / "src.txt"
    dst = td / "dst.txt"
    src.write_text("source")
    dst.write_text("existing")
    try:
        result = shutil.move(str(src), str(dst))
        calls.append(("result", os.path.basename(result)))
    except Exception as e:
        calls.append(("exception", type(e).__name__, str(e)))
    print(calls)
    print("dst content:", dst.read_text() if dst.exists() else "<missing>")
    print("src exists:", src.exists())

os.rename = orig_rename
shutil.copy2 = orig_copy2
shutil.copytree = orig_copytree
shutil.rmtree = orig_rmtree
PY

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 3007


🏁 Script executed:

python3 - <<'PY'
import os, shutil, tempfile, pathlib, inspect

print("shutil.move source:")
print(inspect.getsource(shutil.move))

print("\n--- behavior probe ---")
calls = []

orig_rename = os.rename
orig_copy2 = shutil.copy2

def fake_rename(src, dst):
    calls.append(("rename", os.path.basename(src), os.path.basename(dst)))
    raise OSError(18, "Invalid cross-device link")

def fake_copy2(src, dst, *, follow_symlinks=True):
    calls.append(("copy2", os.path.basename(src), os.path.basename(dst)))
    pathlib.Path(dst).write_text("new")
    return dst

os.rename = fake_rename
shutil.copy2 = fake_copy2

with tempfile.TemporaryDirectory() as td:
    td = pathlib.Path(td)
    src = td / "src.txt"
    dst = td / "dst.txt"
    src.write_text("source")
    dst.write_text("existing")
    try:
        result = shutil.move(str(src), str(dst))
        calls.append(("result", os.path.basename(result)))
    except Exception as e:
        calls.append(("exception", type(e).__name__, str(e)))
    print(calls)
    print("dst content:", dst.read_text() if dst.exists() else "<missing>")
    print("src exists:", src.exists())

os.rename = orig_rename
shutil.copy2 = orig_copy2
PY

Repository: ventura8/Auto-Subtitle-Generator

Length of output: 3007


Keep the existing output until replacement succeeds. In modules/transcription.py:47-49, shutil.move() can fall back to copy+delete on cross-volume moves; deleting dst_path first can discard the last valid separator output if the copy is interrupted. Stage the file in target_dir and os.replace() it into place instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/transcription.py` around lines 47 - 49, Update the replacement flow
around shutil.move in the transcription output handling to preserve the existing
dst_path until the new file is fully staged. Copy or move src_path into a
temporary path within target_dir, then atomically install it with os.replace()
only after staging succeeds; remove the preemptive os.remove(dst_path) and
retain the existing output if staging fails.

Comment thread modules/transcription.py Outdated
if os.path.exists(dst_path):
os.remove(dst_path)
os.rename(src_path, dst_path)
shutil.move(src_path, dst_path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update the test to patch shutil.move.

tests/test_transcription_behavior.py:96-106 still patches os.rename; after this change, the real shutil.move runs against the test’s fake paths and can raise FileNotFoundError. Patch modules.transcription.shutil.move and assert the expected destination.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/transcription.py` at line 49, Update the test covering the move
operation in test_transcription_behavior.py to patch
modules.transcription.shutil.move instead of os.rename, and assert that the
mocked call receives the expected destination path.

@ventura8 ventura8 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please resolve pr comments

@MicahZoltu

Copy link
Copy Markdown
Author

I rebased and had my agent address the comments, but I won't be able to test the docker build for a couple weeks. I'll set a reminder to myself to do this when I can, but I didn't want you to think I had abandoned this PR.

@ventura8
ventura8 force-pushed the main branch 4 times, most recently from e8c7d8d to df902fe Compare September 1, 2026 07:07
The change in `transcription.py` makes it work when the file is moving across volumes (disks).  `os.rename` only works if the source/destination are on the same volume.

Pinned versions in `requirements.txt` were required to get this all working reliably, and is generally a good practice for reproducible builds and minimizing chance that something breaks suddenly.  I spent about 2 days figuring out how to get this all working with the right version of things and I wouldn't want others to waste a similar amount of time.

The main addition is the `Dockerfile`, which works for `amd64`.  It is ridiculously large, given how simple its job is and that it doesn't include any actual models, but that is pytorch and cuda for you.

It has to patch `requirements.txt` because faster-whisper will bring in the wrong version of onnx, so we have to manually install it and its unfullfilled dependencies.

It also has to patch `modules/models.py` because the codebase switched to a newer version of pytorch it seems.  I would be happy to move this change into the main repository, but I wanted to keep this PR as simple as possible.
@MicahZoltu

MicahZoltu commented Sep 6, 2026

Copy link
Copy Markdown
Author

Rebased against latest main and verified that the docker build is working correctly (had to disable e2e tests, since docker build environment doesn't have access to models/GPU).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants