El build context es el conjunto de archivos, directorios y metadata que el builder puede utilizar como entrada para una construcción. La ruta al final de no es un detalle decorativo:
docker build
Bash
docker build -t my-api .
El punto indica que el directorio actual es el contexto. Las instrucciones COPY y ADD no pueden leer arbitrariamente cualquier archivo del equipo; trabajan dentro de esa frontera y respetan las exclusiones definidas.
Controlar el contexto mejora velocidad, seguridad, cache y claridad. Un Dockerfile correcto con un contexto descuidado puede enviar credenciales, dependencias, outputs y gigabytes innecesarios al builder.
El Dockerfile está en docker/, pero el contexto continúa siendo .. Las rutas de COPY se interpretan respecto al contexto, no respecto a la ubicación del Dockerfile.
Esto suele confundirse:
docker
COPY ../package.json ./
No permite escapar del contexto. Debes elegir un contexto que contenga el archivo o reorganizar la construcción.
En un monorepo, el root puede servir como contexto para acceder a paquetes compartidos. Sin embargo, implica que todo el repository puede participar como input salvo exclusión.
No copies esta lista ciegamente. Por ejemplo, excluir dist es correcto si compilas dentro de la imagen, pero incorrecto si el pipeline construye dist previamente y la imagen debe copiarlo.
El orden importa: una regla posterior puede negar una exclusión anterior cuando los directorios padres permiten alcanzar el archivo.
Los detalles de matching deben verificarse con la documentación y versión utilizada. No asumas que funciona exactamente como .gitignore en todos los casos.
Las instrucciones COPY calculan cache a partir del contenido y metadata relevante de sus inputs. Un contexto amplio no siempre invalida todo por sí mismo, pero COPY . . convierte muchos archivos en dependencias del paso.
Ejemplo frágil:
docker
COPY . .
RUN npm ci
Cambiar README, cobertura o un log puede invalidar instalación.
Ejemplo enfocado:
docker
COPY package.json package-lock.json ./
RUN npm ci
COPY src ./src
Ahora cada instrucción declara inputs más pequeños. .dockerignore elimina ruido antes de que llegue al grafo.
El pipeline genera un directorio con únicamente manifests, source y paquetes requeridos. Aporta control, pero introduce un paso adicional que también debe ser reproducible.
El Dockerfile puede consumir el contexto nombrado según las capacidades del frontend. Esto separa fronteras, aunque aumenta complejidad y requiere tooling moderno.
La decisión debe optimizar comprensión y cache, no solo hacer que COPY deje de fallar.
autenticación puede exponerse si se usa incorrectamente;
submodules y Git LFS agregan dependencias;
el build depende de disponibilidad de la fuente;
archivos no versionados locales no existen.
Fija commits, no branches móviles, cuando necesites reproducibilidad. Usa SSH o secret mounts soportados para acceso privado, nunca keys copiadas al Dockerfile.
Flujos modernos pueden usar archivos de ignore asociados a Dockerfiles específicos, según las capacidades y convenciones soportadas, para diferenciar un build de desarrollo, lint o producción.
FROM node:22-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY src ./src
COPY test ./test
RUN npm test
FROM node:22-slim AS runtime
ENV NODE_ENV=production
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
COPY --from=build /app/src ./src
USER node
CMD ["node", "src/server.js"]
El builder puede necesitar leerlo para la construcción aunque no quede disponible para copiar dentro de la imagen. No dependas de copiar Dockerfile al runtime.
Un symlink dentro del contexto no debe utilizarse como mecanismo para escapar y copiar contenido arbitrario exterior. Verifica cómo el builder resuelve y valida enlaces.
El contexto representa los inputs capturados por la operación. No diseñes un proceso donde otro comando modifica archivos concurrentemente esperando resultados deterministas.
Crea temporalmente un archivo con un nombre sensible y confirma que no aparece en el contexto consumido ni en la imagen. No uses credenciales reales para la prueba.
Modifica README, luego source y después lockfile. Observa qué pasos se invalidan. El patrón correcto debe reflejar la dependencia real de cada instrucción.