🚀 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
Container apps don’t supportCOPY instructions or app_files for including local files. Instead, we upload the workflow to fal’s CDN and use ADD in the Dockerfile:
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
Permission Errors in Dockerfile
Thefalai/base image runs as a non-root user. Add USER root before apt-get:
Using an External Registry?
If you have a ComfyUI Docker image hosted on an external registry (Docker Hub, Google Artifact Registry, Amazon ECR), 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