Custom Base Images
This guide shows how to create and import custom base images for Firecase. Base images are ext4 filesystem images that serve as starting points for instances — pre-loaded with your OS, packages, and configuration.
Why Custom Base Images?
The default base image includes Ubuntu 22.04 with common tools. But you may want:
- Language-specific images — Python ML stack with PyTorch, CUDA, and Jupyter pre-installed
- Framework images — Rails, Django, or Next.js with all dependencies cached
- Security-hardened images — Locked-down images with minimal attack surface
- Corporate images — Internal tools, VPN configs, certificates pre-installed
Custom images eliminate setup time — every instance forked from your image starts with everything ready.
Building an Image with Docker
The recommended workflow: build a Docker image, export it as an ext4 filesystem, then import it into Firecase.
1. Create a Dockerfile
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
# System packages
RUN apt-get update && apt-get install -y \
build-essential \
curl \
git \
python3 \
python3-pip \
nodejs \
npm \
vim \
wget \
&& rm -rf /var/lib/apt/lists/*
# Python ML packages
RUN pip3 install \
numpy \
pandas \
scikit-learn \
matplotlib \
jupyter
# Create a default user
RUN useradd -m -s /bin/bash user
# Set up the working directory
WORKDIR /home/user
# Add any config files
COPY .bashrc /home/user/.bashrc
# The guest agent will be injected by Firecase at boot
# Don't worry about it in the Dockerfile2. Build and Export to ext4
# Build the Docker image
docker build -t my-base-image .
# Create a container (don't start it)
docker create --name temp-container my-base-image
# Export the filesystem to a tar archive
docker export temp-container > rootfs.tar
# Clean up the container
docker rm temp-container
# Create an ext4 image from the tar
# Size should be larger than the tar to leave room for writes
truncate -s 4G my-image.ext4
mkfs.ext4 my-image.ext4
# Mount and extract
mkdir -p /mnt/image
mount -o loop my-image.ext4 /mnt/image
tar -xf rootfs.tar -C /mnt/image
# Ensure the guest agent directory exists
mkdir -p /mnt/image/usr/local/bin
# Unmount
umount /mnt/image
rmdir /mnt/image3. Import into Firecase
Upload the ext4 image to the control plane server, then import it:
curl -X POST https://api.firecase.ai/images/import \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "ml-python",
"description": "Python 3 with NumPy, Pandas, Scikit-learn, Matplotlib, and Jupyter",
"image_path": "/data/images/my-image.ext4",
"tags": ["python", "ml", "jupyter"],
"is_default": false
}'The import process:
- Reads the ext4 file
- Splits it into 16 MiB chunks
- Uploads each chunk to S3
- Creates a manifest mapping chunk indices to chunk IDs
- Registers the base image in the database
4. Use Your Image
curl -X POST https://api.firecase.ai/instances \
-H "Authorization: Bearer $API_KEY" \
-d '{
"name": "ml-workspace",
"base_image_id": "{your_image_id}"
}'The instance inherits all chunks from your base image via copy-on-write. No data is copied — creation is instant.
Image Sizing Guidelines
| Use Case | Recommended Size |
|---|---|
| Minimal (Alpine-like) | 512 MiB - 1 GiB |
| Standard dev tools | 2 - 4 GiB |
| ML/Data Science stack | 4 - 8 GiB |
| Full IDE + frameworks | 8 - 16 GiB |
Leave at least 20% free space in the image for runtime writes. The ext4 filesystem needs room for journals, temporary files, and user data.
Best Practices
Keep Images Lean
Every byte in the image is a chunk in S3. Smaller images = faster prefetch on first boot.
# Good: clean up package caches
RUN apt-get update && apt-get install -y python3 \
&& rm -rf /var/lib/apt/lists/*
# Bad: leaves cache around
RUN apt-get update
RUN apt-get install -y python3Layer Wisely
Since Firecase uses 16 MiB chunks, try to keep related changes in the same filesystem region. In practice, this means:
- Install all packages in one
RUNcommand - Don't create then delete large temporary files (the chunks are still uploaded)
Test Locally First
Before importing, test your image locally:
# Test with QEMU
qemu-system-x86_64 -m 1024 -drive file=my-image.ext4,format=raw -nographicVersion Your Images
Use descriptive names with versions:
curl -X POST https://api.firecase.ai/images/import \
-d '{"name": "ml-python-v2", "tags": ["python", "ml", "v2"]}'Managing Base Images
List all images
curl https://api.firecase.ai/base-images \
-H "Authorization: Bearer $API_KEY"Delete an image
curl -X DELETE https://api.firecase.ai/base-images/{id} \
-H "Authorization: Bearer $API_KEY"Deleting a base image removes the image record and template instance. Chunks in S3 are preserved because they may be shared with instances that were created from this image.
Next Steps
- See the Base Images API for all operations
- Learn about Instances and how they use base images
- Explore Profiles to set resource limits for different image types