Ollama: Implantação Containerizada com Docker

Docker transforma Ollama em blocos de LEGO — baixe imagens, orquestre combinações, implante com um comando.

⚠️ Nota: Contêineres Docker não persistem dados por padrão — deletar um Contêiner perde todos os arquivos de modelo (frequentemente vários GB). Você deve usar montagem de Volume (-v ollama_data:/root/.ollama) para persistir dados do modelo no host. Isso jamais deve ser omitido em produção.

📋 Pré-requisitos: Você deve dominar o seguinte primeiro

1. O Que Você Vai Aprender


2. Uma História Real de Uma Empreendedora SaaS

(1) O Problema: Instalando Ollama Manualmente em Cada Servidor

Alice precisa implantar o SupportBot em 3 servidores, cada um requerendo instalação manual do Ollama, download de modelos e configuração de ambiente. Inconsistências de versão, configurações esquecidas e diferenças de ambiente causam vários problemas.

(2) A Solução: Implantação Docker com Um Comando

BASH
# One command to run Ollama in container
docker run -d --gpus all -v ollama_data:/root/.ollama ollama/ollama

# Or with Docker Compose for full stack
docker compose up -d

3. Imagem Oficial do Ollama

(1) Variantes da Imagem

Imagem Tamanho Propósito
ollama/ollama ~800 MB CPU + GPU (auto-detectado)
ollama/ollama:rocm ~1.2 GB Apenas GPU AMD

(2) Comandos Básicos de Execução

Cenário Comando
Apenas CPU docker run -d -p 11434:11434 ollama/ollama
GPU NVIDIA docker run -d --gpus all -p 11434:11434 ollama/ollama
Armazenamento persistente docker run -d -v ollama_data:/root/.ollama -p 11434:11434 ollama/ollama
Porta personalizada docker run -d -p 8080:11434 ollama/ollama
100%
flowchart TD
    A[ollama/ollama image] --> B{GPU available?}
    B -->|NVIDIA| C[nvidia-container-toolkit<br/>--gpus all]
    B -->|AMD| D[rocm image<br/>--device /dev/kfd]
    B -->|None| E[CPU-only mode]
    C --> F[Ollama Server :11434]
    D --> F
    E --> F

▶ Exemplo 1: Execução de Contêiner CPU

⚠️ Aviso: Executar um Contêiner sem montar um Volume (-v ollama_data:/root/.ollama) armazena dados do modelo dentro do Contêiner. Uma vez deletado o Contêiner, todos os modelos são perdidos e devem ser baixados novamente (frequentemente vários GB). Ambientes de produção devem montar armazenamento persistente.

BASH
# Run Ollama in container (CPU mode)
docker run -d \
  --name ollama \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama

# Verify it's running
docker ps | grep ollama

# Pull a model inside the container
docker exec ollama ollama pull qwen2.5

# Test the API
curl http://localhost:11434/api/tags

Saída:

TEXT
I'm a helpful AI assistant running locally on your machine...

4. Configuração de Contêiner GPU

(1) Pré-requisitos para Contêiner GPU NVIDIA

Passo Comando Descrição
1 Instalar drivers NVIDIA nvidia-smi deve funcionar
2 Instalar nvidia-container-toolkit Necessário para passthrough de GPU
3 Reiniciar Docker sudo systemctl restart docker
4 Verificar disponibilidade de GPU docker run --rm --gpus all nvidia/cuda:12.0.0-runtime-ubuntu22.04 nvidia-smi

(2) Instalação do nvidia-container-toolkit

Plataforma Comando de Instalação
Ubuntu/Debian `curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey
CentOS/RHEL `curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo
Configurar Docker sudo nvidia-ctk runtime configure --runtime=docker && sudo systemctl restart docker

▶ Exemplo 2: Execução de Contêiner GPU NVIDIA

BASH
# Run Ollama with GPU support
docker run -d \
  --name ollama-gpu \
  --gpus all \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama

# Verify GPU is visible inside container
docker exec ollama-gpu nvidia-smi

# Test GPU inference speed
docker exec ollama-gpu ollama run --verbose llama3.2 "Hello"

# Specify which GPUs to use
docker run -d \
  --gpus '"device=0,1"' \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama

Saída:

TEXT
I'm a helpful AI assistant running locally on your machine...

▶ Exemplo 3: Contêiner AMD ROCm

BASH
# Run Ollama with AMD GPU (ROCm)
docker run -d \
  --name ollama-rocm \
  --device /dev/kfd \
  --device /dev/dri \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama:rocm

Saída:

TEXT
I'm a helpful AI assistant running locally on your machine...

5. Orquestração Multi-Serviço com Docker Compose

