Databricks Tips #7: Docker en Databricks — contenedores custom para entornos que no se rompen
Laboratorio práctico — Dockerfile + notebook para probar DCS en Databricks Free Edition.
Séptima entrega de Databricks Tips. Sí, Databricks Runtime ya te da un entorno curado con Spark, pandas, MLflow y todo lo estándar pre-instalado. Entonces, ¿para qué Docker? El problema aparece cuando necesitás algo que el runtime no trae: librerías de sistema como GDAL o compiladores de C, versiones específicas que chocan con las del runtime, o un entorno bloqueado que no cambie entre releases de DBR. Ahí es donde Databricks Container Services entra en juego.
Docker en 2 minutos (para los que nunca lo usaron)
Si ya sabés qué es Docker, saltá a la siguiente sección. Si no, acá va la versión corta.
Imaginate que tenés una receta de cocina. Podés darle la receta a alguien y esperar que tenga los mismos ingredientes, el mismo horno y la misma temperatura… o podés darle la cocina entera empaquetada con todo adentro. Docker es eso: empaquetás tu código + dependencias + configuración en una imagen que corre igual en cualquier máquina.
Los conceptos clave:
- Imagen: el paquete con todo adentro (OS + librerías + config). Se construye con un
Dockerfile. - Container: una instancia corriendo de esa imagen. Podés tener muchos containers de la misma imagen.
- Registry: donde guardás las imágenes (Docker Hub, Amazon ECR, Azure ACR). Es como un “GitHub para imágenes Docker”.
- Dockerfile: la receta para construir la imagen. Cada línea
RUNagrega algo al entorno.
# Ejemplo básico de Dockerfile
FROM python:3.11-slim # Partís de una imagen base
RUN pip install pandas==2.2.3 # Instalás dependencias
COPY mi_script.py /app/ # Copiás tu códigoEso es todo lo que necesitás saber para entender el resto del post.
Qué es Databricks Container Services (DCS)
En vez de usar el runtime por defecto, DCS te permite arrancar tu compute con una imagen Docker propia. Vos definís las dependencias exactas, las bakeás en la imagen, y Databricks la usa como entorno de ejecución.
Pero ojo: vos no metés Spark en la imagen. Lo que pasa internamente cuando lanzás un cluster con DCS es esto (fuente):
- Se adquieren VMs del cloud provider
- Se descarga tu imagen Docker del registry
- Databricks crea un contenedor a partir de tu imagen
- El código del Databricks Runtime (Spark, JVM, dbutils) se copia dentro del contenedor
- Se ejecutan los init scripts (si hay)
Es decir, Databricks inyecta Spark en tu contenedor al arrancar. Por eso ignora CMD y ENTRYPOINT — necesita controlar el proceso de inicio. Vos solo ponés las dependencias, ellos ponen el runtime.
Lo nuevo (2025-2026): DCS ahora soporta Standard Compute (shared clusters con aislamiento). Antes solo funcionaba en Dedicated Compute. Esto cambia todo, porque ahora podés tener un entorno Docker compartido sin necesidad de un cluster por persona.
0. Habilitar DCS (prerequisito)
Antes de hacer cualquier cosa, un workspace admin tiene que habilitar Container Services. Si no lo hacés, el tab Docker no aparece al crear compute.
En AWS: Settings → Advanced → Container Services → Enabled.
En Azure (no hay toggle en la UI): se hace por CLI:
# Habilitar DCS en Azure Databricks
databricks workspace-conf set-status --json '{"enableDcs": "true"}' --profile <tu-profile>
# Verificar que quedó habilitado (tiene que devolver "true")
databricks workspace-conf get-status enableDcs --profile <tu-profile>
# Respuesta esperada:
# {
# "enableDcs": "true"
# }El set-status no devuelve output si funciona — eso es normal. Verificá siempre con el get-status.
Para Standard Compute (Beta): además del paso anterior, ir a Settings → Previews → activar “DCS for Standard Compute”.
Importante: después de habilitar, el tab Docker solo aparece si elegís un access mode compatible:
- Single User o No Isolation Shared → aparece el tab Docker
- Shared o Standard → no aparece (salvo la beta con DBR 18.3+)
- Serverless → no soportado
Si habilitaste todo y seguís sin ver el tab, verificá que tu workspace sea Premium tier.
1. El golden container: inmutabilidad en producción
El caso de uso más potente de DCS es el golden container: una imagen Docker que pasa CI/CD, se escanea por seguridad, y se deploya como el único entorno autorizado para producción.
# golden.Dockerfile
FROM databricksruntime/standard:16.4-LTS
# Dependencias fijas — NUNCA usar pip install sin versiones
RUN /databricks/python3/bin/pip install --no-cache-dir \
pandas==2.2.3 \
scikit-learn==1.5.2 \
great-expectations==1.3.0 \
delta-spark==3.3.0
# Librerías de sistema que pip no puede instalar
RUN apt-get update && apt-get install -y --no-install-recommends \
libgdal-dev \
libgeos-dev \
&& rm -rf /var/lib/apt/lists/*# Build + push
docker build -f golden.Dockerfile -t mi-ecr.amazonaws.com/dbx-golden:v2.1.0 .
docker push mi-ecr.amazonaws.com/dbx-golden:v2.1.0La regla de oro: nunca uses tags :latest en producción. Siempre versioná tus imágenes. Si alguien pushea un :latest nuevo y tu cluster se reinicia, tu job se rompe.
2. Configurar el cluster con Docker
Hay dos formas: UI y API/CLI.
Desde la UI:
- Crear nuevo compute → Advanced Options → Docker tab
- Seleccionar “Use your own Docker container”
- Ingresar la URL de la imagen
- Configurar autenticación (si tu registry es privado)
Desde la API (para automatizar):
El endpoint es POST /api/2.0/clusters/create (referencia):
curl -X POST "https://<tu-workspace>.cloud.databricks.com/api/2.0/clusters/create" \
-H "Authorization: Bearer $DATABRICKS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cluster_name": "prod-golden-container",
"spark_version": "16.4.x-scala2.12",
"docker_image": {
"url": "mi-ecr.amazonaws.com/dbx-golden:v2.1.0",
"basic_auth": {
"username": "{{secrets/docker/user}}",
"password": "{{secrets/docker/pass}}"
}
},
"node_type_id": "i3.xlarge",
"autoscale": {
"min_workers": 1,
"max_workers": 4
}
}'O con la Databricks CLI:
databricks clusters create --json '{
"cluster_name": "prod-golden-container",
"spark_version": "16.4.x-scala2.12",
"docker_image": {
"url": "mi-ecr.amazonaws.com/dbx-golden:v2.1.0",
"basic_auth": {
"username": "{{secrets/docker/user}}",
"password": "{{secrets/docker/pass}}"
}
},
"node_type_id": "i3.xlarge",
"autoscale": {
"min_workers": 1,
"max_workers": 4
}
}'Tip: usá Databricks Secrets para las credenciales del registry. Nunca hardcodees usuarios y passwords en la config del cluster.
3. Dedicated vs Standard Compute: cuándo usar cada uno
Con la llegada de DCS para Standard Compute, ahora tenés dos opciones:
| Dedicated Compute | Standard Compute (Beta) | |
|---|---|---|
| Imagen base | databricksruntime/standard:16.x |
databricksruntime/environment:v5-standard |
| DBR mínimo | Varía | 18.3+ |
| Init scripts | Modifican Python | NO modifican Python |
| Instancias ARM | No soportado | Soportado (Graviton) |
| Aislamiento | Single user / No isolation | Standard (con aislamiento) |
| Libraries UI | Soportado | No soportado |
Mi recomendación:
- Usá Dedicated si necesitás init scripts que modifiquen el entorno Python o si tu DBR es anterior a 18.3.
- Usá Standard si querés compartir un cluster entre varios usuarios con entorno Docker unificado.
4. El error más común: instalar paquetes en el path equivocado
Esto te va a pasar, te lo garantizo. Construís tu imagen, todo verde en local, lanzás el cluster y… tus notebooks no encuentran las librerías.
# MALO — instala en el Python del sistema
RUN pip install pandas==2.2.3
# MALO — crea un virtualenv separado
RUN python -m venv /opt/myenv && /opt/myenv/bin/pip install pandas==2.2.3
# BIEN — usa el Python de Databricks
RUN /databricks/python3/bin/pip install pandas==2.2.3Los notebooks y jobs de Databricks usan /databricks/python3 como intérprete. Si instalás paquetes en otro path, no los van a encontrar.
5. Caso de uso real: pipeline geoespacial con GDAL + Prophet
Donde DCS se vuelve indispensable es cuando necesitás librerías de sistema que no se pueden instalar con pip. Un ejemplo real: un pipeline que cruza datos de delivery con geometrías de zonas y predice demanda por área.
El Dockerfile para este caso:
FROM databricksruntime/standard:16.4-LTS
# Librerías de sistema para geoespacial
RUN apt-get update && apt-get install -y --no-install-recommends \
libgdal-dev \
libgeos-dev \
libproj-dev \
gdal-bin \
&& rm -rf /var/lib/apt/lists/*
# Stack geoespacial + forecasting
RUN /databricks/python3/bin/pip install --no-cache-dir \
geopandas==1.0.1 \
shapely==2.0.6 \
fiona==1.10.1 \
prophet==1.1.6 \
pystan==3.10.0
# Validar que GDAL se linkea bien (esto falla silenciosamente si no)
RUN /databricks/python3/bin/python -c "from osgeo import gdal; print(f'GDAL {gdal.__version__}')"Sin Docker, este setup requiere un init script de ~40 líneas que instala apt packages + compila dependencias de C. Tarda ~8 minutos en cada arranque del cluster y falla 1 de cada 5 veces por timeouts de apt-get. Con Docker, las dependencias ya están bakeadas: el cluster arranca en ~2 minutos y nunca falla por dependencias.
El notebook queda limpio:
# El notebook solo tiene lógica de negocio — cero setup
import geopandas as gpd
from prophet import Prophet
# Leer zonas de delivery desde Unity Catalog
zonas = spark.table("prod.geo.zonas_delivery").toPandas()
geo_zonas = gpd.GeoDataFrame(zonas, geometry=gpd.points_from_xy(zonas.lng, zonas.lat))
# Forecast por zona
for zona_id in geo_zonas["zona_id"].unique():
historico = spark.table("prod.demand.historico") \
.filter(f"zona_id = '{zona_id}'") \
.select("ds", "y").toPandas()
modelo = Prophet(yearly_seasonality=True, weekly_seasonality=True)
modelo.fit(historico)
futuro = modelo.make_future_dataframe(periods=30)
forecast = modelo.predict(futuro)
# Guardar predicciones como Delta table
spark.createDataFrame(forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]]) \
.withColumn("zona_id", lit(zona_id)) \
.write.mode("append") \
.saveAsTable("prod.demand.forecast_por_zona")6. CI/CD: Docker como pieza central del deploy
Donde DCS realmente brilla es cuando lo integrás con tu pipeline de CI/CD. En vez de instalar dependencias en cada arranque (init scripts), las bakeás en la imagen y las testeás antes de llegar a producción:
# .github/workflows/docker-dbx.yml
name: Build & Push Golden Container
on:
push:
paths:
- 'docker/golden.Dockerfile'
- 'docker/requirements.txt'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: |
docker build -f docker/golden.Dockerfile \
-t ${{ secrets.ECR_REGISTRY }}/dbx-golden:${{ github.sha }} .
- name: Test — verificar que los imports funcionan
run: |
docker run --rm ${{ secrets.ECR_REGISTRY }}/dbx-golden:${{ github.sha }} \
/databricks/python3/bin/python -c "
import pandas; import sklearn; import great_expectations
print('All imports OK')
"
- name: Push to ECR
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}
docker push ${{ secrets.ECR_REGISTRY }}/dbx-golden:${{ github.sha }}
- name: Tag como latest-stable
run: |
docker tag ${{ secrets.ECR_REGISTRY }}/dbx-golden:${{ github.sha }} \
${{ secrets.ECR_REGISTRY }}/dbx-golden:latest-stable
docker push ${{ secrets.ECR_REGISTRY }}/dbx-golden:latest-stable7. Gotchas que te van a hacer perder horas
Acá van las trampas que nadie te cuenta en la documentación:
Docker Hub rate limits: si lanzás muchos clusters en poco tiempo (autoescalado agresivo, pools grandes), Docker Hub te va a bloquear. Solución: usá un registry en la misma región y cloud que tu workspace (ECR en AWS, ACR en Azure).
Init scripts en Standard Compute: en Dedicated, los init scripts pueden instalar paquetes Python. En Standard, no. Todo tiene que estar en la imagen Docker. Si venís de usar init scripts para dependencias, tenés que migrar todo al Dockerfile.
Instrucciones de Docker ignoradas: Databricks ignora CMD, ENTRYPOINT, USER, EXPOSE y HEALTHCHECK. No perdás tiempo configurándolas.
No hay DBR for ML: DCS no es compatible con Databricks Runtime for Machine Learning. Si necesitás TensorFlow o PyTorch con GPU, tenés que instalarlos vos en la imagen, incluyendo CUDA y cuDNN.
El tab Docker no aparece: verificá tres cosas: (1) que DCS esté habilitado (en Azure solo por CLI), (2) que el access mode sea Single User o No Isolation Shared, y (3) que tu workspace sea Premium tier. Si falta alguno de los tres, el tab no aparece y no te dice por qué.
8. Cuándo NO usar Docker en Databricks
DCS no es para todos. No lo uses si:
- Tu equipo es chico y las dependencias son simples (un
requirements.txtcon 5 librerías) - No tenés un pipeline de CI/CD para construir y testear imágenes
- Necesitás instalar librerías rápidamente para experimentar (los init scripts o las cluster libraries son más ágiles para exploración)
- Usás Databricks Runtime for ML y no querés reconstruir todo el stack de GPU
Usalo cuando:
- Necesitás reproducibilidad garantizada entre ambientes (dev/staging/prod usan la misma imagen)
- Tenés dependencias de sistema (apt packages, librerías C) que no se pueden instalar con pip
- Querés un entorno bloqueado y aprobado por seguridad
- Tu equipo es grande y los init scripts se volvieron inmantenibles
Checklist de DCS
| Paso | Pregunta | Si no lo hacés… |
|---|---|---|
| Habilitación | DCS está habilitado en tu workspace? (CLI en Azure) | El tab Docker no aparece |
| Access mode | Estás usando Single User o No Isolation Shared? | El tab Docker no aparece |
| Imagen base | Estás extendiendo la imagen oficial de Databricks? | Posibles incompatibilidades con el runtime |
| Path de Python | Instalás en /databricks/python3? |
Notebooks no encuentran tus libs |
| Versionado | Usás tags con versión (no :latest)? |
Builds no reproducibles |
| Registry | Tu registry está en la misma región/cloud? | Arranques lentos + rate limits |
| CI/CD | Testeás los imports antes de pushear? | Clusters que arrancan pero fallan al ejecutar |
| Secrets | Las credenciales del registry están en Databricks Secrets? | Credenciales expuestas en config |
Referencias
- DCS para Dedicated Compute — Azure — documentación oficial, cómo construir imágenes, configurar clusters y autenticación.
- DCS para Standard Compute — Azure — la beta nueva con Spark Connect y soporte para shared compute.
- DCS en GPU compute — Azure — contenedores custom con GPU para deep learning.
- Databricks CLI — workspace-conf — referencia del comando para habilitar DCS por CLI en Azure.
- Databricks Secrets — Azure — para guardar credenciales del registry de forma segura.
- Init scripts — Azure — scripts de inicialización y cómo interactúan con DCS.
- Imágenes base de Databricks — Docker Hub — las imágenes oficiales que deberías extender.
- Dockerfiles de ejemplo — GitHub — los Dockerfiles que usa Databricks internamente para construir sus imágenes base.
Otros posts de la serie
Si te sirvió este post, mirá los anteriores de Databricks Tips:
- Tips #1: Databricks Asset Bundles — patrones avanzados de DABs, variables complejas, deploy multi-target.
- Tips #2: Delta Lake — Liquid Clustering, OPTIMIZE, VACUUM, y las 7 cosas que ojalá te hubieran dicho antes.
- Tips #3: Unity Catalog — modelo de gobernanza, GRANTS heredados, row/column security.
- Tips #4: Structured Streaming — watermarks, triggers, y las trampas del micro-batch.
- Tips #5: MLflow + Unity Catalog — del experimento al modelo en producción.
- Tips #6: Feature Engineering — Feature Store, point-in-time lookups, online features.
Próxima semana: Lakeflow Declarative Pipelines (ex-DLT) — expectations, materialized views y serverless compute.



