Skip to content

initial dockerfile in the test directory -- we can use this to finalize a test container#1372

Merged
aliasaria merged 3 commits intomainfrom
add/test-quick
Feb 24, 2026
Merged

initial dockerfile in the test directory -- we can use this to finalize a test container#1372
aliasaria merged 3 commits intomainfrom
add/test-quick

Conversation

@aliasaria
Copy link
Copy Markdown
Member

@aliasaria aliasaria commented Feb 20, 2026

Summary by CodeRabbit

  • Chores
    • Added containerization support combining frontend and backend into a single deployable image with documented build/run steps.
    • Improved build performance and privacy by excluding unnecessary and sensitive files from build context.
    • Configured the container to generate required runtime secrets and expose the application on the default service port.

@paragon-review
Copy link
Copy Markdown

Paragon Review Skipped

Hi @aliasaria! Your Polarity credit balance is insufficient to complete this review.

Please visit https://home.polarity.cc to add more credits and continue using Paragon reviews.

@aliasaria aliasaria marked this pull request as draft February 20, 2026 17:49
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 20, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a46acfe and 903bc19.

📒 Files selected for processing (1)
  • test/Dockerfile

📝 Walkthrough

Walkthrough

Adds Docker build assets: a .dockerignore that excludes build/artifact and sensitive files, and a new two-stage test/Dockerfile that builds the frontend (Node) then the backend (Python) and packages both into one runtime image.

Changes

Cohort / File(s) Summary
Dockerignore
/.dockerignore
Adds ignores for node_modules, dist, release/..., api/venv, api/transformerlab/db/llmlab.sqlite3, .git, .env, .vscode, and *.log to shrink build context and omit sensitive/artifact files.
Two-stage Dockerfile
test/Dockerfile
Introduces a multi-stage Dockerfile: Stage 1 builds frontend with Node (produces release/cloud), Stage 2 builds Python backend (Python 3.11-slim), installs system and Python deps, installs lab-sdk and api, generates JWT secrets, copies frontend build into static webapp, sets env vars, exposes port 8338 and runs uvicorn api:app.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as "Developer"
  participant Docker as "Docker Build"
  participant Node as "Node Builder"
  participant Python as "Python Builder"
  participant Image as "Final Image"
  participant Container as "Running Container (uvicorn)"

  Dev->>Docker: docker build -f test/Dockerfile
  Docker->>Node: Stage 1 - install deps, build frontend (release/cloud)
  Node-->>Docker: frontend artifacts
  Docker->>Python: Stage 2 - install system deps, pip install lab-sdk & api, generate secrets
  Python-->>Docker: backend image + embedded frontend
  Docker->>Image: assemble final image (port 8338)
  Image->>Container: run (uvicorn api:app on 0.0.0.0:8338)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰
