Dockerfile: ¿Mi location de EXPOSE es correcta?

Estoy perplejo por una pregunta que recibí cuando trabajaba en un file Docker de código abierto , que se networkinguce a "¿por qué cambiaste las capas?" – Así que estoy tratando de responder eso con mi propia investigación.

Me disculpo por el hecho de que el tema no esté bien definido, pero esencialmente se trata de cómo las capas de docker se relacionan con la docker-caching.

Así que estoy buscando una explicación elegante en un área que no está bien documentada.

Mis cambios del file Docker original donde separar ENV en diferentes capas, mover una COPIA antes y exponer el puerto más tarde.

El original (simplificado):

FROM ubuntu:latest EXPOSE 80 ENV HELLO world \ && DOCKER whale RUN # Run stuff COPY source /to/container CMD # Do stuff 

Mis cambios:

 FROM ubuntu:latest ENV HELLO world ENV DOCKER whale # <-- Separate ENV into different layers COPY source /to/container # <-- Less prone to change, move earlier RUN # Run stuff EXPOSE 80 # <-- "Bake in" port later CMD # Do stuff 

Presunción

Tengo entendido que, desde una perspectiva de docker-cache, separar las variables ENV en diferentes capas es una buena práctica porque , si un usuario desea anular una ENV, solo una ENV debe cambiar dentro de su propia capa , en lugar de alterarla. toda la capa que contiene todas las ENV por el bien de una.

Pero agregar el puerto EXPOSE más tarde – se siente bien. Esto se debe a que he usado Docker durante aproximadamente 18 meses, y casi todos los documentos y guías de Docker exponen el puerto más adelante en el file Docker.

También estoy convencido de que esto se basa en mi experiencia (y asistir a DockerCon2017 y participar en algunas classs de "mejores prácticas") que las capas más propensas a cambios / anulaciones deben ubicarse más adelante en un Dockerfile , para optimizar mejor el docker-caching para que haya no hay tantas variaciones de capa de bajo nivel.

Pregunta:

¿Es correcta mi creencia (o tonta) suponiendo que separar las capas ENV, mover COPY antes y colocar EXPOSE capas más tarde es una buena práctica y es una mejora general sobre las capas originales de Dockerfile desde la perspectiva de optimizar el caching Docker?

Si bien esta pregunta tiene algunas respuestas muy dogmáticas, intentaré atenerme a los hechos y otras cosas extraídas de los documentos de Docker sobre este tema.

La capa adecuada de capas en la window acoplable tiene esencialmente tres objectives (orderados aproximadamente):

  1. corrección: algunas cosas deben combinarse / orderarse para ser correctas (por ejemplo, las operaciones apt siempre deben comenzar con apt-get update && ... y la apt-get update nunca debe estar en una capa RUN separada)
  2. minimizar capas: pocas capas generalmente significan un mejor performance tanto para la compilation como para el time de ejecución. Esto generalmente significa combinar capas cuando sea posible
  3. performance de la memory caching: presione las capas que se pueden almacenar en caching lo más arriba posible en el file, tenga en count que si una capa se invalida, todas las capas posteriores a esa capa también se invalidan

Dado que, aquí hay algunas observaciones de las cosas que ha propuesto:

separando capas ENV

Dado (2) arriba, debe mantener las capas ENV combinadas cuando sea posible. Los usuarios pueden anular --env en el time de ejecución, lo que no afecta a las capas de time de compilation. Sí, si una de las líneas ENV se modificó en la fuente, invalidaría el rest del file (3) pero, en general, se canjea por motivos de performance .

moviendo COPY hacia arriba

en general, esta no es una buena idea, la fuente en el disco es una de las cosas más probables de cambiar, si la fuente cambia, todas las capas de la capa COPY hacia abajo quedan invalidadas

mover EXPOSE

Esto realmente no importa. EXPOSE es una capa casi trivial (de hecho, no hace nada a less que estés vinculando contenedores). Como es almacenable en caching, lo pondría cerca de la cima, pero una vez más, es trivial de calcular y realmente no cambia.

resumen

tl; dr El responsable es correcto al decir que no a los tres cambios, ya que empeorará el performance de compilation y ejecución.