initial dockerfile in the test directory -- we can use this to finalize a test container#1372
initial dockerfile in the test directory -- we can use this to finalize a test container#1372
Conversation
…ze building a docker image
|
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. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds Docker build assets: a Changes
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)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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.
| # 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"] |
There was a problem hiding this comment.
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.
Summary by CodeRabbit