🚀 Try this Example
Steps to run:- Install fal:
- Authenticate:
- Create the workflow file
sdxl_turbo_workflow.json:
- Copy the code below into
comfyui_sdxl_turbo.py:
- Run the app:
Architecture Overview
The app runs ComfyUI as a background process and communicates with it via HTTP:Key Concepts
Including the Workflow File
This example uploads the workflow to fal’s CDN and usesADD in the Dockerfile to download it during the build. Support for COPY and ADD of local files is experimental. See COPY and Build Context.
Runtime Model Loading
Large model weights are downloaded to/data (persistent storage) at runtime using download_model_weights from fal’s toolkit:
download_model_weights function:
- Atomic writes: Downloads to a temp file first, then renames (prevents corrupted files if multiple workers start simultaneously)
- Automatic caching: Skips download if the file already exists
- Smart storage: Saves to
/data/.fal/model_weights/{hash}/{filename}
Symlinking Models
ComfyUI expects models in specific directories. We create symlinks from ComfyUI’s model directories to the downloaded paths:Background Server with Popen
ComfyUI runs as a non-blocking background process usingsubprocess.Popen. Unlike subprocess.run() which blocks until completion, Popen starts the process and returns immediately, allowing your app to continue setup:
ComfyUI API Interaction
The app communicates with ComfyUI via its HTTP API:- Queue prompt:
POST /promptwith the workflow JSON - Poll for completion:
GET /history/{prompt_id}untilcompleted: true - Get outputs: Extract file paths from the history response
Image Output with fal Toolkit
UseImage.from_path() to upload generated images to fal’s CDN:
request parameter ensures proper metadata is attached for the fal playground.
Customizing the Workflow
Exporting from ComfyUI
- Build your workflow in ComfyUI’s web interface
- Click Save (API Format) to export as JSON
- Replace the contents of
sdxl_turbo_workflow.json
Mapping Node IDs
When you export a workflow, each node has an ID. Update_build_workflow() to map your inputs to the correct node IDs:
Best Practices
-
Use
/datafor model weights: Download large models to/datainsetup()instead of baking them into the Docker image. This improves cold start times. - Pin your dependencies: Specify exact versions in the Dockerfile to ensure reproducible builds.
- Set appropriate timeouts: Model loading and generation can take time. Use generous timeouts.
-
Use
keep_alive: Setkeep_aliveto avoid cold starts between requests.
Troubleshooting
Model Not Found
Check that:- The model is downloaded to the correct path in
/data - The symlink points to the correct file
- The workflow uses the correct model filename
Using an External Registry?
If you have a ComfyUI Docker image hosted on an external registry (Docker Hub, Google Artifact Registry, Amazon ECR, Azure Container Registry), you can pull it directly instead of building from a Dockerfile. See Using Private Docker Registries for setup instructions.Next Steps
- Migrate External Docker Servers - Direct port exposure vs. proxy pattern
- Use Custom Container Images - Dockerfile patterns
- Use Persistent Storage - More about
/datadirectory - Scale Your Application - Handle more traffic