{"id":1170,"date":"2026-03-11T15:20:18","date_gmt":"2026-03-11T18:20:18","guid":{"rendered":"https:\/\/maurobernal.com.ar\/blog\/?p=1170"},"modified":"2026-03-11T20:02:17","modified_gmt":"2026-03-11T23:02:17","slug":"como-escribir-dockerfiles-buenas-practicas-ejemplos","status":"publish","type":"post","link":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/","title":{"rendered":"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza"},"content":{"rendered":"\n<p class=\"intro-destacado\">Mi primer Dockerfile ocupaba 2.1 GB. No exagero. Usaba una imagen base de Ubuntu completa, instalaba todo lo que se me ocurr\u00eda por las dudas, y copiaba el c\u00f3digo sin pensar en las capas. Hoy mis im\u00e1genes de producci\u00f3n pesan entre 60 y 120 MB. Este art\u00edculo es ese camino condensado.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">El Dockerfile: instrucciones para construir una imagen<\/h2>\n\n\n\n<p>Un Dockerfile es un archivo de texto con instrucciones que Docker ejecuta en orden para construir una imagen. Cada instrucci\u00f3n crea una nueva capa. Las capas se cachean, lo que hace que los builds sucesivos sean r\u00e1pidos \u2014 <em>si sab\u00e9s ordenarlas bien<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Las instrucciones esenciales<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># Instrucciones que uso en casi todos mis Dockerfiles:\n\nFROM        # imagen base (siempre es la primera instrucci\u00f3n)\nWORKDIR     # directorio de trabajo dentro del contenedor\nCOPY        # copia archivos del host al contenedor\nRUN         # ejecuta un comando durante el build\nENV         # variables de entorno\nEXPOSE      # documenta el puerto que usa el contenedor\nENTRYPOINT  # comando principal del contenedor\nCMD         # argumentos por defecto del entrypoint<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Mi primer Dockerfile real: una API .NET 8<\/h2>\n\n\n\n<p>Cuando tuve que dockerizar mi primera API .NET en el trabajo, empec\u00e9 con algo que funcionaba pero era terrible. Luego aprend\u00ed a hacerlo bien.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">La versi\u00f3n ingenua (no hagas esto)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># &#x274c; Dockerfile ingenuo - imagen de 2GB+\nFROM ubuntu:22.04\n\nRUN apt-get update && apt-get install -y     wget curl git vim     dotnet-sdk-8.0\n\nWORKDIR \/app\nCOPY . .\nRUN dotnet build -c Release\n\nEXPOSE 80\nCMD [\"dotnet\", \"run\", \"--project\", \"MiApi\"]<\/code><\/pre>\n\n\n\n<p>Problemas de esta versi\u00f3n: imagen base enorme, herramientas de desarrollo en producci\u00f3n, SDK completo en runtime, <code>dotnet run<\/code> en lugar de un ejecutable publicado, y sin usuario no-root.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">La versi\u00f3n con multi-stage build (la forma correcta)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># &#x2705; Dockerfile con multi-stage build - imagen de ~80MB\n# STAGE 1: Build\nFROM mcr.microsoft.com\/dotnet\/sdk:8.0 AS build\nWORKDIR \/src\n\n# Copiar solo el .csproj primero (aprovecha cache de capas)\nCOPY [\"src\/MiApi\/MiApi.csproj\", \"src\/MiApi\/\"]\nRUN dotnet restore \"src\/MiApi\/MiApi.csproj\"\n\n# Ahora copiar el resto del c\u00f3digo\nCOPY . .\nWORKDIR \"\/src\/src\/MiApi\"\nRUN dotnet build \"MiApi.csproj\" -c Release -o \/app\/build\n\n# STAGE 2: Publish\nFROM build AS publish\nRUN dotnet publish \"MiApi.csproj\" -c Release -o \/app\/publish     \/p:UseAppHost=false\n\n# STAGE 3: Runtime (imagen final - solo lo necesario)\nFROM mcr.microsoft.com\/dotnet\/aspnet:8.0 AS final\nWORKDIR \/app\n\n# Usuario no-root\nRUN adduser --disabled-password --gecos \"\" appuser\nUSER appuser\n\nCOPY --from=publish \/app\/publish .\nEXPOSE 80\nENTRYPOINT [\"dotnet\", \"MiApi.dll\"]<\/code><\/pre>\n\n\n\n<p>La magia del multi-stage: la imagen final solo contiene el runtime de ASP.NET y el binario publicado. Todo el SDK, las herramientas de build y el c\u00f3digo fuente quedan afuera. El resultado: de 2.1 GB a 82 MB.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3mo funcionan las capas (y por qu\u00e9 importa el orden)<\/h2>\n\n\n\n<p>Cada instrucci\u00f3n <code>RUN<\/code>, <code>COPY<\/code> o <code>ADD<\/code> crea una capa nueva. Docker cachea cada capa y solo reconstruye las que cambiaron <em>y todas las que vienen despu\u00e9s<\/em>. Esta regla cambia completamente c\u00f3mo orden\u00e1s las instrucciones.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># &#x274c; Orden incorrecto: cualquier cambio en el c\u00f3digo invalida el restore\nCOPY . .                              # capa 1 - se invalida con cada cambio\nRUN dotnet restore                    # capa 2 - se repite innecesariamente\n\n# &#x2705; Orden correcto: restore se cachea hasta que cambie el .csproj\nCOPY [\"MiApi.csproj\", \".\"]           # capa 1 - solo cambia si el proyecto cambia\nRUN dotnet restore                    # capa 2 - se cachea\nCOPY . .                              # capa 3 - cambia con el c\u00f3digo\nRUN dotnet build -c Release           # capa 4 - solo se repite si hay cambios<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Buenas pr\u00e1cticas que aplico en todos mis Dockerfiles<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Siempre usar im\u00e1genes base espec\u00edficas, nunca :latest<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># &#x274c; Impredecible en producci\u00f3n\nFROM node:latest\nFROM python:latest\n\n# &#x2705; Reproducible y auditable\nFROM node:20.11.0-alpine3.19\nFROM python:3.12.2-slim-bookworm<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Preferir im\u00e1genes Alpine o Slim<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># node:20-alpine:   ~55 MB\n# node:20-slim:    ~180 MB\n# node:20:         ~1.1 GB\nFROM node:20-alpine<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Combinar comandos RUN para reducir capas<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># &#x274c; Tres capas separadas\nRUN apt-get update\nRUN apt-get install -y curl\nRUN rm -rf \/var\/lib\/apt\/lists\/*\n\n# &#x2705; Una sola capa, sin cache de apt\nRUN apt-get update && apt-get install -y     curl     && rm -rf \/var\/lib\/apt\/lists\/*<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. El .dockerignore es tan importante como el .gitignore<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># .dockerignore\n**\/bin\/\n**\/obj\/\n**\/.git\/\n**\/node_modules\/\n**\/*.log\n.env\n.env.local\ndocker-compose*.yml\nREADME.md<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">5. Nunca hardcodear secretos en el Dockerfile<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># &#x274c; NUNCA - queda grabado en la capa para siempre\nENV DB_PASSWORD=mipassword123\nRUN curl -H \"Authorization: Bearer TOKEN_SECRETO\" https:\/\/api.ejemplo.com\n\n# &#x2705; Pasar en runtime como variables de entorno\ndocker run -e DB_PASSWORD=$DB_PASSWORD mi-imagen<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Comandos esenciales para construir y gestionar im\u00e1genes<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Construir imagen\ndocker build -t mi-api:1.0.0 .\ndocker build -t mi-api:1.0.0 -f Dockerfile.prod .  # Dockerfile espec\u00edfico\ndocker build --no-cache -t mi-api:latest .           # Forzar rebuild completo\n\n# Etiquetar\ndocker tag mi-api:1.0.0 mi-api:latest\ndocker tag mi-api:1.0.0 miregistry.local\/mi-api:1.0.0\n\n# Ver capas y tama\u00f1o\ndocker history mi-api:1.0.0\ndocker images mi-api\n\n# Limpiar im\u00e1genes no usadas\ndocker image prune -a  # elimina todas las im\u00e1genes sin contenedor activo<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">El resultado: de 2.1 GB a 82 MB<\/h2>\n\n\n\n<p>Con el multi-stage build, una imagen base correcta, el orden de capas optimizado y el .dockerignore configurado, pas\u00e9 de im\u00e1genes que tardaban 8 minutos en buildearse y ocupaban gigabytes, a im\u00e1genes que buildean en 90 segundos (o 20 segundos con cache) y pesan menos de 100 MB. En producci\u00f3n, eso se traduce en deploys m\u00e1s r\u00e1pidos, menos espacio en el registry y menor superficie de ataque.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><em>\u2190 <a href=\"https:\/\/maurobernal.com.ar\/blog\/blog\/kubernetes\/arquitectura-interna-de-docker-engine-daemon-imagenes\/\">Art\u00edculo anterior: Arquitectura interna de Docker<\/a> | <strong>Serie Docker Completo<\/strong> | Pr\u00f3ximo: Ciclo de vida de contenedores \u2192<\/em><\/p>\n\n\n<hr class=\"wp-block-separator\"\/>\n<p><em>\u2190 <a href=\"https:\/\/maurobernal.com.ar\/blog\/blog\/kubernetes\/arquitectura-interna-de-docker-engine-daemon-imagenes\/\">Art\u00edculo anterior: Por dentro del motor: entendiendo la arquitectura de Docker<\/a> | <strong>Serie Docker Completo<\/strong> | Pr\u00f3ximo: <a href=\"https:\/\/maurobernal.com.ar\/blog\/blog\/kubernetes\/ciclo-de-vida-contenedor-docker-run-comandos-esenciales\/\">docker run y todo lo que nadie te explica del ciclo de vida de un contenedor \u2192<\/a><\/em><\/p>","protected":false},"excerpt":{"rendered":"<p>De un Dockerfile de 2GB a im\u00e1genes de 80MB: multi-stage builds, capas optimizadas, .dockerignore y buenas pr\u00e1cticas reales para .NET y m\u00e1s.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[233],"tags":[242,240,248,249,215,250],"class_list":["post-1170","post","type-post","status-publish","format-standard","hentry","category-kubernetes","tag-devops","tag-docker","tag-dockerfile","tag-layers","tag-linux","tag-multistage"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza &#183; devops Mauro Bernal<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza &#183; devops Mauro Bernal\" \/>\n<meta property=\"og:description\" content=\"De un Dockerfile de 2GB a im\u00e1genes de 80MB: multi-stage builds, capas optimizadas, .dockerignore y buenas pr\u00e1cticas reales para .NET y m\u00e1s.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/\" \/>\n<meta property=\"og:site_name\" content=\"devops Mauro Bernal\" \/>\n<meta property=\"article:published_time\" content=\"2026-03-11T18:20:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-11T23:02:17+00:00\" \/>\n<meta name=\"author\" content=\"Mauro Bernal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:site\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mauro Bernal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/\"},\"author\":{\"name\":\"Mauro Bernal\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"headline\":\"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza\",\"datePublished\":\"2026-03-11T18:20:18+00:00\",\"dateModified\":\"2026-03-11T23:02:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/\"},\"wordCount\":453,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"keywords\":[\"devops\",\"docker\",\"dockerfile\",\"layers\",\"linux\",\"multistage\"],\"articleSection\":[\"Kubernetes\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/\",\"name\":\"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza &#183; devops Mauro Bernal\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\"},\"datePublished\":\"2026-03-11T18:20:18+00:00\",\"dateModified\":\"2026-03-11T23:02:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/como-escribir-dockerfiles-buenas-practicas-ejemplos\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\",\"name\":\"devops Mauro Bernal\",\"description\":\"Cuando tu trabajo es hacer que las cosas funcionen bien...\",\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\",\"name\":\"Mauro Bernal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"width\":1740,\"height\":1740,\"caption\":\"Mauro Bernal\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\"},\"description\":\"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman\",\"sameAs\":[\"https:\\\/\\\/maurobernal.com.ar\",\"https:\\\/\\\/x.com\\\/_maurobernal\",\"https:\\\/\\\/youtube.com\\\/maurobernal\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza &#183; devops Mauro Bernal","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/","og_locale":"es_ES","og_type":"article","og_title":"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza &#183; devops Mauro Bernal","og_description":"De un Dockerfile de 2GB a im\u00e1genes de 80MB: multi-stage builds, capas optimizadas, .dockerignore y buenas pr\u00e1cticas reales para .NET y m\u00e1s.","og_url":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/","og_site_name":"devops Mauro Bernal","article_published_time":"2026-03-11T18:20:18+00:00","article_modified_time":"2026-03-11T23:02:17+00:00","author":"Mauro Bernal","twitter_card":"summary_large_image","twitter_creator":"@_maurobernal","twitter_site":"@_maurobernal","twitter_misc":{"Escrito por":"Mauro Bernal","Tiempo de lectura":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/#article","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/"},"author":{"name":"Mauro Bernal","@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"headline":"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza","datePublished":"2026-03-11T18:20:18+00:00","dateModified":"2026-03-11T23:02:17+00:00","mainEntityOfPage":{"@id":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/"},"wordCount":453,"commentCount":0,"publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"keywords":["devops","docker","dockerfile","layers","linux","multistage"],"articleSection":["Kubernetes"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/","url":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/","name":"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza &#183; devops Mauro Bernal","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#website"},"datePublished":"2026-03-11T18:20:18+00:00","dateModified":"2026-03-11T23:02:17+00:00","breadcrumb":{"@id":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/maurobernal.com.ar\/blog\/como-escribir-dockerfiles-buenas-practicas-ejemplos\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/maurobernal.com.ar\/blog\/"},{"@type":"ListItem","position":2,"name":"Mi gu\u00eda para escribir Dockerfiles que no me den verg\u00fcenza"}]},{"@type":"WebSite","@id":"https:\/\/maurobernal.com.ar\/blog\/#website","url":"https:\/\/maurobernal.com.ar\/blog\/","name":"devops Mauro Bernal","description":"Cuando tu trabajo es hacer que las cosas funcionen bien...","publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/maurobernal.com.ar\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":["Person","Organization"],"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283","name":"Mauro Bernal","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","url":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","contentUrl":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","width":1740,"height":1740,"caption":"Mauro Bernal"},"logo":{"@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1"},"description":"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman","sameAs":["https:\/\/maurobernal.com.ar","https:\/\/x.com\/_maurobernal","https:\/\/youtube.com\/maurobernal"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/comments?post=1170"}],"version-history":[{"count":4,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1170\/revisions"}],"predecessor-version":[{"id":1245,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1170\/revisions\/1245"}],"wp:attachment":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/media?parent=1170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/categories?post=1170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/tags?post=1170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}