In burrows of code I softly tread,
I stash the crumbs the builds don't need,
Two-stage hops — frontend then backend fed,
Secrets tucked where roots won't read,
A tiny image, snug and speedy. 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding an initial Dockerfile in the test directory for finalizing a test container, which aligns with the primary changeset addition of test/Dockerfile.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add/test-quick

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/Dockerfile`:
- Line 29: The RUN command in the Dockerfile installs extra recommended packages
increasing image size; update the RUN line that calls apt-get install (the
command installing curl git build-essential) to include --no-install-recommends
so apt doesn't pull unnecessary packages, keep the apt-get update && apt-get
install -y ... && rm -rf /var/lib/apt/lists/* structure, and ensure the flag is
applied to the apt-get install invocation to reduce image bloat.
- Around line 46-64: Don't generate JWT secrets at image build or run the app as
root; move the two secret-generating RUN echo lines out of the Dockerfile and
instead read TRANSFORMERLAB_JWT_SECRET and TRANSFORMERLAB_REFRESH_SECRET from
environment at container start (or create them in an entrypoint script) so they
are not baked into image layers, and stop hardcoding TFL_HOME_DIR to
/root/.transformerlab; create a non-root user (e.g., transformerlab), mkdir and
chown a non-root home (e.g., /home/transformerlab) and set ENV TFL_HOME_DIR
accordingly, then switch to that user with USER before the CMD; update any
references to the build-time RUN that created /root/.transformerlab, ENV
TFL_HOME_DIR and the CMD ["uvicorn", "api:app", ...] so the app runs as the
non-root user and secrets come from runtime env or an entrypoint script.

Comment thread test/Dockerfile Outdated
Comment thread test/Dockerfile
Comment on lines +46 to +64
# Generate JWT secrets for the API
RUN mkdir -p /root/.transformerlab && \
echo "TRANSFORMERLAB_JWT_SECRET=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" > /root/.transformerlab/.env && \
echo "TRANSFORMERLAB_REFRESH_SECRET=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" >> /root/.transformerlab/.env

# Copy built frontend from Stage 1 to the static files directory
# Based on api/transformerlab/shared/dirs.py, the default STATIC_FILES_DIR is ~/.transformerlab/webapp
RUN mkdir -p /root/.transformerlab/webapp
COPY --from=frontend-builder /app/release/cloud/ /root/.transformerlab/webapp/

# Set environment variables
ENV TFL_HOME_DIR=/root/.transformerlab
ENV PYTHONUNBUFFERED=1

EXPOSE 8338

# Run the API
# We run from the /app/api directory so that the 'transformerlab' subfolder is found
CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8338"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid baking JWT secrets and drop root privileges.

Secrets generated at build time are embedded in image layers and reused across all containers. The image also runs as root. Prefer generating secrets at container start (or injecting them via env) and running as a non-root user with a non-root TFL_HOME_DIR.

Proposed change
-# Generate JWT secrets for the API
-RUN mkdir -p /root/.transformerlab && \
-    echo "TRANSFORMERLAB_JWT_SECRET=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" > /root/.transformerlab/.env && \
-    echo "TRANSFORMERLAB_REFRESH_SECRET=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" >> /root/.transformerlab/.env
-
-# Copy built frontend from Stage 1 to the static files directory
-# Based on api/transformerlab/shared/dirs.py, the default STATIC_FILES_DIR is ~/.transformerlab/webapp
-RUN mkdir -p /root/.transformerlab/webapp
-COPY --from=frontend-builder /app/release/cloud/ /root/.transformerlab/webapp/
-
-# Set environment variables
-ENV TFL_HOME_DIR=/root/.transformerlab
-ENV PYTHONUNBUFFERED=1
+# Run as a non-root user
+RUN useradd -m -u 10001 app
+
+# Set environment variables
+ENV TFL_HOME_DIR=/home/app/.transformerlab
+ENV PYTHONUNBUFFERED=1
+
+# Copy built frontend from Stage 1 to the static files directory
+# Based on api/transformerlab/shared/dirs.py, the default STATIC_FILES_DIR is ~/.transformerlab/webapp
+RUN mkdir -p "$TFL_HOME_DIR/webapp" && chown -R app:app /app /home/app
+COPY --from=frontend-builder --chown=app:app /app/release/cloud/ "$TFL_HOME_DIR/webapp/"
+
+USER app
@@
-# Run the API
-# We run from the /app/api directory so that the 'transformerlab' subfolder is found
-CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8338"]
+# Run the API (generate secrets at container start if missing)
+# We run from the /app/api directory so that the 'transformerlab' subfolder is found
+CMD ["sh", "-c", "if [ ! -f \"$TFL_HOME_DIR/.env\" ]; then \
+  mkdir -p \"$TFL_HOME_DIR\"; \
+  echo \"TRANSFORMERLAB_JWT_SECRET=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')\" > \"$TFL_HOME_DIR/.env\"; \
+  echo \"TRANSFORMERLAB_REFRESH_SECRET=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')\" >> \"$TFL_HOME_DIR/.env\"; \
+fi; exec uvicorn api:app --host 0.0.0.0 --port 8338"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/Dockerfile` around lines 46 - 64, Don't generate JWT secrets at image
build or run the app as root; move the two secret-generating RUN echo lines out
of the Dockerfile and instead read TRANSFORMERLAB_JWT_SECRET and
TRANSFORMERLAB_REFRESH_SECRET from environment at container start (or create
them in an entrypoint script) so they are not baked into image layers, and stop
hardcoding TFL_HOME_DIR to /root/.transformerlab; create a non-root user (e.g.,
transformerlab), mkdir and chown a non-root home (e.g., /home/transformerlab)
and set ENV TFL_HOME_DIR accordingly, then switch to that user with USER before
the CMD; update any references to the build-time RUN that created
/root/.transformerlab, ENV TFL_HOME_DIR and the CMD ["uvicorn", "api:app", ...]
so the app runs as the non-root user and secrets come from runtime env or an
entrypoint script.

@aliasaria aliasaria marked this pull request as ready for review February 24, 2026 21:12
@aliasaria aliasaria merged commit 04e358c into main Feb 24, 2026
4 checks passed
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.

1 participant