Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions services/comfy/complete/dockerfile.comfy.cuda.complete
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
FROM core AS complete

# Set shell to bash with pipefail for safety
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Copy the extra requirements file
COPY --chown=comfy:comfy ./extra-requirements.txt ./

# Set shell to bash to support 'source'
SHELL ["/bin/bash", "-c"]

# Install additional python requirements
# Using the same cache path as the core image
RUN --mount=type=cache,mode=0755,uid=1000,gid=1000,target=/app/.cache/pip \
source $VENV_PATH/bin/activate && \
pip install -r extra-requirements.txt

# Re-apply world-writable permissions after installing extra packages.
# The core stage's chmod doesn't cover files added in this layer — newly
# installed packages and entry point scripts would be root-owned 644/755.
RUN PYTHON_VERSION=$(python3 -c "import sys; print(f'python{sys.version_info.major}.{sys.version_info.minor}')") && \
chmod -R a+w /app/.venv/lib/${PYTHON_VERSION}/site-packages && \
chmod a+w /app/.venv/bin
27 changes: 21 additions & 6 deletions services/comfy/core/dockerfile.comfy.core
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ RUN --mount=type=cache,target=/app/.cache/pip \
# ==================================================================
FROM runtime AS core

# Set shell to bash with pipefail for safety (not inherited across FROM)
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Remove default ubuntu user (UID 1000) if it exists to prevent conflict
# https://askubuntu.com/questions/1513927/
RUN touch /var/mail/ubuntu && \
Expand All @@ -58,22 +61,34 @@ ENV PYTHONPATH="/app/ComfyUI"
ENV HOME=/app
ENV XDG_CACHE_HOME=/app/.cache

# Suppress .pyc writes — avoids silent permission failures when running
# as an arbitrary UID that can't write to source directories
ENV PYTHONDONTWRITEBYTECODE=1

# Copy startup scripts to app root
COPY --chown=comfy:comfy startup.sh entrypoint.sh /app/

# Make scripts executable (fast/cheap operation on single files)
RUN chmod +x /app/startup.sh /app/entrypoint.sh

# Make directories writable by any user for arbitrary UID support
# (Docker Compose PUID/PGID, K8s securityContext.runAsUser, etc.)
# (Docker Compose PUID/PGID, K8s securityContext.runAsUser, OpenShift, etc.)
#
# Detect the Python version dynamically to avoid hardcoding python3.12
# Writable targets:
# - site-packages: ComfyUI Manager installs custom node deps at runtime
# - venv/bin: pip-installed packages create entry point scripts here
# - .cache: uv/pip cache operations
# - /etc/passwd: entrypoint injects passwd entry for arbitrary UIDs
# so getpwuid(), getpass.getuser(), and expanduser("~") work
RUN chmod -R a+w /app/.venv/lib/python3.12/site-packages && \
chmod a+w /app/.venv/lib/python3.12 && \
# - ComfyUI data dirs: ComfyUI creates these at startup if missing
# - /etc/passwd, /etc/group: entrypoint injects entries for arbitrary UIDs
# so getpwuid(), getgrgid(), getpass.getuser(), expanduser("~") all work
RUN PYTHON_VERSION=$(python3 -c "import sys; print(f'python{sys.version_info.major}.{sys.version_info.minor}')") && \
chmod -R a+w /app/.venv/lib/${PYTHON_VERSION}/site-packages && \
chmod a+w /app/.venv/lib/${PYTHON_VERSION} && \
chmod a+w /app/.venv/bin && \
mkdir -p /app/.cache && chmod -R a+w /app/.cache && \
chmod g+w /etc/passwd
chmod a+w /app /app/ComfyUI && \
chmod a+w /etc/passwd /etc/group

# Environment variables
ARG CLI_ARGS=""
Expand Down
17 changes: 10 additions & 7 deletions services/comfy/core/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ set -e
if [ "$(id -u)" -ne 0 ]; then
echo "Starting as non-root UID:GID = $(id -u):$(id -g)"

# Inject a passwd entry for the current UID if one doesn't exist.
# Many tools (Python's getpass.getuser(), PyTorch's cache_dir,
# os.path.expanduser) call getpwuid() which fails with KeyError
# for UIDs not in /etc/passwd. This is standard practice for
# containers supporting arbitrary UIDs (e.g., OpenShift).
if ! whoami &>/dev/null 2>&1; then
echo "comfy:x:$(id -u):$(id -g):ComfyUI User:/app:/bin/bash" >> /etc/passwd
# Inject /etc/passwd and /etc/group entries for the current UID/GID
# if they don't already exist. Many tools depend on these lookups:
# - Python: getpass.getuser(), os.path.expanduser("~"), grp.getgrgid()
# - PyTorch: cache_dir resolution via getpwuid()
# This is standard practice for arbitrary UID containers (OpenShift, etc.)
if ! getent passwd "$(id -u)" &>/dev/null; then
echo "comfyuser:x:$(id -u):$(id -g):ComfyUI User:/app:/bin/bash" >> /etc/passwd
fi
if ! getent group "$(id -g)" &>/dev/null; then
echo "comfygroup:x:$(id -g):" >> /etc/group
fi

source /app/.venv/bin/activate
Expand Down
Loading