> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runpod.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Dockerfile

> Package your handler function for deployment.

export const CUDATooltip = () => {
  return <Tooltip headline="CUDA" tip="NVIDIA's parallel computing platform that enables GPU-accelerated processing for AI/ML workloads. CUDA provides the low-level interface between your code and NVIDIA GPUs." cta="Read the CUDA docs" href="https://developer.nvidia.com/cuda-toolkit">CUDA</Tooltip>;
};

export const HandlerFunctionTooltip = () => {
  return <Tooltip headline="Handler function" tip="The core of a Runpod Serverless application. These functions define how a worker processes incoming requests and returns results." cta="Learn more about handler functions" href="/serverless/workers/handler-functions">handler function</Tooltip>;
};

A Dockerfile defines the build process for a Docker image containing your <HandlerFunctionTooltip /> and all its dependencies. This page explains how to organize your project files and create a Dockerfile for your Serverless worker.

<Note>
  New to Docker? Learn the fundamentals with the [introduction to containers](/tutorials/introduction/containers) tutorial series, which covers [creating Dockerfiles](/tutorials/introduction/containers/create-dockerfiles), [essential Docker commands](/tutorials/introduction/containers/docker-commands), and [data persistence](/tutorials/introduction/containers/persist-data).
</Note>

## Project organization

Organize your project files in a clear directory structure:

<Tree>
  <Tree.Folder name="project_directory" defaultOpen>
    <Tree.File name="Dockerfile" comment="Instructions for building the Docker image" />

    <Tree.Folder name="src" defaultOpen>
      <Tree.File name="handler.py" comment="Your handler function" />
    </Tree.Folder>

    <Tree.File name="requirements.txt" comment="Dependencies required by your handler" />
  </Tree.Folder>
</Tree>

`/Dockerfile/` contains the instructions for building your worker image.

`/src/handler.py/` is your <HandlerFunctionTooltip />.

`/requirements.txt/` lists the Python dependencies required by your handler. For example:

```txt title="requirements.txt" theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Example requirements.txt
runpod~=1.7.6
torch==2.0.1
pillow==9.5.0
transformers==4.30.2
```

## Basic Dockerfile structure

A basic Dockerfile for a Runpod Serverless worker follows this structure:

```dockerfile title="Dockerfile" theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM python:3.11.1-slim

WORKDIR /

# Copy and install requirements
COPY builder/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy your handler code
COPY src/handler.py .

# Command to run when the container starts
CMD ["python", "-u", "/handler.py"]
```

This Dockerfile:

1. Starts with a Python base image.
2. Sets the working directory to the root.
3. Copies and installs Python dependencies.
4. Copies your handler code.
5. Specifies the command to run when the container starts.

## Choosing a base image

The base image you choose affects your image size, startup time, and available system dependencies. Common options include:

### Python slim images

Recommended for most use cases. These images are smaller and faster to download:

```dockerfile theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM python:3.11.1-slim
```

### Python full images

Include more system tools and libraries but are larger:

```dockerfile theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM python:3.11.1
```

### <CUDATooltip /> images

Required if you need <CUDATooltip /> libraries for GPU-accelerated workloads:

```dockerfile theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04

# Install Python
RUN apt-get update && apt-get install -y python3.11 python3-pip
```

### Custom base images

You can build on top of specialized images for specific frameworks:

```dockerfile theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime
```

## Including models and files

<Tip>
  If your model is available on Hugging Face, we strongly recommend enabling [cached models](/serverless/endpoints/model-caching) instead of baking/downloading the model into your Docker image. Cached models provide faster startup times, lower costs, and uses less storage.
</Tip>

### Baking models into the image

If you need to include model files or other assets in your image, use the `COPY` instruction:

```dockerfile title="Dockerfile" theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM python:3.11.1-slim

WORKDIR /

# Copy and install requirements
COPY builder/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy your code and model files
COPY src/handler.py .
COPY models/ /models/

# Set environment variables if needed
ENV MODEL_PATH=/models/my_model.pt

# Command to run when the container starts
CMD ["python", "-u", "/handler.py"]
```

### Downloading models during build

You can download models during the Docker build process:

```dockerfile title="Dockerfile" theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Download model files
RUN wget -q URL_TO_YOUR_MODEL -O /models/my_model.pt

# Or use a script to download from Hugging Face
RUN python -c "from transformers import AutoModel; AutoModel.from_pretrained('model-name')"
```

## Environment variables

Set environment variables to configure your application without hardcoding values:

```dockerfile title="Dockerfile" theme={"theme":{"light":"github-light","dark":"github-dark"}}
ENV MODEL_PATH=/models/my_model.pt
ENV LOG_LEVEL=INFO
ENV MAX_BATCH_SIZE=4
```

You can override these at runtime through the Runpod console when configuring your endpoint.

For details on how to access environment variables in your handler functions, see [Environment variables](/serverless/development/environment-variables).

## Optimizing image size

Smaller images download and start faster, reducing cold start times. Use these techniques to minimize image size:

### Use multi-stage builds

Multi-stage builds let you compile dependencies in one stage and copy only the necessary files to the final image:

```dockerfile title="Dockerfile" theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Build stage
FROM python:3.11.1 AS builder

WORKDIR /build
COPY builder/requirements.txt .
RUN pip install --no-cache-dir --target=/build/packages -r requirements.txt

# Runtime stage
FROM python:3.11.1-slim

WORKDIR /
COPY --from=builder /build/packages /usr/local/lib/python3.11/site-packages
COPY src/handler.py .

CMD ["python", "-u", "/handler.py"]
```

### Clean up build artifacts

Remove unnecessary files after installation:

```dockerfile title="Dockerfile" theme={"theme":{"light":"github-light","dark":"github-dark"}}
RUN apt-get update && apt-get install -y build-essential \
    && pip install --no-cache-dir -r requirements.txt \
    && apt-get remove -y build-essential \
    && apt-get autoremove -y \
    && rm -rf /var/lib/apt/lists/*
```

### Use .dockerignore

Create a `.dockerignore` file to exclude unnecessary files from the build context:

```txt title=".dockerignore" theme={"theme":{"light":"github-light","dark":"github-dark"}}
.git
.gitignore
README.md
tests/
*.pyc
__pycache__/
.venv/
venv/
```

## Next steps

After creating your Dockerfile, you can:

* [Build and deploy your image from Docker Hub](/serverless/workers/deploy).
* [Deploy directly from GitHub](/serverless/workers/github-integration).
* [Test your handler locally](/serverless/development/local-testing) before building the image.