💡 Dica: Docker Compose pode orquestrar múltiplos serviços em um comando (Ollama + Chroma + WebUI + FastAPI). Usar healthcheck + depends_on.condition: service_healthy garante que serviços dependentes estão realmente prontos antes de iniciar os subsequentes, o que é mais confiável do que simples ordenação de inicialização.

💡 Dica: O healthcheck + depends_on.condition: service_healthy do Docker Compose garante que serviços dependentes estão realmente prontos antes de iniciar os subsequentes, o que é mais confiável do que a ordem simples de inicialização. O Ollama precisa de alguns segundos após iniciar antes de poder responder a requisições de API.

(1) Arquitetura Multi-Serviço Típica

100%
flowchart TD
    A[Nginx<br/>:80 Reverse Proxy] --> B[FastAPI App<br/>:8000]
    B --> C[Ollama<br/>:11434]
    B --> D[Chroma DB<br/>:8001 Vector Store]
    C --> E[Model Volume]
    D --> F[Chroma Volume]

(2) Template docker-compose.yml

Serviço Imagem Porta Dependências
ollama ollama/ollama 11434 GPU runtime
webui open-webui/open-webui 3000 ollama
chroma chromadb/chroma 8000
app custom fastapi 8001 ollama, chroma

▶ Exemplo 4: Configuração Completa do Docker Compose

⚠️ Aviso: Em configurações de produção, OLLAMA_HOST=0.0.0.0:11434 faz o Ollama escutar em todas as interfaces de rede. Isso é seguro dentro da rede interna do Docker, mas extremamente perigoso se a porta estiver mapeada para o IP público do host. Sempre use isso com autenticação Nginx ou regras de firewall.

YAML
# docker-compose.yml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    restart: unless-stopped

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - webui_data:/app/backend/data
    depends_on:
      - ollama
    restart: unless-stopped

  chroma:
    image: chromadb/chroma
    container_name: chroma
    ports:
      - "8001:8000"
    volumes:
      - chroma_data:/chroma/chroma
    environment:
      - ANONYMIZED_TELEMETRY=FALSE
    restart: unless-stopped

volumes:
  ollama_data:
  webui_data:
  chroma_data:
BASH
# Start all services
docker compose up -d

# Pull model inside ollama container
docker exec ollama ollama pull qwen2.5
docker exec ollama ollama pull nomic-embed-text

# Check all services
docker compose ps

# View logs
docker compose logs -f ollama

Saída:

TEXT
[+] Running 4/4
 ✔ Network ollama_default  Created
 ✔ Container ollama        Started
 ✔ Container open-webui    Started
 ✔ Container chroma        Started

(1) Comparação de Montagem de Volume

Método Comando Persistência Desempenho
Named Volume -v ollama_data:/root/.ollama ✅ Gerenciado pelo Docker Bom
Bind Mount -v /data/ollama:/root/.ollama ✅ Gerenciado pelo host Melhor
tmpfs --tmpfs /root/.ollama ❌ Memória Mais rápido

(2) Comparação de Modo de Rede

Modo Comando Caso de Uso Descrição
bridge Padrão Comunicação entre Contêineres Requer mapeamento de porta
host --network host Baixa latência Compartilha rede do host
Rede personalizada docker network create mynet Multi-serviço Resolução DNS automática

▶ Exemplo 5: Docker Compose de Nível de Produção

YAML
# docker-compose.prod.yml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - /data/ollama/models:/root/.ollama
    environment:
      - OLLAMA_HOST=0.0.0.0:11434
      - OLLAMA_KEEP_ALIVE=30m
      - OLLAMA_NUM_PARALLEL=4
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
        limits:
          memory: 16G
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
      interval: 30s
      timeout: 10s
      retries: 3

  app:
    build: ./app
    container_name: supportbot
    ports:
      - "8000:8000"
    environment:
      - OLLAMA_HOST=http://ollama:11434
    depends_on:
      ollama:
        condition: service_healthy
    restart: unless-stopped

networks:
  default:
    name: supportbot-net

Saída:

TEXT
# Verify configuration file syntax
docker compose config --quiet && echo "✅ Configuration file syntax is correct"
# Output: ✅ Configuration file syntax is correct

7. Exemplo Abrangente: Implantação Docker Full-Stack do SupportBot

ℹ️ Info: O Contêiner init-models usa um padrão de "tarefa única" — ele automaticamente baixa os modelos necessários após o health check do Ollama passar, e então sai. Isso elimina a necessidade de entrar manualmente no Contêiner para executar ollama pull, alcançando verdadeira "implantação com um comando."

YAML
# ============================================
# Comprehensive: SupportBot full-stack Docker
# Ollama + FastAPI + Chroma + Open WebUI
# ============================================

