Skip to content

Running a containerized application

The easiest way to understand how to run a containerized application is to see an example. Let’s convert the example from the previous section into a containerized application.

import fal
from fal.container import ContainerImage
from fal.toolkit import Image, optimize
from pydantic import BaseModel, Field
dockerfile_str = """
FROM python:3.11
RUN apt-get update && apt-get install -y ffmpeg
RUN pip install "accelerate" "transformers>=4.30.2" "diffusers>=0.26" "torch>=2.2.0"
"""
class Input(BaseModel):
prompt: str = Field(
description="The prompt to generate an image from.",
examples=[
"A cinematic shot of a baby racoon wearing an intricate italian priest robe.",
],
)
class Output(BaseModel):
image: Image = Field(
description="The generated image.",
)
class FalModel(
fal.App,
image=ContainerImage.from_dockerfile_str(dockerfile_str),
kind="container",
):
machine_type = "GPU"
def setup(self) -> None:
import torch
from diffusers import AutoPipelineForText2Image
# Load SDXL
self.pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16",
)
self.pipeline.to("cuda")
# Apply fal's spatial optimizer to the pipeline.
self.pipeline.unet = optimize(self.pipeline.unet)
self.pipeline.vae = optimize(self.pipeline.vae)
# Warm up the model.
self.pipeline(
prompt="a cat",
num_inference_steps=30,
)
@fal.endpoint("/")
def text_to_image(self, input: Input) -> Output:
result = self.pipeline(
prompt=input.prompt,
num_inference_steps=30,
)
[image] = result.images
return Output(image=Image.from_pil(image))

Voila! 🎉 The highlighted changes are the only modifications you need to make; the rest remains your familiar fal application.

Private docker registries

To use private docker registries, you need to provide registry credentials like so:

Dockerhub

class FalModel(
fal.App,
kind="container",
image=ContainerImage.from_dockerfile_str(
"FROM myuser/image:tag",
registries={
"https://index.docker.io/v1/": {
"username": "myuser",
"password": "$DOCKERHUB_TOKEN", # use `fal secrets set` first to create this secret
},
},
),
)
...

Google Artifact Registry

class FalModel(
fal.App,
kind="container",
image=ContainerImage.from_dockerfile_str(
"FROM europe-west1-docker.pkg.dev/myuser/image:tag",
registries={
"https://index.docker.io/v1/": {
"username": "oauth2accesstoken",
"password": "$GCP_TOKEN", # use `fal secrets set` first to create this secret
},
},
),
)
...

Amazon Elastic Container Registry

class FalModel(
fal.App,
kind="container",
image=ContainerImage.from_dockerfile_str(
"FROM 123456789012.dkr.ecr.us-east-1.amazonaws.com/image:tag",
registries={
"https://index.docker.io/v1/": {
"username": "AWS",
# Use `aws ecr get-login-password --region us-east-1` to get a token. Note that they only last
# 12 hours so it is better to just create them dynamically here instead of creating one and
# setting it as a `fal secret`.
# https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html
"password": aws_token,
},
},
),
)
...