Docker provides a consistent way to package and deploy Gradio apps across different environments. This guide shows you how to containerize your Gradio applications and deploy them anywhere.
Why use Docker?
Deploying Gradio apps with Docker offers several advantages:
Consistency : Your app runs identically across development, staging, and production
Portability : Move containers between local machines, cloud providers, and servers
Scalability : Use orchestration tools like Kubernetes to scale horizontally
Isolation : Dependencies are contained within the image
Reproducibility : Anyone can run your app with a single command
Prerequisites
Before you begin:
Install Docker Desktop (includes Docker Engine and Docker Compose)
Basic familiarity with Docker concepts
A working Gradio application
Quick start
Create a simple Gradio app and containerize it:
Create your Gradio app
Create app.py: import gradio as gr
def greet ( name ):
return f "Hello { name } !"
demo = gr.Interface(
fn = greet,
inputs = "text" ,
outputs = "text"
)
demo.launch()
Create a Dockerfile
Create Dockerfile in the same directory: FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 7860
ENV GRADIO_SERVER_NAME= "0.0.0.0"
CMD [ "python" , "app.py" ]
Create requirements.txt
List your Python dependencies:
Build and run
Build the Docker image: docker build -t gradio-app .
Run the container: docker run -p 7860:7860 gradio-app
Access your app at http://localhost:7860
Dockerfile explained
Let’s break down the Dockerfile:
# Use official Python runtime as base image
FROM python:3.10-slim
# Set working directory in container
WORKDIR /app
# Copy requirements and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Expose Gradio's default port
EXPOSE 7860
# Set environment variable for Gradio
ENV GRADIO_SERVER_NAME= "0.0.0.0"
# Run the application
CMD [ "python" , "app.py" ]
Key elements
FROM : Base image (use python:3.10-slim for smaller size)
WORKDIR : Sets /app as the working directory
COPY requirements.txt : Copies dependencies first (better caching)
RUN pip install : Installs Python packages
COPY . : Copies all app files
EXPOSE 7860 : Documents that the app listens on port 7860
ENV GRADIO_SERVER_NAME : Makes Gradio accept external connections
CMD : Command to run when container starts
Setting GRADIO_SERVER_NAME="0.0.0.0" is crucial - it allows connections from outside the container. Without this, you won’t be able to access the app.
Production-ready Dockerfile
For production deployments, use this enhanced Dockerfile:
FROM python:3.10-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
build-essential \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -m -u 1000 gradio && \
mkdir -p /app && \
chown -R gradio:gradio /app
WORKDIR /app
# Copy and install dependencies
COPY --chown=gradio:gradio requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application files
COPY --chown=gradio:gradio . .
# Switch to non-root user
USER gradio
# Expose port
EXPOSE 7860
# Set environment variables
ENV GRADIO_SERVER_NAME= "0.0.0.0" \
GRADIO_SERVER_PORT=7860
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:7860/ || exit 1
# Run application
CMD [ "python" , "app.py" ]
Improvements:
Non-root user for security
System dependencies handling
Health check for monitoring
Proper file permissions
Multi-stage builds
Reduce image size with multi-stage builds:
# Build stage
FROM python:3.10 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# Runtime stage
FROM python:3.10-slim
WORKDIR /app
# Copy installed packages from builder
COPY --from=builder /root/.local /root/.local
# Copy application
COPY . .
# Update PATH
ENV PATH=/root/.local/bin:$PATH
EXPOSE 7860
ENV GRADIO_SERVER_NAME= "0.0.0.0"
CMD [ "python" , "app.py" ]
Docker Compose
For apps with multiple services (database, cache, etc.):
version : '3.8'
services :
gradio :
build : .
ports :
- "7860:7860"
environment :
- GRADIO_SERVER_NAME=0.0.0.0
volumes :
- ./data:/app/data
restart : unless-stopped
redis :
image : redis:7-alpine
ports :
- "6379:6379"
restart : unless-stopped
Run with:
Environment variables
Manage configuration with environment variables:
In Dockerfile
ENV MODEL_NAME= "gpt2" \
MAX_LENGTH=100 \
TEMPERATURE=0.7
At runtime
docker run -p 7860:7860 \
-e MODEL_NAME="gpt2" \
-e MAX_LENGTH= 100 \
gradio-app
Using .env file
Create .env:
MODEL_NAME=gpt2
MAX_LENGTH=100
TEMPERATURE=0.7
Run with:
docker run -p 7860:7860 --env-file .env gradio-app
In your app
import os
import gradio as gr
MODEL_NAME = os.getenv( "MODEL_NAME" , "gpt2" )
MAX_LENGTH = int (os.getenv( "MAX_LENGTH" , "100" ))
def generate ( prompt ):
# Use MODEL_NAME and MAX_LENGTH
return f "Generated with { MODEL_NAME } "
demo = gr.Interface(
fn = generate,
inputs = "text" ,
outputs = "text"
)
demo.launch()
Volume mounting
Persist data between container restarts:
Mount data directory
docker run -p 7860:7860 \
-v $( pwd ) /data:/app/data \
gradio-app
Mount model cache
docker run -p 7860:7860 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
gradio-app
GPU support
For apps using GPU models:
Dockerfile with CUDA
FROM nvidia/cuda:11.8.0-runtime-ubuntu22.04
RUN apt-get update && apt-get install -y python3 python3-pip
WORKDIR /app
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 7860
ENV GRADIO_SERVER_NAME= "0.0.0.0"
CMD [ "python3" , "app.py" ]
Run with GPU
docker run -p 7860:7860 --gpus all gradio-app
Deployment scenarios
AWS ECS
Push image to ECR:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin < account-i d > .dkr.ecr.us-east-1.amazonaws.com
docker tag gradio-app:latest < account-i d > .dkr.ecr.us-east-1.amazonaws.com/gradio-app:latest
docker push < account-i d > .dkr.ecr.us-east-1.amazonaws.com/gradio-app:latest
Create ECS task definition with your image
Create ECS service
Configure load balancer with session stickiness
Enable session stickiness on your load balancer! Gradio requires multiple connections from the same client to route to the same instance. Set sessionAffinity: ClientIP or equivalent.
Google Cloud Run
Build and push:
gcloud builds submit --tag gcr.io/PROJECT-ID/gradio-app
Deploy:
gcloud run deploy gradio-app \
--image gcr.io/PROJECT-ID/gradio-app \
--platform managed \
--port 7860 \
--allow-unauthenticated
Azure Container Instances
az container create \
--resource-group myResourceGroup \
--name gradio-app \
--image myregistry.azurecr.io/gradio-app:latest \
--dns-name-label gradio-app \
--ports 7860
Push to Docker Hub or DigitalOcean Container Registry
Create new app in App Platform
Select Docker Hub as source
Configure HTTP port: 7860
Deploy
Behind a reverse proxy
When deploying behind Nginx or similar:
Nginx configuration
server {
listen 80 ;
server_name demo.example.com;
location / {
proxy_pass http://localhost:7860;
proxy_http_version 1.1 ;
proxy_set_header Upgrade $ http_upgrade ;
proxy_set_header Connection "upgrade" ;
proxy_set_header Host $ host ;
proxy_set_header X-Real-IP $ remote_addr ;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $ scheme ;
}
}
Docker Compose with Nginx
version : '3.8'
services :
gradio :
build : .
expose :
- 7860
environment :
- GRADIO_SERVER_NAME=0.0.0.0
nginx :
image : nginx:alpine
ports :
- "80:80"
volumes :
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on :
- gradio
Best practices
Use .dockerignore
Create .dockerignore to exclude unnecessary files: __pycache__
*.pyc
.git
.env
.DS_Store
venv/
*.md
Pin dependency versions
In requirements.txt: gradio==4.44.0
transformers==4.35.0
torch==2.1.0
Use specific base image tags
Instead of python:3.10, use python:3.10.13-slim
Minimize layers
Combine RUN commands: RUN apt-get update && \
apt-get install -y package1 package2 && \
rm -rf /var/lib/apt/lists/*
Add health checks
Monitor container health: HEALTHCHECK CMD curl -f http://localhost:7860/ || exit 1
Troubleshooting
Can’t access app from browser
Ensure GRADIO_SERVER_NAME="0.0.0.0" is set
Verify port mapping: -p 7860:7860
Check firewall rules
Out of memory
Increase Docker memory limit in Docker Desktop settings
Use smaller base image (-slim or -alpine)
Reduce model size or use quantization
Slow builds
Use .dockerignore
Order Dockerfile commands from least to most frequently changed
Use multi-stage builds
Enable BuildKit: DOCKER_BUILDKIT=1 docker build
Check logs: docker logs <container-id>
Verify app.py runs locally
Ensure all dependencies are in requirements.txt
Next steps
Hugging Face Spaces Deploy to managed infrastructure
Sharing apps Add authentication and embedding