Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de Docker

Curso de Docker

Guido Vilariño

Guido Vilariño

Multi-stage build

30/32
Recursos

Aportes 20

Preguntas 7

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Multiples fases con un solo DockerFile

# Define una "stage" o fase llamada builder accesible para la siguiente fase
FROM node:12 as builder
# copiamos solo los archivos necesarios
COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src
# Instalamos solo las dependencias para Pro definidas en package.json
RUN npm install --only=production

COPY [".", "/usr/src/"]
# instalamos dependencias de desarrollo
RUN npm install --only=development

# Pasamos los tests
RUN npm run test
## Esta imagen esta creada solo para pasar los tests.

# Productive image
FROM node:12

COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src
# instar las dependencias de PRO
RUN npm install --only=production

# Copiar  el fichero de la imagen anterior.
# De cada stage se reutilizan las capas que son iguales.
COPY --from=builder ["/usr/src/index.js", "/usr/src/"]
# Pone accesible el puerto
EXPOSE 3000

CMD ["node", "index.js"]
### En tiempo de build en caso de que algún paso falle, el build se detendrá por completo.

AQUÍ LO QUE YO ENTENDÍ

  • El Dockerfile de producción contiene 2 “fases de build” que se pueden pensar como hacer 2 build seguidos, en donde al final la imagen construida contendrá lo especificado en el ultimo de los build.

  • El primer build corre 1 test que verifica que todo funcione bien
    El segundo build construye la imagen final aprovechando el caché de las capas del primer build.

  • Al final el 2do build es solo una extracción de lo que nos interza del primer build.

  • Lo importante en este caso especifico es que si el test falla, entonces el build 2 no se corre, lo que significa que la imagen no se construye.

Comandos:
$ docker build -t prodapp -f Dockerfile . (ahora le especifíco el Dockerfile)
$ docker run -d --name prod prodapp

Les comparto un articulo donde describen las Desventajas de usar Docker muy interesante para que lo puedan tomar en cuenta https://es.quora.com/Cuáles-son-las-desventajas-de-usar-Docker?share=1

Un fragmento de ese articulo es: “Los contenedores dockers están diseñados para ser “eficientes” del punto de vista del consumo de recursos o traducido al español (que sean baratitos baratitos y puedas menter un mogollón de ellos en un mismo lugar) para eso los inventaron a fin de cuenta, para hacer más masivo lo que con máquinas virtuales ya era bastante masivo y ganar un pastón a costa de quebradero de cabeza de otros.”

Entendido súper eso voy a revisar como hacer deploy de una app de django siempre uso docker para dev pero seria bueno usar el multi stage para prod

Hubiera sido bueno un Multi-stage con docker-compose también. Creo que para proyectos grandes terminaremos usando docker-compose que el Dockerfile

Cuando no queres que codigo de desarrollo este en la imagen, unicamente queremos que esten archivos de produccion estos pueden ser binarios de ejecucion o en caso de nodejs (index.js, node_modules, package.json y package-lock.json)

nano development.Dockerfile
############development.Dockerfile############

FROM node:12

COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src

RUN npm install

COPY [".", "/usr/src/"]

EXPOSE 3000

CMD ["npx", "nodemon", "index.js"]

################################################
nano build/production.Dockerfile
############production.Dockerfile############

FROM node:12 as builder

COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src

RUN npm install --only=production

COPY [".", "/usr/src/"]

RUN npm install --only=development

RUN npm run test


# Productive image
FROM node:12

COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src

RUN npm install --only=production

COPY --from=builder ["/usr/src/index.js", "/usr/src/"]

EXPOSE 3000

CMD ["node", "index.js"]

################################################
docker build -t prodapp -f build/production.Dockerfile .

docker image ls

docker run -d --name prod prodapp 

docker exec -it prod bash

# ls -lac
# docker ps
# exit

– Experimentamos editando el archivo test/test.js para que falle, comprobamos que fallara el layer falla y se detiene el build

docker build -t prodapp -f build/production.Dockerfile .

Esto es muy parecido o análogo a lo que ocurre con los procesos CD/CI en un clásico ambiente DevOps. Muy interesante.

Con:

docker build --target builder -t prodapp .

puedes especificar una de las fases en especifico.
https://docs.docker.com/develop/develop-images/multistage-build/

Multi-stage buildComandos:
$ docker build -t prodapp -f Dockerfile . (ahora le especifíco el Dockerfile)
$ docker run -d --name prod prodapp

Multiples fases con un solo DockerFile
# Define una "stage" o fase llamada builder accesible para la siguiente fase
FROM node:12 as builder # copiamos solo los archivos necesarios
COPY ["package.json", "package-lock.json", "/usr/src/"]
WORKDIR /usr/src # Instalamos solo las dependencias para Pro definidas en package.json
RUN npm install --only=production
COPY [".", "/usr/src/"] # instalamos dependencias de desarrollo
RUN npm install --only=development # Pasamos los tests
RUN npm run test ## Esta imagen esta creada solo para pasar los tests. 
# Productive image
FROM node:12
COPY ["package.json", "package-lock.json", "/usr/src/"]
WORKDIR /usr/src# instar las dependencias de 
PRORUN npm install --only=production
# Copiar el fichero de la imagen anterior.
# De cada stage se reutilizan las capas que son iguales.
COPY --from=builder ["/usr/src/index.js", "/usr/src/"] # Pone accesible el puerto
EXPOSE 3000
CMD ["node", "index.js"]   ### En tiempo de build en caso de que algún paso falle, el build se detendrá por completo

Duplicar comandos en el Dockerfile es util para reutilizar capas usando cache y optimizar la velocidad de build

que curso tan completo, nos muestra como optimizar nuestras img segun sea la necesidad de correr en dev or prod

Entendiendoooo

# Define una "stage" o fase llamada builder accesible para la siguiente fase
FROM node:12 as builder
# copiamos solo los archivos necesarios
COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src
# Instalamos solo las dependencias para Pro definidas en package.json
RUN npm install --only=production

COPY [".", "/usr/src/"]
# instalamos dependencias de desarrollo
RUN npm install --only=development

# Pasamos los tests
RUN npm run test
## Esta imagen esta creada solo para pasar los tests.

# Productive image
FROM node:12

COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src
# instar las dependencias de PRO
RUN npm install --only=production

# Copiar  el fichero de la imagen anterior.
# De cada stage se reutilizan las capas que son iguales.
COPY --from=builder ["/usr/src/index.js", "/usr/src/"]
# Pone accesible el puerto
EXPOSE 3000

CMD ["node", "index.js"]
### En tiempo de build en caso de que algún paso falle, el build se detendrá por completo.

funcionalidad para tener una opción de desarrollador y otra opción ya en producción

Genial!

Muy interesante

🤯

  • Los multistage build en docker, nos permite crear imágenes de build y test, previas a la imagen que usaremos para la publicación de nuestro servicio.