# docker-compose.yml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_models:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:11434/api/tags || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
    restart: unless-stopped

  init-models:
    image: curlimages/curl
    container_name: init-models
    depends_on:
      ollama:
        condition: service_healthy
    command: >
      sh -c "
        curl -s http://ollama:11434/api/pull -d '{\"name\":\"qwen2.5\"}' &&
        curl -s http://ollama:11434/api/pull -d '{\"name\":\"nomic-embed-text\"}' &&
        curl -s http://ollama:11434/api/pull -d '{\"name\":\"llava\"}'
      "

  chroma:
    image: chromadb/chroma
    container_name: chroma
    ports:
      - "8001:8000"
    volumes:
      - chroma_data:/chroma/chroma
    environment:
      - ANONYMIZED_TELEMETRY=FALSE
    restart: unless-stopped

  supportbot:
    build:
      context: ./app
      dockerfile: Dockerfile
    container_name: supportbot
    ports:
      - "8000:8000"
    environment:
      - OLLAMA_HOST=http://ollama:11434
      - CHROMA_HOST=http://chroma:8000
      - EMBED_MODEL=nomic-embed-text
      - CHAT_MODEL=qwen2.5
    depends_on:
      ollama:
        condition: service_healthy
      chroma:
        condition: service_started
    restart: unless-stopped

  webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: webui
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - webui_data:/app/backend/data
    depends_on:
      - ollama
    restart: unless-stopped

volumes:
  ollama_models:
  chroma_data:
  webui_data:
BASH
#!/bin/bash
# Deploy SupportBot stack

# Start all services
docker compose up -d

# Wait for Ollama to be healthy
echo "Waiting for Ollama to be ready..."
until curl -s http://localhost:11434/api/tags > /dev/null 2>&1; do
    sleep 2
done
echo "Ollama is ready!"

# Pull required models
docker exec ollama ollama pull qwen2.5
docker exec ollama ollama pull nomic-embed-text

# Verify all services
docker compose ps
echo "SupportBot stack deployed!"
echo "  Ollama API:  http://localhost:11434"
echo "  SupportBot:  http://localhost:8000"
echo "  WebUI:       http://localhost:3000"
echo "  Chroma:      http://localhost:8001"

Saída:

TEXT
Waiting for Ollama to be ready...
Ollama is ready!
NAME                IMAGE                              STATUS
ollama              ollama/ollama                      Up (healthy)
chroma              chromadb/chroma                    Up
supportbot          custom/app                         Up
webui               ghcr.io/open-webui/open-webui      Up
SupportBot stack deployed!
  Ollama API:  http://localhost:11434
  SupportBot:  http://localhost:8000
  WebUI:       http://localhost:3000
  Chroma:      http://localhost:8001

❓ Perguntas Frequentes

P: A Inferência GPU dentro de Contêineres Docker é mais lenta que a instalação direta? R: Não deve haver diferença em condições normais. Verifique: 1) Se --gpus all está efetivo; 2) Se nvidia-container-toolkit está instalado; 3) Se o runtime do Docker está configurado como nvidia.

P: Os modelos ainda estão lá após reiniciar o Contêiner? R: Se você montou um Volume em /root/.ollama, os dados do modelo são persistidos e retidos. Sem Volume, os modelos são perdidos e devem ser baixados novamente.

P: Como entro em um Contêiner para executar comandos ollama? R: Use docker exec -it ollama bash ou docker exec ollama ollama pull model_name para operar dentro do Contêiner.

P: O depends_on do Docker Compose garante que o serviço está pronto? R: Não. depends_on apenas garante a ordem de inicialização. Adicione healthcheck + condition: service_healthy para garantir que serviços dependentes estão realmente prontos.

P: O que é Open WebUI? R: Uma interface web de código aberto no estilo ChatGPT que se conecta diretamente ao Ollama. Adequada para usuários não-técnicos e para demonstrações. Implantação Docker com um comando.

P: Como múltiplos Contêineres compartilham uma GPU? R: Use --gpus all para deixar todos os Contêineres compartilharem a GPU. O Ollama internamente enfileira requisições. Para isolamento, use --gpus '"device=0"' e --gpus '"device=1"' para atribuir GPUs diferentes.


📖 Resumo


📝 Exercícios

  1. Básico (⭐): Execute um Contêiner Ollama com Docker, baixe um modelo, e teste uma conversa via API.
  2. Intermediário (⭐⭐): Escreva uma configuração Docker Compose para iniciar Ollama + Open WebUI, e complete uma conversa no WebUI.
  3. Avançado (⭐⭐⭐): Implante o SupportBot full-stack completo (Ollama + FastAPI + Chroma + WebUI), implemente Q&A RAG, e verifique persistência.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%