Cómo Dockerize tus aplicaciones de Python | Max S | Skillshare
Buscar

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Cómo Dockerize tus aplicaciones de Python

teacher avatar Max S, Power through programming

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción del curso

      1:34

    • 2.

      Docker Intro

      9:28

    • 3.

      Creación de un archivo Docker

      35:45

    • 4.

      Construción en múltiples etapas

      21:46

    • 5.

      Docker Compone

      32:40

    • 6.

      Makefile

      12:21

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

123

Estudiantes

--

Proyecto

Acerca de esta clase

En esta clase aprenderás a usar tu código Python existente y lanzarlo como contenedor de docker, tanto con docker como con composición de docker.

Docker es una tecnología muy común e importante para usar en tu carrera de ingeniería de software. Te ayuda a crear imágenes de tus aplicaciones que tienen un estado reproducible, lo que significa que puedes estar seguro de que si se ejecuta en tu máquina, se ejecutará con alguien más y en la

state, también te hace que sea muy fácil usar el software existente, ya que puedes crear una base de datos de Postgres o una caché de Redis sin ningún trabajo extra con el solo uso de esa imagen de docker.

Esto simplifica todo el desarrollo, ya que puedes reproducir la configuración de producción en tu entorno local, lo que significa que puedes desarrollar y probar tu aplicación mucho

better.You seguir el código en GitHub aquí: https://github.com/codingwithmax/PythonTutorialFastAPI/tree/58CreatingADockerfile

Conoce a tu profesor(a)

Teacher Profile Image

Max S

Power through programming

Profesor(a)

Habilidades relacionadas

Desarrollo Herramientas de desarrollo Docker
Level: Beginner

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción del curso: Hola, es max y bienvenido a mi curso sobre como ojos oscuros tus aplicaciones Python. Ahora, como sabe cualquier desarrollador de software, más oscuro juega un papel muy importante en tu carrera de desarrollo de software porque te permite sentirte seguro de que lo que tengas localmente es en realidad lo mismo. Y va a funcionar de la misma manera en una máquina diferente también, también en la Nube y en un entorno de producción. Además, también te va a proporcionar muchas herramientas realmente agradables para hacer girar fácilmente diferentes imágenes para que tengas todo tipo de software fácilmente disponible. Pero queremos ser capaces de asegurarnos de que usamos más oscuro correctamente. Y así en este curso vamos a aprender los conceptos básicos de cómo escribir tu primer archivo Docker, cómo hacer una compilación multietapa, y también cómo usar docker-componer para que puedas tomar tu aplicación Python realmente cualquier otro código que hubiera. Pero en este caso solo nos estamos enfocando en Python y realmente ejecutarlo usando Docker construyendo la imagen Docker y luego ejecutando el contenedor Docker, tanto a través de los comandos regulares de Docker como así como también sobre Docker Compose. Ahora bien, este curso es en realidad parte de una serie Python más grande. Aprenderemos a construir una aplicación Python completa desde cero. Pero en este caso, sólo vamos a enfocarnos sólo en la parte más oscura. Y así el código que vamos a usar es de esta serie de Python más grande. Y en realidad podrás acceder a eso usando el enlace de GitHub a continuación en la descripción del curso. Sin embargo, obviamente también puedes usar tu propio código Python para los mismos fines. O puedes usar el código que ya está en GitHub si quieres. De cualquier manera, también encontrarás cada una de estas lecciones como diferentes sucursales de GitHub y ese repositorio GitHub a continuación. Entonces, si quieres seguir junto con el código, asegúrate de verificarlo también por ahí. Entonces sin más preámbulos, te veré dentro y feliz aprendiendo. 2. Docker Intro: Bien, entonces en esta sección, vamos a empezar a aprender sobre Docker y vamos a integrar más oscuro en nuestra aplicación. Ahora, el Dr. es un programa realmente genial y de hecho te recomendaría solo Google download docker o simplemente ve a esta URL aquí, docker.com slash productos slash Docker Desktop. Y para mí, porque estoy en una Mac, me va a dar las opciones de Mac. Pero si estás en un Windows o Linux, será predeterminado a esos y solo asegúrate de seguir adelante y descargarlos porque son un par de cientos de megabytes. Por lo que puede tardar un par de minutos en descargarse. Ya he seguido adelante y he hecho esto. Entonces sí. Para Docker, docker es realmente agradable porque nos ayuda a resolver otro tipo de problema que ya empezamos a resolver cuando estábamos hablando de entornos virtuales. Entonces, si recuerdas volver a los entornos virtuales, o la principal motivación fue que queremos asegurarnos de que tenemos todo consistente. Y en cierto sentido un poco aislado para todos los paquetes Python que necesitamos. Entonces, por ejemplo, si nuestra aplicación necesita una API rápida para ejecutarse, queremos asegurarnos de que todos los que intenten ejecutar nuestro código tengan FastAPI instalado, así como todas las demás cosas que también necesitan para ejecutar esto aplicación. Y que no les está diciendo como, Oh oye, te estás perdiendo esta instalación, te estás perdiendo esa instalación, o están tratando de usar las instalaciones locales. Y luego hay un desajuste de versión, por ejemplo, estamos usando alguna versión como no sé, como diez puntos lo que sea. Y están usando versión como nueve puntos lo que sea. Y hay un desajuste de versión. Entonces todas esas cosas son cosas que hemos tratado de abordar usando entornos virtuales. Y es genial y ha sido extremadamente útil. Pero en realidad hay más que podemos hacer con esto para que esto sea aún más consistente. Y la idea aquí es que con más oscuros, podamos crear Contenedores aislados. Entonces, esencialmente, solo piensa en ello como una caja que podemos construir desde cero, incluido el sistema operativo. Y sabemos que no importa a dónde vaya a correr esto, si le damos las instrucciones adecuadas, se verá igual en todas partes. Y ahora tal vez te estés preguntando, por qué querríamos hacer eso suena un poco como exageración. Bueno, en realidad, hay ciertos escenarios y me he encontrado con esto en realidad yo mismo varias veces donde puedes instalar algo en una Mac y puede que no funcione correctamente, o puede funcionar de manera diferente en una Linux, o las cosas están funcionando en un Linux de una manera funcionan una manera diferente y luego funcionan en Windows como una tercera forma. O también tienes ya instaladas cosas locales que quizás hayas olvidado porque las has instalado como hace seis meses o hace un año o dos años. Y entonces alguien más intenta ejecutar tu código y están como, Oye, estas cosas no están funcionando. Y es solo porque hay algunas cosas que instalaste que te olvidaste que no tienen. Y así usar Docker nos ayuda a abordar todos estos problemas. Y en realidad hay muchas más cosas geniales que podemos hacer con eso que veremos en el futuro. Pero ahora mismo vamos a enfocarnos. En primer lugar, solo usar Docker para crear esencialmente una caja extremadamente limpia que contenga nuestra aplicación que no importa dónde se ejecute, será consistente. Y en realidad Docker se usa en todo el mundo que cuando estás desplegando código, normalmente estarás desplegando ese código como una imagen de Docker que se ejecutará en alguna parte. Así que sí, más oscuro, muy importante para que eso realmente nos ayude a obtener todo consistente desde la base hacia arriba, de tener el mismo sistema operativo que se ejecuta en las mismas versiones del lenguaje de programación R, lo mismo, y luego usar nuestros entornos virtuales para instalar paquetes consistentes. Y así solo queremos asegurarnos de que todo sea igual sin importar dónde lo ejecutes y más oscuro nos va a permitir hacerlo. Y es extremadamente, extremadamente útil porque entonces nunca tienes que preocuparte por oh, hubo algo que olvidé que también hay que instalar que tengo instalado o hay algunos variable de entorno que configuré que quizás me haya olvidado? O, ya sabes, todo este tipo de rarezas raras que pueden surgir. Y luego sobre todo lidiando con problemas como, Whoa, ¿por qué no funciona en tu máquina? Está funcionando bien en mi máquina. ¿Instalaste las cosas del entorno virtual correctamente? Sí, lo hiciste. Bien. Eso es raro. Como ¿por qué está funcionando en mi máquina y en la suya? Darker nos va a ayudar a paliar todos estos problemas. Y luego, como veremos más adelante, en realidad hay algunas cosas más interesantes que podemos hacer que te harán la vida mucho más fácil con Docker, por ejemplo, también como hacer girar una base de datos que podamos usar o haciendo girar un efectivo que podamos usar. Y un montón de cosas geniales por venir. Pero nos enfocaremos en solo aislar primero nuestra aplicación para que podamos darle esta imagen a alguien y luego ellos puedan ejecutarla y ellos obtendrán exactamente lo mismo que estamos viendo de nuestro lado. Entonces sí, con eso, recomendaría solo Google, descarga docker Desktop y tu buscador favorito o ve a esta web aquí, que puede cambiar con el tiempo, probablemente no, pero docker.com slash productos slash Docker Desktop. Y luego solo sigue adelante y descarga la versión más oscura para ti. Otra vez, ya lo hice. Entonces para mí, cuando desempaque la imagen, todo lo que tengo que hacer es simplemente arrastrarla de aquí a mis aplicaciones. Una vez que hayas hecho eso, sigue adelante y entra en tus aplicaciones. Y aquí ahora quieres hacer doble clic en más oscuro y solo conseguir que corra por mí porque ya lo he ejecutado antes. Simplemente va a empezar a correr. Y en realidad vas a ver si estás en una Mac y en la esquina superior derecha, va a haber esta pequeña nave que se ve así, que va a empezar a rebotar en un Windows. Pasaremos por eso en un segundo. Pero sí, espera a que se abra esto. Es la primera vez que lo vas a usar. Te va a pedir que leas y aceptes los términos y condiciones antes de que comience la aplicación. Así que justo cuando surja ese pop-up, solo asegúrate de seguir adelante y hacer eso. Y nuevamente en una Mac en la esquina superior derecha, generalmente en tu barra de herramientas ahí arriba, que actualmente está fuera de mi pantalla, deberías ver una ballena como esta con los contenedores circulando, lo que significa que estaba empezando. Y una vez que toma una forma fija, eso significa que se ha iniciado correctamente. Y después de haber aceptado los términos y condiciones y la startup está comenzando, deberías poder ir a tu PyCharm. Ahora bien, si solo escribes más oscuro en aquí, deberías ver alguna salida aquí que indicará que la instalación se ha ido con éxito. Si tienes algún problema con esto, lo primero que recomendaría es solo antes que nada, espera a que tu Docker termine de abrir. Y si sigue teniendo problemas, intenta reiniciar tu PC, no deberías necesitar hacerlo, pero generalmente es algo bueno intentarlo. Y luego cuando escribes más oscuro aquí, deberías ver que responde a algún tipo de salida. Nosotros tenemos aquí. Por el lado de Windows de las cosas. Vamos a estar en la misma página y podemos ver aquí ya me están recomendando la versión para Windows. Adelante y haz clic en Descargar sobre esto, que ya he seguido adelante y hecho porque tarda un par de minutos en descargarse. Entonces vas a abrir el instalador. Te va a preguntar, si quieres abrir esto, vas a hacer clic en Sí. Y luego vamos a abrir el instalador o va a haber dos casillas de verificación que van a estar marcadas por defecto. Simplemente déjelos y haga clic en Siguiente. Entonces se va a iniciar la instalación, lo que nuevamente toma un par de minutos. Así que voy a dejar que se ejecute en segundo plano. Y este es el estado al que vas a llegar donde dirá que la instalación ha tenido éxito. Y luego sólo vamos a hacer clic en cerrar y reiniciar. Entonces vamos a reiniciar nuestra máquina para esto. Entonces, después de reiniciar en el lado de Windows de las cosas, también nos van a preguntar con este pop-up aquí. Voy a aceptar los términos y simplemente continuar con eso. Y ahora Docker va a abrir en caso de que llegues este pop-up a. Solo vamos a seguir algunas instrucciones más aquí para obtener el proceso de instalación. Así que vamos a seguir adelante rápidamente y hacer eso. Mueve esto fuera del camino. Sigue las instrucciones aquí. Donald, esto de aquí, muy rápido. Abrir ejecutar y simplemente pasar por este proceso. Y entonces ya tengo PyCharm abierto aquí. Voy a tomar esto y sólo voy a copiarlo. Entra en PyCharm que ya tiene el PowerShell abierto. Pega esto ahí dentro. Sólo voy a presionar Reiniciar una vez más. Y después de golpear un reinicio aquí, si vamos a nuestro Docker, ahora deberíamos estar viendo que Docker Desktop está empezando a abrir esta aplicación. Si vamos a la parte inferior derecha, entonces también ahí, que para mí está actualmente fuera de pantalla. Pero también hay deberías poder ver si haces clic en esta pequeña flecha de ventanas que siempre tienes, que tienes aquí esta cosa más oscura del barco. Y entonces tienes los contenedores que deberían estar moviéndose. Y también ahí. Si haces clic en él, entonces debería llevarte vuelta a la aplicación Docker como la tenemos aquí. Bien, entonces ahora entrando en nuestro PyCharm, si golpeamos o si tecleamos más oscuro aquí. Y luego también desde el lado de Windows, este comando ahora debería estar registrado con algo y nos veremos en un segundo. Ahora tenemos salida asociada a ella. Entonces así es como vamos a ir sobre el proceso de instalación en Windows. 3. Creación de un archivo Docker: Bien, así que ahora que tenemos Docker instalado, sigamos adelante y realmente usemos Docker para que podamos ejecutar nuestra aplicación sobre él. Ahora, antes de saltar a eso, rápidamente quiero mostrarles solo en general, donde vamos a obtener estos sistemas operativos base son estos paquetes base preinstalados de los que vamos a usar. Entonces para hacer eso, puedes dirigirte a hub.docker.com. Entonces vas a necesitar crear una cuenta aquí. Entonces, si no tienes uno, solo tienes que seguir adelante e inscribirte en eso. Puedes iniciar sesión y llegarás a una página que probablemente se vea algo así. Y puedes dirigirte a la sección Explorar si lo deseas. Y aquí ya podemos ver una lista de diferentes tipos de sistemas base que están disponibles para nosotros. Estos pueden o no significar nada para ti. Y podemos ver aquí python es uno de esos. Así que podemos hacer clic directamente en esto o si estamos buscando algo específico. También podríamos buscar aquí, por ejemplo Python. Y vamos a estar usando una versión de esto. Y cuando vemos aquí dentro, podemos ver que hay esencialmente como etiquetas asociadas a ellas. Y veremos en un segundo cómo podemos usar estos. Pero todas estas son esencialmente versiones diferentes a las que tenemos acceso y que podemos usar. Y la importancia de usar etiquetas es que proporciona una sensación de consistencia. Si usamos una etiqueta, somos capaces de reutilizar consistentemente lo mismo. Y de esa manera, aunque me gusta, se apagan las actualizaciones o algo así, sabemos que nuestro sistema no va a cambiar. Siempre va a estar funcionando exactamente en las mismas condiciones, lo cual obviamente es tan importante para nosotros. Entonces para nosotros, voy a estar usando el Python aquí. Pero solo por tu información que si alguna vez necesitas usar una base o imágenes diferente que si no estás seguro de qué es exactamente lo que estás buscando, un Google rápido o usando tu motor de búsqueda de elección, probablemente te apuntaremos muy rápidamente en dirección o dirección, pero de lo contrario también puedes simplemente navegar qué imágenes están disponibles para el público en un solo lugar, solo entra en el Docker Hub. Y verás aquí por ejemplo para Python, esta es una imagen oficial y esa suele ser una buena etiqueta que quieres buscar. Ya que esos son generalmente los más confiables. Ya que esto no va a estar formando la base. Y entonces quieres asegurarte de que lo que tienes instalado es como una versión adecuada y no solo hecha por alguna persona aleatoria que puede ser un poco menos confiable. Aunque la línea verde, la línea gris en esa zona, también se vuelve un poco cuestionable qué, qué es confiable y qué no. Pero generalmente como un buen indicador, lo primero es buscar las imágenes oficiales. Y cuando no lo es, bueno, no tiene esa etiqueta. Solo asegúrate de entender lo que estás usando. Ya que es en lo que vas a estar ejecutando tu aplicación. Entonces solo estar consciente de eso desde una perspectiva de seguridad. Pero dicho eso, volvamos a nuestra aplicación. Y lo que voy a hacer aquí, voy a crear un nuevo archivo. Y voy a llamar a este archivo Docker como este archivo D Docker en mayúscula. Apenas va a golpear Enter. Y ahora aquí vamos a crear nuestro archivo Docker. Entonces, lo primero que tenemos que hacer es precisar qué debe formar la base de nuestro sistema. Entonces, esencialmente, la forma en que vamos a ir sobre la creación de estos contenedores Docker, que puedes pensar. Estamos transportando estos Contenedores bien estructurados, empaquetados y aislados, casi como un astillero. En cada uno de estos contenedores contendrá, en nuestro caso, como una aplicación, pero realmente puede contener cualquier cosa que esté adentro. Y suena como autosuficiente, o al menos tiene todo incluido que necesita ser incluido dentro del paquete único. Entonces, lo primero que tenemos que hacer es definir en qué va a estar nuestra base. Y entonces necesitamos algún tipo de sistema operativo basado en. Pero generalmente, si recién partimos de un sistema operativo, se vuelve molesto porque entonces necesitamos instalar todas las dependencias adicionales de Python para asegurarnos de que podemos ejecutar Python. Y lo mucho más fácil para nosotros es en lugar de comenzar como comenzar en algún sistema operativo básico y construir a partir de ahí, podemos ir un par de pasos más allá y podemos comenzar con un sistema operativo que tenga Python instalado. Y entonces todo lo que tenemos que hacer es instalar todas las cosas que necesitamos y esencialmente ejecutar nuestra aplicación. Entonces eso es lo que vamos a hacer. Vamos a empezar con esto desde la palabra clave, que va a definir con dónde queremos empezar. Voy a estar usando la imagen Python. Y específicamente voy a estar usando la etiqueta tres puntos nueve, que como habrás adivinado, indica que esto es para la versión 3.9 para Python. Y luego también voy a agregar otro guión aquí y hacer la imagen alpina. Ahora bien, la imagen alpina es generalmente algo agradable para comenzar a construir porque es relativamente pequeña. Lo que realmente no quieres es que no quieras instalar un sistema operativo masivo que tenga un montón de cosas instaladas, pero no vas a estar usando muchas de ellas. Entonces, en general, la propia imagen alpina con el Python será suficiente para tus casos de uso. Pero si alguna vez no lo es, hay otra cosa llamada slim buster que puedes probar. Pero alternativamente, un Google rápido o un rápido usando tu motor de búsqueda favorito, sea lo que sea, te apuntará muy rápidamente en la dirección correcta de lo que puede ser una mejor imagen para usar esto. Pero para la mayoría de los casos, la imagen alpina será suficiente para ti. Y nuevamente, el beneficio que obtenemos de ello es que no solo estamos instalando un montón de cosas y que nuestro contenedor se vuelve muy grande. Pero más bien queremos mantenerlo lo más pequeño posible para que no estemos agotando muchos de los recursos de nuestro sistema solo para tener todas estas cosas instaladas que ni siquiera estamos usando. Así que vamos a empezar desde la imagen de Python usando la etiqueta 39 dash Alpine, que de nuevo es una versión de Python 3.9 y viene con todo eso y las dependencias preinstaladas. Y aquí estamos usando la versión Alpine ya que esta es relativamente pequeña. Bien, entonces este es el primer comando que tenemos, que es el comando frontal. Ahora vamos a ver el siguiente comando, que va a ser un comando run. Entonces aquí podemos usar estos comandos para iniciar ciertos pasos. Y la forma en que hacemos las cosas y Docker es cada comando que tenemos en todas partes, cada palabra clave que estás usando aquí, puedes imaginar que estás agregando otra capa a tu imagen. Entonces tenemos nuestra primera capa aquí. Ahora cuando tengamos aquí nuestra primera palabra clave, corre, que veremos en un segundo. Vamos a formar nuestra segunda capa. Tenemos otra palabra clave aquí, digamos otra carrera. Sólo voy a formar nuestra tercera capa. Y con esto estamos construyendo un poco capa sobre capa sobre capa. Ahora la razón por la que esto es agradable porque Docker en realidad también tiene alguna forma de almacenamiento en caché. Por lo que reconocerá si no has hecho ningún cambio para como la mitad de tus cosas. Y realmente solo el último paso es el que cambia, entonces puede reutilizar la mayor parte de las cosas de antes y solo necesita cambiar la última capa. Así que teniendo eso en cuenta como algo muy importante, solo porque cuando estás construyendo tus imágenes de Docker, realmente las cosas que apenas cambian, quieres poner en lo más alto, y las cosas que puede cambiar más regularmente, por ejemplo, los paquetes que necesita instalar o también solo el código de su aplicación. Todo eso debería ser más hacia el fondo. Bien, así que estoy empezando con este comando de ejecución. Aquí podemos decirle a Docker que ejecute un comando específico y lo reconocerá. Vamos a ejecutar pip, instalar pip. Y así vamos a estar ejecutando este comando aquí, que probablemente reconozcas de una lección anterior, donde vamos a estar instalando pip end usando nuestro PIP. Y tenemos PIP disponible porque estamos instalando esta imagen base de Python, que ya tiene Python así como las cosas que necesitamos para ello o todo está preinstalado. La versión de Python aquí va a ser 3.9 otra vez, y también tenemos el comando pipa man que viene inmediatamente con él. Entonces sí, vamos a estar instalando R así. Ahora otra cosa que vamos a hacer es que vamos a crear un nuevo directorio. Vamos a crear una nueva carpeta donde podamos guardar todas nuestras cosas. Porque en última instancia estamos creando este contenedor y queremos poner todo lo que necesitamos en una ubicación para que esté disponible para nosotros tal como lo tenemos aquí en nuestro archivo de proyecto, por ejemplo y así para hacer esto, vamos a estar usando este directorio MK para make directory. Y vamos a tener este menos p, que esencialmente nos permite crear múltiples carpetas a la vez. Y luego solo vamos a usar esta ruta de usuario SRC slash app. Y aquí es donde vamos a estar poniendo todo nuestro código para nuestra aplicación. Ahora bien, estas cosas, no quiero entrar en demasiados detalles con todos los comandos de Linux porque en realidad hay un curso separado sobre eso. Así que no quiero descarrilar un poco demasiado aquí y solo enfocarte realmente en esto. Pero esencialmente teniendo en cuenta aquí, y solo puedes reutilizar la sintaxis es que solo estamos creando este directorio aquí, y estamos creando estas carpetas. Entonces en la carpeta de usuario, tenemos la carpeta SRC, y ahí tenemos la aplicación. Y si alguno de estos no existe, vamos a estar creándolo. Así que estamos haciendo esto otra vez, solo para que tengamos una carpeta en la que podamos poner nuestras cosas. Lo siguiente que vamos a hacer es que vamos a usar un nuevo comando llamado loops work. Y esto va a establecer nuestro directorio de trabajo actual. Esto nos va a ayudar porque en lugar de tener que escribir siempre esto en todas partes, cada vez que queramos ejecutar algo o en un segundo veremos copiar algo por encima. Solo podemos decir usando nuestra ubicación actual. Así que solo nos va a facilitar un poco más para que no tengamos que repetir este año todo el tiempo. Así que vamos a estar vendiéndola a esta aplicación de usuario SRC. Este va a ser nuestro directorio de trabajo o la carpeta en la que estamos trabajando actualmente, que todo debe ser relativo a bien. Así que ahora tenemos instalado pip, tenemos la carpeta en la que vamos a poner nuestras cosas. Y también vamos a estar simplemente estableciendo una ubicación relativa a esto. Ahora lo que tenemos que hacer es tener acceso a nuestros archivos, pero queremos copiarlos a nuestra imagen y ponerlos en la ubicación correcta. Vamos a usar este comando copy. Y ahora tenemos que mirar lo que tenemos aquí. Y esencialmente queremos ahora copiar esto. Y queremos tener la misma estructura en su mayor parte aquí, excepto tal vez deshacernos de alguna de la basura que no necesitamos. Entonces vamos a hacer esto en dos pasos. Vamos a comenzar con el bloqueo de archivos pip y el archivo pip, así como este main.py. Ya que estos son los que están más afuera, están, están un poco por encima de un nivel. Así que vamos a estar copiando estos. Así que vamos a copiar nuestro archivo pip, nuestro archivo pip punto loc. Y también vamos a estar copiando sobre nuestro main.py. Y solo vamos a usar esto porque en lugar de tener que escribir la aplicación SRC de usuario de ruta completa donde queremos copiarla, porque hemos establecido nuestro directorio de trabajo, solo podemos usar el ruta relativa, lo que significa copiado en el directorio de trabajo actual. Entonces eso va a ser copiar, tomar esto, y va a estar copiando eso para nosotros. Bien, así que ahora que tenemos estos archivos copiados, ahora queremos copiar sobre todo en nuestra carpeta de aplicaciones aquí. Ahora desafortunadamente, no podemos simplemente agregar nuestra app aquí porque va a tomar todos los contenidos desde adentro y solo va a copiarlo en la misma capa, que no es lo que queremos. Entonces vamos a agregar un segundo paso de copia aquí. Y queremos copiar el contenido de nuestra aplicación en esencialmente una carpeta de aplicaciones. Entonces lo que voy a hacer es que solo voy a crear una, otra carpeta de aplicaciones dentro de aquí. Entonces nuestra estructura de carpetas va a ser tu carpeta superior es la usr, entonces vamos a SRc. Entonces tenemos la carpeta de aplicaciones, y dentro de aquí tenemos otra carpeta de aplicaciones. Así que puedes imaginar esto solo por este nombre de carpeta en lugar de ser ofertas, cómpralas, proyecto estaría arriba y tenemos app aquí y app aquí. Y ahora quería copiar el contenido de esta carpeta, que es app, en la carpeta app que se encuentra dentro de aquí. Bien, así que hemos copiado nuestras cosas de primer nivel aquí. Va a estar en la misma capa. Y ahora quiero asegurarme de que todos los contenidos y aquí también están en este formato. Y nuevamente, si acabo de usar esto, eso va a tomar los contenidos de aquí y sólo va a copiarlos al mismo nivel, que obviamente no es la estructura actual que tenemos. Para hacer eso solo voy a agregar otra carpeta aquí en la que podamos copiar eso. Bien, entonces ahora que tenemos esto, sigamos adelante y por ahora, solo aprendamos cómo podemos iniciar nuestra imagen y mirar nuestra estructura actual para asegurarnos de que eso está bien. Y entonces lo que vamos a hacer es que vamos a terminar con el resto de las cosas que van a estar instalando usando la instalación pip y también ejecutando realmente nuestro servidor. Pero por ahora, veamos nuestra estructura actual y veamos que es apropiada. Y para esto, voy a usar el ls menos l, que si estás en una Mac o Linux lo hará, debería funcionar para ti. No creo que esto funcione en un Windows, pero está bien porque va a funcionar aquí porque vamos a estar usando una versión basada en Linux de todos modos. Pero puedes ver lo que hace este comando es que imprime los contenidos contenidos dentro de la carpeta actual en la que estoy. Así que esencialmente podemos ver aquí los contenidos aquí son exactamente como los contenidos enumerados aquí. Así que solo voy a ejecutar esto por ahora, solo para que podamos echar un vistazo a nuestra imagen que estamos construyendo aquí para asegurarnos de que nuestra estructura es correcta. Bien, así que ahora que tenemos nuestro archivo Docker definido, que define el conjunto de pasos que vamos a tomar, comenzando desde una imagen base y copiando todas nuestras cosas hasta tener esta imagen que contiene todas las cosas que necesitamos para que podamos ejecutar nuestra aplicación. Aún no lo tiene todo, pero ya estamos llegando. Entonces ahora que tenemos que hacer es ahora que tenemos esta imagen para encontrar aquí, necesitamos construir esta imagen. Así que no necesitábamos ejecutar estos comandos y ponerlo todo en un paquete listo que solo podamos ejecutar. Y así para hacer esto, vamos a usar el comando llamado Docker build. Y ahora vamos a usar un menos t aquí, que va a ser el objetivo que queremos copiar esto, el nombre que queremos asociar a esto. Y así que aquí sólo voy a llamar a esto mi primera app. Y voy a darle el giro a la etiqueta, lo último. Ahora, lo último es una etiqueta que verás muy a menudo, que es. Sólo indica que esta es la última versión de esta imagen. Ahora normalmente lo que vas a tener es que vas a tener una etiqueta asociada a cada imagen, y luego también tienes una última etiqueta. Entonces de esa manera si solo quieres ejecutar la última versión, puedes usar la última etiqueta, que probablemente cambiará con el tiempo si se están aplicando actualizaciones. Así que de esa manera tienes la garantía de estar siempre en la última versión. O también podrías hacer referencia a una etiqueta específica, como estamos haciendo aquí en este caso, lo que significa que incluso cuando más de 3.10 es nuestro, entonces es 3.11, 13.12, 13 si eso va a salir o cuando salga el precio y cuatro, eso no nos va a impactar porque todavía vamos a estar pegando con una imagen específica que está etiquetada con esta etiqueta aquí. Por lo que nos garantiza consistencia que aunque las cosas alrededor de un cambio, siempre vamos a estar usando la misma base. Entonces obviamente hay pros y contras para cada uno. Con esto, fácilmente podrás estar día con la última versión cada vez que la estés iniciando o reconstruyendo. Pero obviamente también son advertencias porque si las cosas cambian, pueden volverse incompatibles y entonces tus cosas pueden dejar de funcionar, lo cual obviamente no es bueno. Entonces, teniendo eso en mente, ahora tenemos el objetivo que queremos decir, construya esto en. Ahora sólo tenemos que dar la ubicación de nuestro archivo Docker, que sólo voy a poner el punto aquí, que sólo va a indicar que está en la carpeta actual donde estamos actualmente. Voy a golpear enter. Ahora para ti, esto probablemente va a llevar un poco de tiempo ya que primero necesitas descargar esta imagen. Y luego vas a ejecutar todos estos comandos encima de él. Para mí, muchas de las cosas ya han sido cobradas. Y puedes ver aquí, si nos desplazamos hacia arriba, se han cobrado muchos de estos pasos. Y así no se está haciendo ninguna descarga real para mí. Y en el proceso de construcción en realidad va muy, muy rápido como podemos ver. Una vez que hayas ejecutado esto la primera vez, si lo vuelves a ejecutar, entonces también irá muy rápido. Porque de nuevo, estas capas se encuentran en caché. Entonces ahora que tenemos nuestra imagen creada, ahora queremos ejecutarla. Entonces tenemos este paquete que está listo y ahora queremos ejecutarlo. Y así para hacer eso, vamos a usar el comando docker run. Y vamos a proporcionar ahora el nombre así como la etiqueta que queremos ejecutar. Entonces queremos ejecutar esta imagen aquí. Y también le voy a asignar un nombre. Entonces vamos a estar ejecutando esto, y esto va a estar funcionando como un contenedor. Vamos a estar ejecutando esta imagen aquí como un contenedor. Y vamos a darle un nombre a este contenedor en ejecución para que podamos verlo mejor. Eso podemos, cuando estamos viendo qué cosas están funcionando, que veremos en un segundo. sabremos, bien, esto es, este no es uno. Así que podemos darle un nombre legible. Entonces llamaremos a esto nuestra tal vez subrayado primera aplicación. No necesitas los guiones bajos, pero yo los voy a usar. Y si, solo pulsa entrar aquí. Y vamos a estar ejecutando esto y podemos ver que ejecutó este comando aquí, que es simplemente enumerar los contenidos. Y la estructura que tenemos es archivo pip. Tenemos archivo pip punto loc. Tenemos la carpeta de aplicaciones, que en su interior debería contener todas estas cosas. Y tenemos el main.py. Así es como se ve nuestra carpeta actual que tenemos. Ahora bien, esto es bueno porque no tenemos las pruebas, por ejemplo porque no necesitamos la prueba si estamos ejecutando nuestra imagen o para ejecutar este código como una aplicación. Porque para entonces, o nuestras pruebas las he ejecutado y ya no necesitamos las pruebas ahí porque no vamos a estar ejecutando las pruebas como una aplicación en vivo. Vamos a estar ejecutando la prueba cuando estemos probando localmente, vamos a estar ejecutando las pruebas más adelante cuando estemos, antes de construir nuestra imagen. Una vez construida nuestra imagen, ya no necesitamos las pruebas. Y así podemos descartar eso y decir, ahorrarnos aquí también un poco de espacio. Entonces ahora que tenemos esto funcionando, sigamos adelante y continuemos con nuestra configuración aquí. Porque realmente no solo queremos imprimir el contenido y luego terminar con él. Pero más bien queremos tener una aplicación en ejecución que podamos usar realmente. Para ello, todavía tenemos que dar un par de pasos. Lo primero que tenemos que hacer es que tenemos que ejecutar nuestra pip install para que estemos instalando toda la dependencia que necesitamos. Así que vamos a usar nuestra instalación pip . No vamos a estar usando la etiqueta def porque esta va a ser nuestra imagen de producción esencialmente. Entonces no queremos instalar las dependencias de desarrollo porque no las necesitamos. Sólo vamos a ser una aplicación pura. Sin embargo, vamos a usar una nueva etiqueta que va a ser dash, dash system. Ahora bien, esto va a instalar todo lo que estamos usando todo el sistema para que uno lo estemos ejecutando o cuando intentemos acceder a él, no tenemos que entrar en nuestro entorno virtual, sino que es solo va a ser instalado para todo un sistema, que va a hacer que sea un poco más fácil para nosotros porque entonces no tenemos que usar el PIP y el comando es más tarde otra vez, porque esencialmente lo que tenemos en toda esta imagen aquí es un entorno virtual. Estamos recreando esto cada vez y no hay nada más entrando en ello. Entonces podemos instalar este sistema en todo el sistema porque sabemos exactamente lo que es, porque estamos construyendo todo. Desde cero. Así que vamos a estar instalando nuestras dependencias como solemos hacer. Y ahora lo que tenemos que hacer es que realmente necesitamos ejecutar nuestra aplicación. Entonces volveremos a usar el comando CMD para esto. Y vamos a abrir y cerrar paréntesis. Y cada una de las entradas son cada uno de los elementos que vamos a tener aquí va a ser uno de los argumentos que vamos a ejecutar. Entonces, por ejemplo, generalmente cuando ejecutamos la aplicación de tablero principal de unicornio, que en realidad puedes ejecutar así. Pero la forma preferida de escribirlo sería así. Entonces si solo hacemos esto, este va a ser el comando habitual que usemos, Excepto Normalmente también tenemos esta recarga, etiqueta whoops. No queremos usar esto en producción porque esto disminuirá fuertemente o la aplicación. Así que asegúrate de no usar esta etiqueta en producción. Cuando lo estamos ejecutando localmente, está bien. Hace que el proceso sea mucho más fácil. Pero cuando lo estoy ejecutando en producción, ya no quieres usar esta etiqueta. Entonces ahora mismo solo podemos mantenerlo así si queremos, podemos probarlo. Pero aún quedan algunos temas que veremos en un segundo con esto. Pero vamos a llegar a esos cuando lleguemos a esos. Entonces lo que voy a hacer es volver a reconstruir mi imagen y luego entrar en mi primera app, la última. Así que voy a estar anulando esa etiqueta usando el comando de compilación de docker. Y whoops, olvidé el menos t aquí. Entonces en este caso va a estar tardando un poco más porque ahora realmente necesitamos ejecutar este sistema pip install. Entonces anteriormente no ejecutamos esto, pero ahora lo estamos ejecutando. Y entonces necesita ejecutar realmente este proceso que necesita descargar, instalar todas las dependencias hasta este momento va a ser un poco más lento, pero podemos ver todos los pasos anteriores aquí estamos en realidad se almacena en caché y así van muy, muy rápido. Y una vez hecho esto, lo cual debería hacerse en sólo un segundo. Sí, ahí vamos. Entonces ahora que tenemos esto derramado, podemos ir a Docker Run. Y vamos a dar nuestro nombre, que va a ser mi primera app, la última. Y vamos a reutilizar el mismo nombre, que va a ser nuestra primera aplicación. Queremos dar la etiqueta con el nombre aquí. Aquí nos vamos a estar topando con un problema porque se queja de que este nombre ya está en uso. Y llegaremos a este problema en un segundo. Pero por ahora, vamos a usar un nombre diferente, por ejemplo, así. Este nombre es ahora diferente a este. Entonces debería estar bien. Pero llegaremos a este tema en tan sólo un segundo. Entonces, sigamos adelante y ejecutemos esto. Y esto va a ser, podemos ver aquí el comando que hemos visto habitualmente, que es nuestra aplicación está iniciando. Pero ahora aquí está la cosa. Si tratamos de acceder a él, damos click en aquí. En realidad no tenemos acceso a él. cual obviamente apesta porque idealmente, incluso localmente, queremos poder usar Docker para hacer nuestro desarrollo. Y de esa manera podemos estar extremadamente seguros que lo que tenemos funcionando localmente en nuestra máquina es exactamente lo que se va a ejecutar en la nube más adelante. No vamos a encontrarnos ningún problema de que las cosas no estén correctamente instaladas, cosas que no estén disponibles. Entonces eso es lo que vamos a ver ahora. Bien, así que me golpean aquí, control C para matarlo. Y ahora lo que voy a hacer es primero, hecho voy a usar esta etiqueta dash, dash host. Entonces, en lugar de ejecutarlo en 127 punto cero punto, punto uno, en cambio, voy a ejecutarlo en 0000, que solo significa que esto aceptará cualquier interfaz de la que viniera, lo que solo la hace más general, que de nuevo es, agradable porque no queremos especificar una dirección concreta, sino que esencialmente solo queremos hacerla, siempre y cuando vayamos aquí, queremos tener acceso a ella. Así que vamos a usar este host en su lugar. Y ahora también lo que vamos a hacer es que vamos a definir un puerto específico que queremos utilizar para la consistencia. Entonces voy a estar usando el puerto 80, 80 aquí, por ejemplo, pero también puedes usar diferentes. Pero para este caso voy a estar usando el puerto 80, 80. Y ahora si reconstruimos nuestra imagen, solo vamos a desplazarnos hacia arriba y reconstruir y esperar a que termine este proceso. Verás que la mayoría de nuestras capas están en caché porque el único cambio que hicimos fue en realidad aquí. Todo lo demás ya se ha hecho. Y así, esencialmente recargamos todos esos pasos del efectivo. Y ahora solo voy a asignar un nuevo nombre por ahora, ya que tenemos ese nombre colisión anteriormente, que veremos en un segundo y golpearemos Run. Bien, así que ahora podemos ver aquí se están ejecutando en este host y estamos corriendo en este puerto. Pero aún así, si voy aquí, todavía no podemos acceder a él. Y eso es porque nuestra aplicación se está ejecutando dentro este contenedor y actualmente no tiene acceso al mundo exterior, ni siquiera en nuestra propia máquina. Entonces lo que tenemos que hacer es en nuestro comando docker run, voy a usar el indicador menos P. Y nos va a permitir hacer reenvío de puertos. Cuando salimos de nuestra máquina y miramos desde nuestro puerto, va a reenviar a un puerto específico en nuestro contenedor en ejecución, por ejemplo voy a decir forward port 808-02-8080 en el contenedor. Y de esta manera ahora, cuando ejecuto este nombre ya existe, hay que cambiar este nombre por ahora. Cuando vaya aquí. Ahora va a estar disponible. Y podemos ver si vamos a la página de docs, tendremos los docs disponibles para nosotros porque estamos en el puerto 80. 80, que en realidad ahora se reenvía al puerto de contenedores. Ahora, para mostrarte esto de nuevo, vamos a usar algunos números diferentes aquí. Vamos a usar el puerto 8,000, que vamos a adelantar al, gritos, eso no es lo que quería. 8 mil, que va a ser remitido al puerto 80, 80 y a nuestro contenedor. Así que recuerda, en nuestra aplicación contenedora se está ejecutando en el puerto 80, 80, pero afuera la vamos a estar reenviando desde el puerto 8,000. Entonces, si ejecuto esto, volví a adoptar el nombre. Lo estoy manejando. Si hago clic aquí, ahora vamos a tener un problema porque no hay nada funcionando en el puerto 80. 80. Pero si utilizo el puerto 8,000, entonces vamos a ser reenviados al puerto 80, 80 dentro de nuestra aplicación. Entonces esto no es importante. Vaya, vuelve a mostrar el comando. Este es un paso importante que debemos dar porque vamos a estar reenviando lo que tenemos en nuestra máquina, lo que realmente nos permite entrar en el contenedor. Bien, así que ahora vamos a llegar a este tema de nomenclatura aquí. Si usamos este comando docker ps, realidad podemos mirar todos los contenedores actuales en ejecución, que actualmente no hay ninguno. Pero si vuelvo a ejecutar este, el nombre otra vez. Bien, si vuelvo a ejecutar esta, abro aquí una nueva terminal. Y solo espera a que esto termine de prepararse. Voy a salir de mi entorno virtual. Ahora si vuelvo a usar el comando, docker ps, podemos ver aquí tenemos el único contenedor en ejecución. Podemos ver aquí este es el comando que se está ejecutando en su interior. Este es el reenvío de puertos que tenemos pasando. Este es el nombre del contenedor en ejecución. Cuando se creó. El Stata es que tenemos que añadir la imagen de que está corriendo. En cuanto matemos. Se. Se puede ver aquí ahora también se ha ido. Pero si queremos ver todos los contenedores que están disponibles, y volveremos a nuestra terminal anterior. Podemos usar este docker, ps dash, dash all, que nos mostrará todos los contenedores que tenemos. Entonces podemos ver aquí, esta es la primera que creamos. Entonces tenemos el segundo, el tercero, el cuarto, el quinto 161. Y entonces lo que podemos hacer es si tenemos estos contenedores viejos, en lugar de simplemente sentados ahí ocupando espacio, en realidad podemos eliminarlos si queremos, lo que podemos hacer usando docker remove. Y luego vamos a especificar aquí el ID del contenedor. Entonces voy a darle a Enter y va a quitar eso para que podamos ver si lo imprimo de nuevo. Este ya se ha ido. Y voy a hacer esto por esta también. Y hagámoslo también. Vamos a imprimir estos de nuevo aquí. Y para que esto sea un poco más rápido, eliminemos múltiples. Ahí vamos. Imprimiendo esos. Ahora podemos ver que solo tenemos nuestra aplicación cinco sobrantes, que además ya no se está ejecutando. Entonces, si queremos eliminar este, también podemos docker remove. Así que ahora no tenemos contenedores y AlphaGo volver a por ejemplo o ejecutar comando. Podemos reutilizar el mismo nombre porque no hay ningún contenedor que esté asociado actualmente a él. Ahora otra vez, va a estar funcionando. Todavía hay algunos otros comandos aquí, aunque probablemente estarás usando uno de ellos. Y lo que voy a hacer aquí es que sólo voy a encadenar dos comandos juntos. Entonces voy a realmente, primero necesito obtener su ID de contenedor y lo voy a quitar. Bien, entonces veremos eso en un segundo. Pero primero, una cosa que probablemente estará haciendo es lo que no queremos es que no queremos que nuestra terminal sea bloqueada por esto porque todavía queremos poder hacer otras cosas. Entonces hay un vuelo que podemos usar, que es este menos d, que lo va a ejecutar como un proceso daemon, lo que significa que solo se va a ejecutar en segundo plano. No va a estar sacando este espacio terminal de primer plano. Entonces si ejecutamos esto, podemos ver aquí ahora si hacemos docker ps, tenemos un contenedor en ejecución. Y si vamos a nuestro navegador web, le doy a refrescar aquí, entonces ya podemos ver. Que nuestra aplicación de hecho se está ejecutando. Estos fueron los otros, así que sólo voy a cerrar estos. Este tampoco debería estar corriendo porque es minucioso importante. Así que ahora vamos a correr un poco en segundo plano. Entonces ahora la pregunta podría ser, ¿cómo evitamos que se ejecute previamente podríamos golpear Control C. Lo que podemos hacer ahora es que podamos usar el comando docker, matar y darle el ID del contenedor, golpear Enter. Y ahora si lo intentamos de nuevo, nuestra aplicación ya no se está ejecutando. Podemos ver aquí no hay contenedores en funcionamiento. Y aún así tener el contenedor disponible. Entonces voy a quitar esta. Así. También podemos hacer esto usando la interfaz de usuario de escritorio si queremos. Entonces, si sacamos este de aquí arriba y ahora ejecutamos nuestro contenedor así, volvemos a la interfaz de usuario. Podemos ver aquí ahora tenemos un contenedor en funcionamiento. Si queremos, podemos hacer click en él. En realidad podemos ver la salida aquí. Hay algunas cosas con las que puedes jugar si quieres. Siempre que estemos listos. Quiero decir, hemos visto cómo podemos hacer esto por la terminal. Si quieres usar la interfaz, si quieres detenerla, por ejemplo, puedes golpear Detener aquí, lo que va a impedir que se ejecute. Entonces si tienes docker ps, podemos ver que no hay contenedores en ejecución o hacer docker ps menos, menos todos. ¿Ves el contenedor todavía disponible? Y si pulsamos Eliminar aquí, por ejemplo, entonces también vamos a estar borrando nuestro contenedor. Entonces esta fue nuestra primera mirada a más oscuro. Y sé que hemos cubierto mucho. Pero hemos llegado a un punto muy agradable porque ahora podemos ejecutar bien todo nuestro código, excepto por hacer cambios en cuyo momento todavía tenemos que reconstruir. Pero realmente podemos ejecutar nuestra aplicación sobre una imagen de Docker, lo cual es increíble porque estas van a ser las especificaciones exactas en las que se va a ejecutar cuando se esté ejecutando en un entorno en la nube en alguna parte. Y así sabemos que lo que sea que se esté ejecutando aquí es esencialmente cómo va a funcionar cuando se está ejecutando en otro lugar. Lo cual es extremadamente genial porque ahora tenemos mucha consistencia en nuestro sistema y no tenemos que preocuparnos por cómo k, sino que funciona en mi máquina. ¿Realmente correrá en otro lugar? Si estamos usando imágenes de Docker, entonces sabemos que aunque queramos darle esto a un colega, ellos pueden descargarla. Pueden construir la imagen de Docker que la pueda ejecutar. Y van a estar viendo exactamente las mismas cosas que nosotros. Ahora. Obviamente, más oscuro es un software muy genial y hay muchas cosas que vienen con él. Y no vamos a cubrirlos a todos. También vamos a estar buscando en Docker Compose. Entonces hay algunas cosas que podemos hacer en la oscuridad que no vamos a estar investigando aquí porque algunas de las cosas que vamos a hacer usando Docker componen, por ejemplo, pero incluso con eso, obviamente hay un montón de cosas metidas en las que puedes meterte. Algunas cosas realmente elegantes y complejas para tener realmente un sistema genial. Pero para la mayoría, casi todos los efectos, lo que estamos haciendo ahora es esencialmente lo que vas a necesitar o vas a estar haciendo cuando en realidad estás construyendo y ejecutando aplicaciones en acompanar. Y si alguna vez necesitas cosas específicas se encuentran problemas específicos que Google o cualquiera que sea tu motor de búsqueda favorito, probablemente solo te va a ayudar más rápido porque sabes exactamente lo que estás buscando, las cosas base de lo que puedes hacer y luego puedes simplemente rápidamente, Hay algunas cosas alrededor. Pero sí, más oscuro otra vez, es algo muy, muy importante, muy, muy común. Todo mi código que estoy ejecutando esencialmente se ejecutará con más oscuro y de alguna manera porque es tan agradable tener esa consistencia de tener esta imagen que solo podemos implementar en alguna parte y sé exactamente cómo va a funcionar. Y se lo puedes dar a un colega y ellos lo pueden ejecutar en su máquina y sabes que lo que sea que tengan va a ser exactamente la misma configuración que tú tienes. Y así es simplemente muy agradable porque permite consistencia y reproducibilidad. 4. Construción en múltiples etapas: Así que anteriormente hemos visto cómo podemos crear nuestras imágenes Docker. Ahora en esta lección vamos a repasar algunas mejores prácticas y la adaptación es que puedes hacer a esta imagen de Docker que estamos creando con esta plantilla de imagen de Docker que estamos creando para construir una contenedor fuera de. Y esencialmente se trata de cosas que muy probablemente verás utilizadas en muchos, muchos lugares. Y solo en general. En primer lugar, como nota al margen rápida, probablemente verás si estás usando PyCharm que vas a obtener algún tipo de solicitudes de instalación de plugins para Docker. Si quieres, puedes simplemente presionar instalar plugin. Habrá como una barra azul y solo voy a agregar poco de formato ya que pueden ver que la tengo aquí. Pero si no lo quieres, simplemente puedes hacer clic en Ignorar. Pero solo como una nota al margen rápida, probablemente verás esa barra emergente. Pero de todas formas, así que para estas mejoras, vas a ver esto generalmente mucho. Y vamos a ver es que primero vamos a crear un usuario. Este usuario nos va a ayudar porque no queremos ejecutar nuestro sistema completo como usuario root al final. Pero en cambio, si lo ejecutamos como un usuario con privilegios reducidos, eso nos puede ayudar. Porque si nuestra imagen Docker o un contenedor Docker alguna vez es atacado, entonces ese usuario que hackea, entonces ese usuario que hackea, no va a tener acceso completo al sistema, sino que va a tener acceso reducido, lo cual es agradable. La otra cosa que la vamos a ver como construcciones multietapa. Y esto solo nos ayuda a reducir el tamaño de la imagen final que tenemos que vamos a ejecutar, lo que solo ayuda a que las cosas sean más pequeñas. Entonces sí, y solo como nota general, para estas cosas más oscuras, vamos a pasar por esto paso a paso para que entiendas lo que estamos haciendo. Pero la mayoría de las veces vas a tener algún tipo de plantilla. Si estás trabajando en una organización, probablemente puedas estar bastante seguro de que tienen algún tipo de plantilla Docker que puedas usar para trabajar. Si no tienen uno oficial, solo puedes buscar en otro repositorio y usarlo como plantilla y tipo de adaptado a lo que necesites. Y alternativamente, si sabes lo que buscas, hay un montón de plantillas herramienta online que puedes usar para que no tengas que memorizar estas cosas de memoria. Probablemente vas a estar usando plantillas para esto. Solo necesitas saber lo que quieres, por qué está ahí. Y si falta algo, agregue eso en, esencialmente. Entonces eso es lo que vamos a pasar por él desde cero. Pero la mayoría de las veces cuando estás haciendo esto, puedes escribirlo tú mismo. Pero también es fácil usar una plantilla porque la mayoría de las veces vas a estar haciendo cosas muy similares. Bien, así que comencemos agregando a nuestro usuario. Entonces vamos a agregar otro comando run aquí. Y vamos a hacer Agregar Grupo menos S. Para agregar esto, vamos a crear un grupo al que vamos a agregar nuestro usuario en un segundo. Vamos a agregar eso a nuestro sistema. Y sólo voy a llamar a este grupo mi app, pero puedes llamarlo como sea. Entonces usamos esto y, y lo que nos permite encadenar comandos juntos. Entonces primero vamos a ejecutar éste, y ahora vamos a ejecutar otro comando después de éste, que va a ser add user. Y también vamos a hacer de esto un usuario de nuestro sistema. Vamos a agregarlo a nuestro grupo my app. Vamos a darle a este usuario el nombre usuario, y también vamos a asignarle un ID. Vamos a hacer 1234. Ahora si queremos ejecutar todo como usuario, vamos a usar este comando de usuario de Docker. Y entonces podemos o dar aquí el nombre que hemos asignado o veremos en un segundo, todos podemos ver es el id Y lo que esto va a hacer es que va a buscar a este usuario en el sistema, y va a encontrar esta identificación. Y luego el siguiente comando o punto de entrada que tengamos, se va a ejecutar usando este usuario en su lugar. Lo cual es bueno porque entonces ya no estamos ejecutando esto como el usuario root que tiene acceso completo, sino con acceso reducido. Así que sigamos adelante y asegurémonos de que esto funcione. Vamos a la primera compilación de Docker menos t. Haremos mi aplicación más reciente. Y en realidad también voy a usar esto y entregar aquí para que veas lo que hace. Pero esencialmente primero ejecutamos esto. Y si, si esto tiene éxito, entonces vamos a ejecutar lo siguiente aquí. Y eso va a ser docker, corre. Firmarlo con un nombre, mi prueba AP. Y podemos mapear los puertos como aprendimos anteriormente y la imagen vamos a ejecutar mi app, última, que va a ser esta de aquí. Golpea Enter. Ahora bien, esto debería ir relativamente rápido porque las cosas deberían estar en caché y solo agregamos dos comandos más en la parte inferior aquí, podemos ver aquí el proceso de construcción fue muy rápido. Y ahí vamos corriendo, y está funcionando correctamente. Tan excelente. Bien, sigamos adelante y apaguemos eso. Control C. Y sí, pasa a la parte de construcción multietapa. Y aquí vamos a añadir algunos cambios más, que veremos en un rato. Entonces lo primero que vamos a hacer es que vamos a mantener esto al mando. De hecho vamos a asignarle un alias y llamaremos a esto nuestra base. Y aquí esencialmente vamos a estar haciendo nuestra instalación y nuestra configuración. Y luego en un poco, como veremos, vamos a copiar cosas desde esta base que hemos creado en nuestra imagen principal en ejecución. Y ahora esto todo lo que no va a ser el último que estamos usando solo va a ser temporal y luego va a ser descartado, lo cual es lindo porque eso significa todo lo que no metamos en nuestra imagen final será desechado y no ocupará ningún espacio. Bien, entonces estamos creando nuestra imagen base aquí. Entonces ahora lo primero que queremos hacer es todavía y queremos instalar pip nth. Y ahora más que porque lo primero que queremos hacer o todo el punto de estas imágenes base, esencialmente queremos instalar algunas de nuestras cosas. Entonces lo que voy a hacer es que voy a tomar esto aquí, voy a cortar voy a poner esto por aquí. Pero no necesito el archivo principal ahora mismo porque solo quiero nuestro archivo pip y nuestro archivo pip lock. Porque solo quiero hacer la instalación. Voy a crear por ahora un comando de copia extra aquí abajo. Y voy a tomar esta parte y moverla aquí abajo, y llegaremos a esto más tarde. Así que ahora mismo solo voy a copiar o archivo pip y luego bloqueo de archivos pip. Alternativamente, lo que podemos hacer es usar pip file star, que va a buscar cualquier cosa que coincida con este formato. Entonces cualquier cosa que tenga archivo pip por adelantado y luego cualquier archivo que tenga algo después de eso. Así que esto es, por ejemplo, vamos a hacer coincidir archivo pip y el archivo pip punto loc. Y si tuviéramos otro como archivo pip, archivo , esto también se emparejaría con eso. Pero esto, vaya, no quería eso. Podemos usar esta o la otra. Pero esto es sólo una taquigrafía. Bien, entonces estamos copiando nuestro archivo pip. Y ahora lo siguiente que queremos hacer es en realidad ejecutar esta instalación. Porque queremos ejecutar esta imagen creada y nuestra base. Y luego vamos a copiar sobre los archivos instalados para que no tengamos ninguno, nada más. Bien, así que vamos a mantener una sintaxis similar, pero cambiar las cosas un poco. Así que vamos a mantener nuestro pip para instalar. Vamos a hacer una instalación en todo el sistema. Rocas van a agregar otro vuelo aquí, que va a ser la bandera de despliegue. Y si quieres saber qué hacen estas banderas específicamente, podemos, porque tenemos pip instalado, podemos ir pip install menos h. y esto en realidad va a sacar una ayuda buscar, lo que te dará todos los comandos que son accesibles. Entonces podemos ver si vamos al sistema por ejemplo va a ser vamos a instalar esto solo en nuestro sistema o desplegarlo. Entonces esto va a ser bueno porque esencialmente si algo anda mal, como nuestros archivos de registro desactualizados o la versión de Python es incorrecta, va a abortar. Lo cual es bueno porque solo queremos asegurarnos de que todo esté funcionando como se describe. Y así si algo anda mal aquí, sólo va a abortar. Y luego vamos a agregar otra bandera que va a ser ignorar los bucles de archivos pip. Lo que significa que vamos a construir específicamente a partir de la cerradura. Bien, así que esta va a ser nuestra instalación pip, que es un poco diferente, pero sigue siendo muy similar a lo que teníamos antes. Todavía quedan algunos cambios que habrá que hacer aquí en un segundo, pero llegaremos a esos cuando lleguemos a esto. Ahora vamos a agregar otro de y vamos a sacar de la misma imagen exacta aquí. Y luego aquí. Ahora vamos a, bueno, queremos copiar sobre. El caso es que hemos instalado previamente aquí para que todos los paquetes que instalamos se copien en nuestra imagen principal que vamos a necesitar. Ahora para hacer esto correctamente, hay varias cosas que tenemos que hacer. Entonces, antes que nada, vamos a agregar algunas variables de entorno, que en realidad para Docker, solo podemos usar esta palabra clave final que va a establecer variables de entorno para nosotros. Entonces la primera variable de entorno que voy a usar va a ser nuestra raíz pi. Y lo voy a definir para tener este valor de raíz de slash pi. Y esto esencialmente va a, vamos a usar esto en un segundo para decir donde queremos que las cosas se instalen también. Entonces vamos a crear una variable base de usuarios de Python. Ahora bien esta variable es importante porque nos dice o le dice al sistema el directorio base para el usuario. Y vamos a establecer este valor a esta variable de entorno pirata. Y puedo hacer referencia al valor contenido en esta variable usando el signo de dólar y luego el nombre de la variable. Si quiero, también puedo poner esto entre corchetes, lo que puede ser útil si después hay otras cosas adjuntas. Entonces ahora lo que hemos hecho es que hemos definido esta variable de entorno a este valor. Y hemos definido esta variable de entorno al valor que contiene aquí. Ahora vamos a usar una variable de entorno más, que va a ser la ruta. Ahora con la ruta es, es esencialmente una lista de lugares donde nuestro sistema operativo buscará ejecutables para. Y como vamos a estar instalando en este directorio aquí, queremos asegurarnos de que añadimos esto a la lista de archivos descubribles para buscar ejecutables. Para. Entonces, para hacer esto, vamos a hacer referencia a nuestra variable de ruta existente, y vamos a agregar a ella nuestros piratas. Slash bin directorio específicamente porque aquí es donde van a vivir nuestras cutículas de ejecución. Ahora otra vez, como mencioné anteriormente, no tienes que entender esto como de adentro hacia afuera. No hay que poder reproducir esto por memoria. El punto es que entiendes por qué estamos haciendo estos pasos. Aquí. Estamos agregando esto porque necesitamos tener algún tipo de directorio de usuario base donde van a ir nuestras instalaciones. Y ahora como estamos agregando instalaciones, también queremos asegurarnos de que los ejecutables puedan ser encontrados realmente por sistema operativo. Esos son esencialmente los pasos que estamos dando aquí. Y si no damos estos pasos, ya verás. Y podemos probar eso en un segundo. No va a correr. Por lo que es importante que agreguemos estos pasos para que funcione correctamente. Y todo lo que estamos haciendo aquí es simplemente crear variables de entorno. Bien, entonces tenemos nuestra instalación pip, pip end, que vamos a mantener igual. Así que todavía queremos instalar pip end. Vamos a copiar nuestros archivos Pip. Y ahora vamos a agregar una bandera más delante de aquí. O vamos a definir nuestra variable de entorno para este comando. Y vamos a establecer la variable de entorno de usuario aquí para querer una. que significa que va a tratar esta instalación como una instalación de usuario. Lo que significa esencialmente las cosas de ubicación del usuario que definimos anteriormente. Voy a hacer efecto. Así que acabamos de actualizar esto para ahora tratarlo como una instalación de usuario. Y esta es la primera parte. Entonces esto es en lo que va a consistir nuestra base. Y nuevamente, el propósito está aquí, es hacer la configuración. Y si alguna vez necesitas instalar alguna otra dependencia, lo harías en el componente base. Entonces instalando todo lo que necesitamos que luego podremos usar para instalar otras cosas. Todas esas cosas van a entrar aquí. Ahora vamos a tener nuestra segunda etapa Docker. Aquí. De hecho vamos a juntar nuestra imagen final y vamos a tomar el control de lo que necesitamos a partir de aquí. Y todo lo que no vamos a tomar el control realidad va a ser desechado al final, lo cual es bonito porque eso nos ahorra un poco de espacio porque no nos estamos apoderando de cosas innecesarias. En realidad vamos a definir estas tres variables exactamente de la misma manera aquí. Así que sólo voy a copiar estos. Ahora lo siguiente que voy a hacer es que en realidad voy a tomar este comando de usuario. Y vamos a mover esto aquí arriba. Porque cuando estamos haciendo nuestra copia en un segundo, realidad quiero asegurarme de asignar estos archivos específicamente al usuario. Pero antes de hacer eso, vamos a tener un comando copy aquí porque primero queremos obtener todos nuestros paquetes que hemos instalado con nuestro PIP n en esta imagen. Ahora, voy a usar un CH propio. Y aquí vamos a definir primero al grupo. Entonces el grupo aquí es mi app, y debería ser igual, no dos puntos. Aquí va el colon. Entonces este va a ser el grupo, y este va a ser el usuario. Y vamos a agregar otra bandera desde base. Este espacio hace referencia, este alias que tenemos aquí arriba. Ahora, vamos a copiar los contenidos del directorio pirata, de nuestra base nuestro directorio pirata en esta imagen aquí. Así que esencialmente estamos copiando ahora todas estas cosas que hemos instalado aquí con la instalación pip, estamos copiando todos esos paquetes sobre él porque los necesitamos, porque necesitamos esas cosas instaladas para ejecutar nuestra aplicación. Y este comando, esta sintaxis aquí es algo especial que podemos agregar para Docker e intereses significa copiar esto y asignar los privilegios para estas cosas copiadas a nuestro usuario aquí. Y aquí es de donde queremos copiar. Bien, así que ahora que hemos copiado sobre todos los paquetes que necesitamos instalados, me voy a quedar este año porque vamos a mantener nuestro directorio. Voy a mantener nuestra asignación del directorio de trabajo. Y en lugar de simplemente copiar estos directamente, ahora voy a copiarlos con privilegios asignados a ese usuario. Así. Sí, eso es. Eso es. Este es nuestro comando Docker actualizado. Y vamos a ejecutar esto para asegurarnos de que funciona. Y luego vamos a repasarlo una vez más. Entonces voy a, primero, necesito quitar la imagen que corrimos anteriormente, que es sí, este es el nombre que le asignamos. Entonces tengo que quitar este primero. Y en realidad voy a usar esto y otra vez aquí. Y lo que voy a hacer es porque esto me ayuda a manejarlo varias veces. Si todo pasa, voy a eliminar la imagen que creé anteriormente. Esto solo funciona obviamente si primero he corrido estos dos comandos. Pero una vez que ejecuto este docker run, y solo quiero ejecutarlo con el mismo nombre una y otra vez. Voy a quitar esa existente lo siento, no imagen. Voy a quitar ese contenedor existente. Voy a construir una nueva imagen a partir de nuestra plantilla de archivo Docker. Asigne la misma etiqueta. Voy a ejecutar esta imagen como un nuevo contenedor en este nombre. Entonces probemos eso. ¿Bien? Así que podemos ver aquí tenemos dos etapas diferentes también sucediendo. Tenemos una etapa base y tenemos nuestra etapa final. Y ahí vamos. Nuestro sistema ahora sigue funcionando, por suerte. Pero hemos integrado algunas mejores prácticas de prensa más oscuras. Ahora no nos estamos ejecutando como el usuario root. En cambio, estábamos corriendo como un usuario que hemos creado con privilegios reducidos. Y aquí también hay un paso que para nosotros probablemente no va a tener un impacto tan grande. Pero una vez que necesitas instalar otras cosas binarias para ayudarte a instalar otras bibliotecas, como primero, necesitas instalar algunas cosas para que puedas instalar otras cosas. Te ayudará porque esas cosas que instalaste anteriormente, una vez que hayas instalado tu biblioteca, es posible que ya no las necesites. Entonces este proceso solo va a ayudar con eso porque esencialmente muchas de las cosas de configuración que podemos necesitar instalar, pero puede que en realidad no necesite después de que se complete la instalación, podemos descartar todo eso. Entonces todo aquí que no estamos copiando específicamente en esta etapa final aquí. Actualmente, esta es nuestra etapa final. Todo incluido esto. Todo esto aquí que no se haya copiado aquí será desechado. Entonces eso sólo nos va a ayudar de nuevo a salvar algo de memoria. Y si, esto es un edificio de varias etapas con un adicional que están ejecutando cosas como usuario, también podemos cambiar esto para usar el ID de usuario que le hemos asignado aquí. Y volvamos a ejecutar eso para asegurarnos de que esto siga funcionando. Si buscas plantillas de Docker, tanto dentro de una organización como también en línea en alguna parte y van a seguir un formato similar como este. Pueden tener algunas diferencias en alguna parte, pero este va a ser el objetivo principal es que tengas una imagen base y a menudo quizás a veces también veas como una imagen base. Entonces verás una imagen de constructor donde realmente ocurre el proceso de construcción. Y luego verás la imagen final donde se copian las cosas. Puede haber incluso más de dos pasos involucrados, pero es la misma idea de hacer la configuración y luego copiar todo lo que necesitamos y descartar el resto para simplemente hacer nuestras imágenes finales un poco más pequeños para que no estemos usando memoria innecesaria en nuestras imágenes. Que esencialmente no queremos cosas instaladas que no vamos a usar es el objetivo de todo esto. ¿Bien? Entonces, sí, hay una optimización más que podemos hacer, que en realidad voy a hacer ahora mismo. Aquí tenemos dos etapas. Y en general, un buen objetivo para tener es tener el menor número de etapas posible. Entonces lo que voy a hacer es en lugar de tener el punto principal py afuera, realidad voy a mover esto a nuestra aplicación aquí. Así. Copia esto sobre. Y en nuestra olla principal aquí. Todavía tenemos nuestra aplicación definida aquí. Y no creo que en realidad tengamos que cambiar nada aquí, lo cual es genial. Pero ahora en nuestro archivo Docker, necesitamos, ahora podemos eliminar esencialmente esto. También podemos eliminar una de estas aplicaciones porque ahora todo va a estar contenido dentro de nuestra carpeta de aplicaciones aquí. También podemos eliminar esta app si queremos. O alternativamente, podríamos dejar esto adentro y simplemente hacerlo así. Y construyamos y ejecutemos eso una vez más. Y ojalá haya actualizado todas las referencias correctamente. Sólo voy a tomar un poco más de tiempo porque aquí hemos hecho algunos cambios en nuestro código. Y así en algún momento antes de la copia, Oh, bien. Déjame encontrar rápidamente lo que está pasando aquí. Main.py. Bueno, creo que esto es solo pruébalo así. Y ahora necesito actualizar mi punto de entrada aquí porque nuestro directorio de trabajo está un nivel arriba. Entonces necesito asegurarme de entrar en esta carpeta y luego ejecutarla desde ahí. Sí, una vez más. La tercera o tercera vez es un encanto. Bien, ahí vamos. Entonces, qué pasos este pudimos reducir su número de pasos uno su número de pasos que tenemos en nuestro archivo Docker, lo cual es agradable. Y esencialmente solo tuvimos que cambiar algunos de los archivos que creamos en algunas de sus referencias de nombre aquí para asegurarnos que todo esté en la ubicación correcta, que estamos referenciándolo desde el lugar correcto. Entonces ahora estamos esencialmente en este nivel. Aquí, vamos a nuestra carpeta de aplicaciones, a nuestra carpeta de aplicaciones, estamos haciendo referencia al archivo principal. Y aquí todavía estamos haciendo referencia a esta app, esta app inicializada que hemos creado aquí. Entonces el proceso sigue siendo el mismo, pero lo hemos puesto un poco en la única cosa de aquí. Hemos reducido los pasos de nuestros estados en uno, lo cual es simplemente más agradable. Cuantos menos pasos tengas, mejor es. Vamos solo a una buena cosa general a la que apuntar. Ahora, antes de terminar esta lección de las mejores prácticas de Docker, en realidad notamos que también queremos agregar a nuestro usuario es igual a un vuelo aquí porque queremos asegurarnos de que todos los de las mejores prácticas de Docker, en realidad notamos que también queremos agregar a nuestro usuario es igual a un vuelo aquí porque queremos asegurarnos de que todos los instalaciones que estamos haciendo, en realidad vas a estar con el mismo nivel de usuario para que no estemos instalando algunas cosas en nuestro sistema y otras cosas instaladas en nuestro usuario. Además, también me he dado cuenta cuando es pequeño error tipográfico, es decir, este debería ser el usuario primero y luego el grupo. Así que vamos a arreglar eso rápidamente también. Y ahí vamos. 5. Docker Compone: Bien, anteriormente hemos profundizado en este archivo Docker y lo hemos reestructurado de una manera mejor siguiendo las mejores prácticas. Ahora vamos a echar un vistazo Docker Compose porque actualmente cuando hemos estado usando el archivo Docker, que ha estado construyendo el archivo único, y luego lo hemos estado ejecutando. Pero en realidad lo que va a ser agradable y lo que verás también cuando lleguemos a él más tarde cuando agreguemos como bases de datos y almacenamiento en caché y esas cosas es que no solo queremos tener nuestra aplicación ejecutándose, también queremos tener una ejecución que podemos usar con nuestra aplicación. Y probablemente también queremos tener una caché separada ejecutándose que queremos usar con nuestra aplicación. Y así poder configurar todo este sistema que podamos reutilizar. Y en realidad hay muchas cosas geniales que puedes configurar y bueno, es un tema profundo en el que sumergirnos y obviamente no vamos a cubrir todo, pero vamos a repasar los puntos principales. Y a medida que lleguemos a él en puntos más abajo de la carretera en este curso, también vamos a volver a tocar este Docker Compose y agregarle componentes. Por ejemplo, la base de datos en el efectivo que acabo de mencionar. Pero el punto es que a veces simplemente no queremos ejecutar una cosa que esté un poco aislada, sino que queremos ejecutar varias cosas y tal vez esas cosas o incluso conectadas. Y así para que ese proceso sea fácil para nosotros, vamos a usar Docker Compose. Y así vamos a empezar creando un nuevo archivo aquí. Y voy a llamar a este Docker componer. A Docker, Compose punto YAML, así. Si tienes Docker instalado, también deberías tener Docker Compose. Entonces todo ya debería estar configurado para ti. Bien, entonces primero vamos a escribir un código esqueleto y luego vamos a explicar lo que está pasando. Y esencialmente lo primero que vamos a tratar de hacer es que vamos a intentar reproducir lo que hemos tenido corriendo con más oscuro. Pero ahora en lugar de usar Docker componer, así que solo queremos poner en marcha el mismo servicio un contenedor Docker al que aún podamos acceder a través de nuestro navegador web. Entonces lo primero que necesito definir aquí es qué versión vamos a usar de la sintaxis que vamos a usar aquí versión tres. Y luego vamos a definir los servicios que aquí se están ejecutando. Puedes ver que tengo instalado el plugin Docker. Entonces algunas de estas cosas en realidad se llenan automáticamente. Si no lo tienes instalado, entonces no lo hará. Y si aún tienes esa notificación aquí arriba, entonces obviamente la forma más fácil es simplemente golpear install plug-in y lo instalará por ti. Pero de nuevo, no es realmente necesario. Simplemente ayuda, ayuda con el llenado automático y algunas cosas. Pero sí, bien, así que aquí vamos a definir los diferentes servicios que se están ejecutando. Uno de esos servicios, por ejemplo, va a ser tu aplicación. Vamos a definir un solo servicio. Voy a darle el nombre de la app. Podemos llamarlo como queramos, pero le voy a dar el nombre app solo para tener claro en torno a qué es esto. Y ahora aquí dentro vamos a definir más a fondo algunas de las cosas al respecto. Entonces lo primero que quería encontrar es, ¿cómo puedo construir esta aplicación? ¿Cuál es el archivo Docker al que necesitamos hacer referencia? Algunos casos en los que en realidad podemos estar haciendo referencia un archivo Docker que está en Docker Hub. Y en otros casos queremos hacer referencia a un archivo Docker aquí que tenemos. Entonces voy a tener este parámetro bill y solo voy a señalarlo al directorio actual. Entonces solo usando un solo punto para eso. Ahora la otra cosa que quiero hacer para tener acceso a ella, que también hicimos anteriormente, es que voy a definir las asignaciones portuarias. Entonces Docker, usamos eso menos p Aquí. Vamos a tener que esto sea un puerto. Y podemos ver aquí ya es auto lo llena para mí. Pero esencialmente vamos a tener dos puntos después de aquí. Vamos a ir en una nueva línea. Y entonces vamos a tener un guión que indica que esto va a ser una matriz. Entonces podemos hacer múltiples asignaciones de puertos porque solo vamos a usar un mapeo de puertos aquí va a ser nuevamente del puerto 80 al puerto 80, 80, así. Y aquí podemos ver que estamos iniciando esto en el puerto 80, 80. Por lo tanto, queremos asegurarnos de que nuestro puerto externo esté mapeando con el puerto de información correcto. Lo mismo que cubrimos cuando ejecutamos el archivo Docker individual. Y esto es en realidad todo, lo que necesitamos para reproducir esencialmente lo que teníamos con nuestra compilación Docker. Así que sigamos adelante y hagamos girar esto. Entonces, lo primero que tenemos que hacer para esto se ejecute es que podamos usar el comando Docker dash compuso. Y luego vamos a escribir aquí arriba. Y también vamos a agregar una bandera adicional que va a ser menos menos construir. Y así esto significa que vamos a hacer girar nuestro contenedor, pero también vamos a construirlo primero. Así que primero construye que gastarlo. Entonces, sigamos adelante y ejecutemos esto. Probablemente voy a tomar solo un poco de tiempo para construir. La mayor parte debe ser cacheada. Y veamos aquí. Simplemente sigue creándolo. Bien, entonces ahí vamos. Tenemos nuestro contenedor funcionando. Y si hago clic en esto entonces debería tener acceso a él. Entonces, si vas a la página de docs y pruebas uno de estos puntos finales. Bien, ahí vamos, Genial. Entonces este es el valor predeterminado que tenemos y está funcionando. Entonces si queremos volver a bajarlo, bueno. Ahora no lo estamos ejecutando en modo daemon. Entonces si acabo de darle a Control C, en realidad va a detenerlo, lo cual podemos ver si volvemos aquí, refrescándolo ahora está abajo. Pero si queremos ejecutarlo en modo daemon, como hicimos para nuestro Docker. Así que tenerlo en segundo plano y no ocupar el primer plano aquí, voy a hacer lo mismo, menos, menos construir. Y entonces voy a agregar una bandera menos d aquí y ejecutar esta una vez más. Nuevamente, todo el asunto debe ser almacenado en caché, por lo que debería ir bastante rápido. Y ahí vamos. Entonces ahora sigue funcionando en segundo plano. Puedo hacer docker ps para ver que esto de hecho está funcionando. Y si voy a refrescar, entonces otra vez, estamos corriendo. Ahora bien, si quiero bajar el servicio, puedo hacer docker componer abajo, lo que va a detener todo esto. Y otra vez, si refresco esto, ahí vamos. Ya no se ejecuta. Bien, hasta ahora tan bien, ¿verdad? Bastante simple y bastante conveniente. Pero hasta ahora, no hay tanta diferencia en usar el comando Docker, ¿verdad? Es, es un poco más corto porque podemos hacer la compilación y correr paso a la vez aquí, pero aún no tanto más corto. Así que vamos a meternos un poco más en ello y ver algunas de las otras cosas geniales que podemos hacer. Entonces, una de las cosas que una de las cosas adicionales que podemos hacer, por ejemplo, es que podemos definir esta variable de punto de entrada. Y aquí vamos a usar la misma sintaxis que teníamos en nuestro comando aquí. Va a tomar esto y copiarlo. Pero tal vez lo que realmente quiero hacer, voy a copiar esto por aquí, es cuando estamos construyendo nuestro archivo Docker y queremos ejecutarlo en alguna parte. Obviamente no queremos ejecutarlo con el guión, el indicador de recarga de tablero porque eso va a agregar muchos gastos generales que no queremos. Pero cuando nos estamos desarrollando localmente, es muy agradable tener esa bandera porque podemos cambiar las cosas y podemos hacer cosas. Simplemente podemos desarrollarnos más rápido porque no tenemos que derribar si iniciamos nuestra aplicación. Así que idealmente podríamos usar este indicador de recarga menos, menos. Y así si definimos un punto de entrada en nuestro nivel Docker Compose, realidad va a usar estos puntos de entrada o este comando en lugar de cualquier comando final que tengamos aquí. Entonces en este caso, si vuelvo a ejecutar esto, estibador-compongo, y lo construyo y lo ejecuto. Y modo David, vamos a ver en un segundo. En realidad no lo haremos. Así que voy a derribarlo y ejecutarlo no en modo daemon para que solo podamos ver la salida directamente. Hagámoslo una vez más. Aquí vemos que iniciamos una recarga de nuestro proceso. Entonces eso es porque tenemos esta bandera de recarga ahora activa. Para que podamos ver que esto funciona correctamente. Desafortunadamente, porque estamos corriendo en un contenedor Docker. Entonces si actualizo esto, esto está funcionando como se pretendía. Pero si trato de hacer algún cambio, por ejemplo, entrar aquí y tal vez solo actualizar el nombre de este punto final, como simplemente agregar algo aleatorio aquí. Ya podemos ver que no se está reiniciando. Y si me refresco aquí, tampoco está actualizando. Pero lo ideal es que lo que quisiera es poder tener esta cosa funcionando y poder editar mi código. Y como estoy editando tal como lo hicimos cuando lo ejecutamos localmente sin Docker, quiero poder tener estas actualizaciones tipo de actualización. La forma en que vamos a hacer eso es que vamos a volver a bajar esto. Aquí vamos a agregar un componente extra, que se llama volumen o volúmenes. Y lo que los volúmenes nos permiten hacer es que nos permitan mapear esencialmente fuera de los almacenes a lugares dentro de nuestro contenedor. Y los volúmenes son extremadamente agradables porque nos proporcionan un método persistente de almacenamiento. Entonces nuestros contenedores pueden bajar, ¿verdad? Como si tuviéramos nuestra cosa Docker funcionando y guardamos cosas, idealmente, no queremos guardar nada en nuestro contenedor porque ese contenedor puede apagarse. Y la forma en que deberían estar funcionando nuestros contenedores es que solo deberíamos poder hacer girar uno nuevo y debería tener exactamente el mismo estado que el anterior. Como que no debería evolucionar con el tiempo. Si queremos almacenar información, o bien la vamos a enviar a bases de datos en alguna parte. O si es una base de datos en sí misma, debería almacenarla en algún tipo de almacenamiento que aunque el contenedor se caiga, el almacenamiento aún está disponible. Y así es lo que esos volúmenes nos permiten hacer. Nos permite mapear lugares externos de almacenamiento a lugares en nuestro contenedor Docker. Podemos usar esto para bases de datos que veremos más adelante para persistir los datos a medida que hacemos girar hacia arriba y hacia abajo una instancia de base de datos. Pero en realidad lo vamos a usar por ahora, es que vamos a mapear nuestros estados locales de nuestro código en el estado del código en nuestro Docker Compose. Lo que voy a hacer es mapear nuestro directorio actual a. Este lugar aquí en nuestro archivo Docker. Y esto no debería estar aquí. Entonces repasemos esto una vez más, luego ejecutémoslo y veamos cómo está funcionando. Y entonces tal vez tomar otro par de momentos para pensar en lo que realmente está pasando aquí. Pero esencialmente lo que hicimos es en nuestro archivo Docker aquí, hemos creado una nueva aplicación SRC de usuario de ubicación de carpetas. Y esencialmente porque estamos copiando sobre esta aplicación en esta carpeta de aplicaciones, en esta ruta, esta ubicación en la que estamos en esta carpeta, este directorio esencialmente representa lo que tenemos aquí. No copiamos sobre todo, pero esencialmente, bien, eso es lo que tenemos. Copiamos sobre las cosas que necesitábamos. Entonces, si agrego el mapeo aquí, por ejemplo de nuestra ubicación actual a esa ubicación en el archivo Docker. Entonces en realidad, y te voy a mostrar esto ahora, y volveré a agregar la bandera menos d. Porque ahora podemos tenerlo funcionando en segundo plano. Ahora vamos a mapear este lugar dentro de nuestro archivo Docker a este lugar que actualmente está en nuestra máquina local. Veamos esto en acción. Entonces, si refresco esto, baje esto. Bien, ahí vamos. Entonces ahora todavía tenemos lo que tenemos aquí. Ahora sigamos adelante y hagamos un cambio. Voy a añadir un extra a aquí, Guardar. Voy a refrescar la documentación. Ahora podemos ver que nuestras actualizaciones realmente se han reflejado. Entonces nuevamente, la razón por la que pudimos hacer eso es porque anteriormente no pudimos acceder después de haber creado nuestra imagen Docker y comenzamos con el contenedor, estábamos incapaz de acceder a su contenido internamente. Pero ahora hemos creado un mapeo de esta carpeta aquí a esta carpeta aquí. Y lo que también podríamos hacer es que en realidad podríamos ser más específicos y simplemente mapear. Y voy a deshacer estos cambios aquí así. Y vamos a hacer Docker componer abajo. Sólo para que estemos empezando de borrón y cuenta nueva. Podemos ser más específicos y mapear la carpeta de aplicación que tenemos aquí a la aplicación que tenemos ahí. Así que estamos, porque estamos copiando esto de nuevo en nuestro archivo Docker, así, que va a estar en este camino. Vamos a tomar un mapeo de la carpeta de la aplicación aquí a la ubicación que se copiará la aplicación sobre un archivo Docker y nuestro. Refresca esta una vez más. Ahí vamos. Entonces lo que teníamos, ahora voy a actualizar esta otra vez aquí, guardar, refrescar. Y ahí vamos. Así que nuevamente, los volúmenes nos permiten mapear estos almacenamientos desde el interior de nuestro contenedor hasta algún tipo de almacenamiento externo. Y esto es realmente agradable porque de esta manera también somos capaces guardar datos fuera. Y si un contenedor baja, podemos simplemente conectarlo al volumen persistente. No tienes acceso a los mismos datos exactos. Lo cual obviamente es muy agradable si tenemos bases de datos funcionando, por ejemplo , y sí, solo tenlo en cuenta. Eso si estás ejecutando un contenedor Docker y estás guardando en un archivo local. Una vez que ese contenedor cae, ese archivo se ha ido. Así que siempre, si necesitas algo, siempre guárdalo en algún lugar fuera de tu contenedor porque realmente no tendrás muy fácil acceso a él dentro del contenedor y una vez que se baje, se ha ido. Así que solo teniendo eso en mente. Y aquí es de nuevo donde los volúmenes realmente nos ayudan. ¿Bien? Entonces los volúmenes son bonitos, esto es algo así como lo que tenemos ahora mismo, que es esencialmente la aplicación que hemos tenido anteriormente. Déjame bajarlo de nuevo. Ahora somos capaces de hacer mucho más con nosotros. Entonces tenemos nuestra aplicación actual. Pero algo que también queremos hacer es que queremos que nos guste ejecutar nuestras pruebas unitarias, por ejemplo, idealmente, lo ejecutaríamos en el contenedor Docker porque esa es exactamente la configuración a la que vamos tener cuando se está ejecutando en producción. Porque ese es el objetivo de esto, que tenemos esta configuración reproducible. Entonces voy a crear un nuevo servicio. Voy a llamar a esta app menos test, solo para indicar que esta es una versión de prueba de wrap. Voy a tomar esto aquí. Y sólo voy a copiar la mayor parte de esto. Y no voy a actualizar el punto de entrada. Esto realmente no importa demasiado. Y tampoco necesito un mapeo de puertos porque en realidad no quiero hacer nada con nuestro contenedor de prueba. Y también si utilizo este mapeo de puertos, entonces vamos a tener un conflicto porque ya mapeamos nuestro puerto del sistema a este puerto. Y así el contenedor Docker, y no podemos reasignar el mismo puerto dos veces. Entonces esto en realidad causará problema. Así que tenemos que quitar eso de todos modos. Y voy a ahora en vez de mapear la app, solo la carpeta app, en realidad voy a mapear todo este directorio porque si entramos en un archivo Docker, notarás que en realidad no estamos copiando sobre la carpeta de prueba, pero aún necesitamos tener acceso a eso dentro de un contenedor Docker. Ahora, cuando ejecutemos esto, en realidad tendremos dos contenedores separados funcionando. La primera va a ser tu aplicación que estamos usando actualmente con esta bandera de recarga de barra diagonal, lo que nos permitirá porque estamos mapeando nuestra carpeta aquí a ese lugar dentro del Docker contenedor para hacer desarrollo y mirarlo en nuestro navegador web y poder jugar con él. Este contenedor aquí esencialmente va a ser responsable de solo ejecutar pruebas unitarias contra para que podamos probar nuestro código. ¿Bien? Bien, así que todavía hay algunas otras cosas que debemos encargarnos porque si entramos en nuestro archivo Docker, realmente notamos aquí no instalamos ninguna dependencia de desarrollo y necesitamos las dependencias de desarrollo para poder ejecutar nuestras pruebas unitarias. Entonces ahora lo que tenemos que hacer es que tenemos que actualizar nuestro archivo Docker para que el proceso de instalación que ocurra aquí sea diferente dependiendo de si estamos en nuestra aplicación o si estamos en la aplicación que solo está pensada para ejecutar pruebas. Y entonces hagámoslo primero. Ahora lo que necesitamos es algún tipo de forma de indicar dónde estamos actualmente. Ahora una gran cosa que normalmente harías con esto es usar variables de entorno. Desafortunadamente, no tenemos acceso a los que están dentro de nuestro contenedor Docker, pero podemos proporcionar argumentos de compilación. La forma en que podemos proporcionarlos es mediante, en lugar de simplemente usar esta sintaxis de compilación aquí, realmente podemos expandirnos sobre esto. Y voy a aportar dos palabras clave más. Entonces el contexto nuevamente va a ser donde nuestro archivo Docker o donde vamos a ejecutar esta cosa desde la ubicación, que va a ser simplemente la ubicación actual. Entonces. Ahora aquí también podemos proporcionar argumentos de construcción. Y nuevamente, podemos proporcionar esto como una matriz, mientras que la lista, y vamos a proporcionar el nombre, y luego vamos a proporcionar el valor. Entonces e.g. Puedo llamar a este nombre entorno, entorno y asegurarse de que lo estoy diciendo correctamente. Creo que lo soy. El valor aquí va a ser prueba. Así que sólo voy a hacer un nombre, lo que voy a llamar medio ambiente. Y esta va a ser la prueba de valor. Y ahora necesito hacer algo similar aquí arriba porque no quiero tener dependencias dev instaladas en nuestra aplicación. Y entonces este, voy a llamar a cualquiera de dev o tal vez lo llamaré local. Entonces ahora lo que quiero hacer es aprobar este argumento de proyecto de ley. Ahora necesito poder acceder a él dentro de un contenedor Docker. Y luego quiero actualizar nuestra ejecución aquí para que si lo estamos, si esta variable de entorno aquí es test, también quiero instalar dependencias dev. De lo contrario no lo hago. Bien, entonces lo primero es lo primero, para tener acceso a este argumento del proyecto de ley. Voy a usar esta palabra clave args. Y entonces voy a poner aquí el nombre de esta variable. Esto es ahora voy a darnos acceso a este argumento dentro de nuestra construcción docker aquí. Bien, ahora lo que tenemos que hacer es actualizar esta declaración a condicionalmente y vamos a usar una sentencia if para esto, pero vamos a usar una sentencia bash IF para instalar condicionalmente con dependencias de desarrollo. Si este valor de entorno aquí es prueba para escribir una sentencia if y bash. Y no vamos a entrar en demasiados detalles aquí, realmente solo vamos a pasar por los huesos básicos para tener suficiente para poder hacer esto. Porque la mayoría de las veces que te gustaría no vas a necesitar más que esto. Y si alguna vez lo haces, porque sabes escribir declaraciones condicionales en Python, entenderás la lógica y podrás transferirla a bash. Solo necesitas buscar la sintaxis adecuada. Entonces la sintaxis va a ser si y luego abrir y cerrar corchetes. Y entonces aquí vamos a poner IF. Y para acceder a la variable de entorno en Bash, vamos a necesitar poner el letrero de $1 delante de él. Entonces si el argumento del proyecto de ley, si el valor de este argumento de construcción al que tenemos acceso, porque lo definimos aquí arriba. Si este valor es igual a la prueba de cadena. Ahora una cosa muy importante aquí es tener espacios antes o después y antes de abrir y cerrar estos corchetes. Entonces voy a poner punto y coma aquí. Esto es importante porque si queremos tener más de un comando en la misma línea en Bash, necesitamos separarlos por punto y comas. De lo contrario, estaríamos creando nuevas líneas que también servirían para ese propósito. Pero como íbamos a tener la mayor parte de esto en la misma línea, voy a poner punto y coma aquí. Entonces, si nuestro entorno es test, entonces queremos instalar con dependencias de dev. Entonces entonces queremos hacer lo mismo aquí, pero con dependencias de dev. Nuevamente, dos puntos, porque todo esto está en una línea. Ahora porque vamos a repasar una línea porque no quiero tener esta cosa o como correr hacia el infinito hacia el lado derecho. Pero también podemos ver que aquí tenemos sugerencias como márgenes y no queremos repasar esto. Entonces para continuar una, algo que estaba en la misma línea. Y vamos a entrar en un salto de línea que podemos hacer con la diagonal inversa. Vamos a continuar con esto en la siguiente línea. Y entonces vamos a tener nuestras demás declaraciones. Otro colon aquí. Y luego para terminar esta afirmación, hacemos FI, Entonces lo contrario de f. así que repasemos esto una vez más. ¿Qué hicimos? Creamos un argumento de construcción que estamos proporcionando ya estamos construyendo nuestra imagen con este valor aquí, luego estamos obteniendo acceso al argumento derramado aquí. Y aquí estamos accediendo a su valor. Lo estamos comparando con la prueba de valor usando un solo signo igual aquí. Entonces tenemos una declaración condicional. Entonces, si este valor es test, entonces vamos a hacer esta sentencia install y hemos agregado este menos, menos dev tall, algunas dependencias de stall dev. De lo contrario sólo vamos a hacer nuestra instalación normal. Y luego tenemos algunas cosas especiales de palabras clave aquí. Sólo porque eso es algo así es como se ve la declaración if . Eso es lo que hay que escribirlo. ¿Bien? Bien, así que vamos, bueno, vamos a poner en marcha estos. No lo hacemos, en realidad no estamos ejecutando nuestras pruebas todavía, pero podemos si queremos que así sea. Entonces, si quisiéramos, podríamos, por ejemplo actualizar nuestro punto de entrada aquí para que en su lugar sea algo así como prueba pi y pruebas. Pero vamos a ver una mejor manera de que podamos hacerlo en un segundo. Porque si lo hacemos así, entonces sólo estaremos corriendo de una vez cuando nos pusimos en marcha. Pero lo ideal sería que pudiéramos ejecutar a voluntad. Bien, así que simplemente voy a ejecutar la compilación no en modo David ahora mismo para que podamos ver la salida completa. ¿Correcto? Entonces esta vez va a tomar un poco más de tiempo porque aquí hemos actualizado nuestras declaraciones. Y así ahora ya no vamos del efectivo, sino que tenemos que rehacer esta cosa, que en realidad incluye instalar componentes, obtenerlo de online, descargarlo durante la instalación proceso. Entonces va a tomar un poco más de tiempo, ojalá, no demasiado tiempo porque todo lo demás aún debería ser almacenado en caché. Espera a que eso termine. Bien, entonces nuestra construcción finalmente terminó. Todo está arrancando. Entonces podemos ver aquí este es nuestro primer contenedor funcionando, y este es nuestro segundo. Y aquí realmente podemos ver la salida de las pruebas. Tenemos nueve pruebas que han pasado y el otro contenedor sigue funcionando. Así que sólo voy a bucle, Así que no quiero que haga clic en un enlace aquí en alguna parte. Bien, así que vamos a bajar esto. Bien, así que tenemos que correr. Excelente. Ahora lo que vamos a actualizar es en lugar de simplemente ejecutar estas pruebas una vez. En cambio, lo que vamos a aprender a hacer es que vamos a ejecutar estas pruebas cuando queramos contra sus contenedores. Entonces voy a construir esto, hacer girar esto, facturarlo de nuevo, ejecutarlo y modo daemon. Si ningún código ha cambiado, tampoco es necesario reconstruirlo, lo que obviamente hará que el proceso vaya más rápido. Entonces si lo hacemos así sólo va a hacer girar la imagen existente que hemos construido para ello. O mejor dicho, si agregamos la bandera de compilación, entonces se va a reconstruir. Y aunque todo esté en caché, obviamente todavía lleva un poco más de tiempo. Ahora para ejecutar nuestras pruebas contra este contenedor de pruebas que tenemos aquí, vamos a usar docker ps, dash componer. Y luego vamos a escribir aquí exit exec. Entonces vamos a ejecutar algo contra algo. Nuestro objetivo va a ser este servicio de prueba de app dash que tenemos aquí. Y lo que vamos a ejecutar, el comando que vamos a ejecutar, va a ser pruebas de prueba pi. Así que estamos ejecutando la prueba pi contra nuestra carpeta de pruebas aquí. Si le pego a Enter, y ahí vamos. Entonces estamos haciendo nuestras pruebas. Y ahora esto es realmente agradable porque todo está funcionando dentro de un contenedor Docker. Contamos con varios contenedores Docker. Tenemos dos contenedores separados aquí funcionando. Una de ellas la podemos utilizar para el desarrollo local. Podemos hacer nuestros cambios. Así que solo vuelve a ver esto. Si elimino esto, esto aún debería estar desapareciendo. Y tenemos este mapeo por volúmenes. Tenemos varios contenedores funcionando. Uno de ellos es uno que simula lo que vamos a tener en la producción de desarrollo, excepto que hemos anulado esta bandera para estar recargando. Éste. Aunque nunca copiamos ninguno de los archivos de prueba aquí, porque no los queremos en nuestra imagen final porque aquí usamos un mapeo de volúmenes. De hecho todavía tenemos acceso a todo eso aquí. Porque la forma en que esta carpeta se ve dentro de una imagen de Docker ahora va a ser representada por lo que tenemos aquí localmente. Entonces pudimos usar este comando exec de Docker Compose para ejecutar un comando contra un objetivo específico, que es el nombre que tenemos aquí. Y este es el comando que vamos a ejecutar contra él, lo que significa que cada vez que hagamos cambios, también podemos simplemente hacer nuestros cambios aquí, actualizar nuestras pruebas aquí, y luego cuando ejecutemos a ejecutarlo, solo podemos ejecutar las pruebas en su contra. Y con ese tipo de ejecución nuestras pruebas unitarias y todo está en un entorno Docker reproducible realmente agradable , lo cual es increíble. Y con esta configuración, entonces podremos ver en el futuro, podemos hacer muchas más cosas con ella. Podemos, por ejemplo, agregar variables de entorno similares. Por solo tener un teclado extra aquí, ya podemos ver. Podemos rellenar estas cosas. Podemos agregar servicios adicionales que van a ser como nuestras bases de datos y nuestra caché, por ejemplo, o si realmente está construyendo múltiples servicios que tal vez quieran comunicarse entre sí, en realidad puede tener todos de esos servicios, diferentes servicios que estás construyendo funcionando al mismo tiempo. Para que puedas probarlos a todos como si estuvieran corriendo en vivo en alguna parte. Y esto realmente nos da mucho poder porque somos capaces de simplemente hacer girar todo, dejar que hable entre ellos, y poder probar de una manera muy agradable y reproducible. Entonces sí, Docker Compose. Espero que te resulte útil. Y nuevamente, aquí hay mucho más como argumentos que hemos mirado o que nosotros, que no hemos mirado que proporcionan funcionalidad extra. Y si alguna vez necesitas algo más con más oscuro, entonces solo puedes buscar cuál es el nombre de la variable que necesito proporcionar aquí y ¿cómo puedo ponerlo? Podrás establecer eso y Docker Compose. Y personalmente prefiero esto mucho más porque nuestros comandos aquí son mucho más cortos en comparación con tener estos comandos más largos como Docker. Y nuevamente, podemos definir todo en estos archivos de configuración YAML que alguien más puede simplemente tomar y ejecutar. Mientras que de lo contrario tendrías que enviarles tu copia exacta de, um, qué, a qué comando estás corriendo. Gira tu contenedor a partir de una imagen si estás como proporcionar muchas variables de entorno o algo así. Mientras que con este Docker componer YAML, podemos tener todo esto preconfigurado. Y ojalá alguien más solo debería poder tomar todo esto, girarlo, ejecutar el Docker Compose y poder tener exactamente lo mismo. Y es solo, solo hace que todo sea más fácil en todas partes porque una vez que has llegado a este punto, obviamente es un poco de trabajo llegar hasta aquí. Pero una vez que llegas a este punto, estás en un lugar realmente agradable. Somos capaces de tener cosas reproducibles. Ya sabes, lo que tienes aquí es cómo va a ser cuando lo ejecutes en otro lugar. Es muy fácil hacer cambios, agregar cosas nuevas y mantener todo como reproducible y comprobable y todo por el estilo. Así que una cosa más rápida que quiero mostrarte es que a veces puedes tener, por ejemplo, múltiples archivos de composición Docker. Y esencialmente vamos a tener, voy a crear un nuevo directorio aquí. Voy a llamarlo prueba de deuda, DC. Vamos a asegurarnos de sacar mis contenedores existentes. Ahí vamos. Y entonces sólo voy a mover aquí este archivo de redacción Docker. Entonces digamos que queremos tener diferentes compositores para diferentes escenarios. Si alguna vez necesitas tener algo así, entonces lo que puedo hacer es agregar una bandera menos f a la referencia, donde está eso. Si ejecuto esto ahora no va a funcionar porque no puede encontrar un archivo de composición docker. Pero si agrego una bandera menos f aquí, puedo señalar mi archivo que va a ser intestacy slash Docker, componer, YAML, ese es nuestro nombre de archivo. Y entonces podemos intentar ejecutarlo de nuevo. Y bam, ahí vamos. Funciona. Así que como un rápido aparte en caso de que alguna vez te encuentres con algo así. Obviamente para bajarlo, necesitábamos tener la misma sintaxis aquí para derribarlo. Y probablemente voy a no querer eso aquí. Así de aquí atrás. Obviamente. Esto no es tan agradable como solo tenerlo directamente aquí y así es exactamente cuántos lo guardan. Pero igual que un rápido aparte, si alguna vez te encuentras con algo así, entonces así es como podemos hacer eso también. Pero sí, así que eso es más oscuro. Mucho Docker docker compone. Y aunque hemos hecho mucho trabajo de campo para conseguir lo que aquí, ahora hemos llegado a un punto realmente agradable donde de nuevo, tenemos muy pocos comandos que son muy cortos y legibles que permiten nosotros para construir sistemas muy complejos y hacerlos funcionar de una manera que sea reproducible, lo cual es simplemente súper agradable porque esto puede darte mucha tranquilidad para asegurarte de que la forma en que las cosas están funcionando aquí va a ser la forma en que las cosas estaban funcionando a otra parte. Que es lo que es muy, muy agradable. Sí. Sé que algunas de las cosas pueden ser un poco confusas cuando las miras por primera vez. Lleva algún tiempo jugar con algunas de estas cosas. Tómate un tiempo para jugar con este volumen para entender lo que hace. Echa un vistazo a cada una de las cosas que hicimos aquí. Tal vez intente agregar otro arco de construcción o cambiar el nombre aquí solo para ver qué pasa, para asegurarse de que se sienta más cómodo con él. Pero con el tiempo, te sentirás más cómodo con él. Y también de nuevo, es porque cuando estamos construyendo estas cosas, muchas de estas cosas terminarán pareciendo, por razones obvias. Entonces generalmente te estarás acercando de la misma manera. Y la mayoría de las veces tendrás como plantillas para trabajar, para tener estos archivos docker. Y entonces solo tendrás que adaptar lo que estás copiando y cómo estás haciendo la instalación y etcétera, etcétera. Pero mucho de esto es en realidad como material de plantilla repetitiva. Ya sabes, que puedes reutilizar. Y obviamente queremos pasarlo a detalle una vez solo le enseñé entender correctamente lo que está pasando para que si lo lees o necesitas hacer cambios o adiciones, ya sabes dónde buscar, ya sabes qué buscar. Pero sí, la mayoría de las veces tendrás como una plantilla para trabajar. Ahora tienes una plantilla, puedes tener una plantilla y organización y puedes encontrar plantillas en línea que pueden ayudarte a alcanzar este resultado final mucho más rápido. 6. Makefile: Bien, así que hemos recorrido un largo camino y de hecho hemos logrado llegar a un punto, lo cual es bastante agradable de no tener que escribir tantas cosas para poner las cosas en marcha. Pero con el tiempo, probablemente incluso con esto, te frustras teniendo que escribir una y otra vez las mismas cosas. Y hay más formas que podemos usar para acortar esto. Para tener esencialmente atajos para comandos que estamos ejecutando regularmente. Ahora bien, esto funcionará en un Mac y Linux, creo que para Windows necesitarás hacer alguna configuración extra para que estos makefiles funcionen, que es lo que veremos ahora. Pero en términos generales, si terminas trabajando en alguna organización en alguna parte, es poco probable que estés trabajando en Windows? No sí, no es que sea imposible es simplemente mucho más probable que estés trabajando en una Mac o una Mac o Linux. Así que sí, solo un poco teniendo eso en mente. Vamos a repasar esto ahora porque es común crear archivos makefiles por ti mismo o verlos en otro repositorio. Porque como veremos en un segundo, hará la vida mucho más fácil. Nuevamente, para Windows, hay un, algunas otras cosas que necesitas instalar para que realmente funcionen estos comandos. Buscada, súper importante para conseguir que esto funcione. Así que solo sé consciente de esto, que estas cosas existen y así es como podemos manejarlas. Y puedes crearlos si quieres o puedes dejarlos fuera porque son simplemente cosas bonitas para hacer. Corto. La sintaxis es aún más corta. Pero sí, de todos modos. Bien, así que vamos a crear un nuevo archivo aquí al que vamos a llamar un archivo make como este. Y en este makefile, ahora vamos a definir una serie de comandos que nos van a permitir esencialmente lo que teníamos aquí como el Docker componer dash, dash menos d, sólo para que no tengamos que escribir esto cada vez. Vamos a hacer un atajo que nos va a ejecutar esto. Ahora bien, una cosa muy importante aquí está en, si estás en PyCharm, como yo estoy aquí en este archivo, queremos ir al fondo y dar click en estos cuatro espacios y configurar la resistencia para llanura y use el carácter de tabulación. Porque el Makefile tiene una diferencia muy, muy específica entre cuatro espacios y una tabulación. Mientras que en otros casos, como en Python, por ejemplo , es, realmente no hace mucha diferencia. Entonces está bien usarlo así. Pero en PyCharm encontrarás que he hecho aquí, si estás usando Visual Code, si no estás usando el código visual PyCharm o cualquier otra cosa, lo encontrarás en una ubicación similar probablemente. Pero generalmente, si te encuentras con problemas es decir que falta algún separador o lo que sea. Muy probablemente el tema con el que te estás topando es lo que queremos. Se te olvidó poner un colon, lo que también sucede. Pero a los otros temas muy comunes que estás usando espacios en lugar de grifos. Bien. Te voy a mostrar también en una segunda forma rápida para que veas eso. De hecho, me dejó apagar eso para eso, solo para mostrarte cómo se vería eso. Bien, así que lo primero que queremos hacer es que vamos a definir un comando aquí, que es que solo voy a llamar inicio porque es corto y me gusta. Pero puedes llamarlo como sea, como correr, girar, como sea. Voy a llamarlo inicio. Cuando ejecutamos este comando, lo que queremos tener es esto menos la parte de compilación, así. Ahora, te darás cuenta de que estoy usando espacios ahora mismo porque si vuelvo, vuelvo aquí, notarás que vuelve cuatro veces. Entonces estos son espacios. Y si cambio esto de cuatro espacios a usar un carácter de tabulación en su lugar, elimine esto y presione Tab nuevamente. Ahora cuando voy a la izquierda de la derecha. Entonces este es el personaje superior. Muy gran diferencia para usar espacios aquí. Te vas a encontrar con problemas y es frustrante. Bien, entonces tenemos que empezar. Otra cosa que usamos muy comúnmente es comenzar con build. Entonces voy a llamar a eso start underscore build. Y aquí sólo voy a poner este comando así. Otra cosa que queremos hacer es derribarla. Entonces, o usas takedown, pero esa es una palabra larga, detente más fácil palabra. Y vamos a hacer docker, componer así. Y otra cosa que probablemente queramos hacer regularmente es ejecutar nuestras pruebas unitarias. Podemos llamar a que las pruebas unitarias son pruebas para usar plural porque probablemente estamos ejecutando múltiples pruebas. Y el comando que vamos a ejecutar aquí va a ser el comando que vimos anteriormente. Entonces Docker Compose x menos t y va a ser apto para probar, que está en contra de este contenedor aquí. El comando que estamos ejecutando es pi test, pruebas como esta. ¿Bien? Entonces estos son cuatro comandos que usaremos con bastante regularidad. Y aquí de esto tenemos nuestro Makefile. Hay una cosa que queremos agregar en la parte superior, que es que queremos proporcionar una lista de delitos graves. Lo que esencialmente le dice al makefile que estos son comandos. Y si alguna vez tenemos archivos de estos nombres, que cuando usemos esto con el comando make, que veremos en un segundo que debería tratarlos como comandos. Vamos a poner aquí todos estos comandos que queramos usar. Sólo va a ser inicio que vamos a tener inicio para subrayar construir. Tenemos parada, tenemos pruebas unitarias. Bien, entonces déjame ver si algo está funcionando. Lo es. Entonces voy a hacer, bueno, usemos nuestro comando principal. Entonces tengo a estos dos corriendo todavía de la última vez. Lo que voy a hacer es ahora voy a escribir make stop, que va a ejecutar este comando aquí. Cuando golpeé Enter. Y podemos ver que está ejecutando este comando y está derribando todo. Podemos hacer empezar a correr esto y va a traer las cosas de nuevo para nosotros. Entonces mira aquí, si me refresco, es Aguanta 1 s. ahí vamos. Bien, bajémoslo y paremos . Y ahí vamos. Ahora si me refresco, ahí vamos. Así que ya no corres. Una cosa a tener en cuenta, si no quieres ver estos comandos, podemos agregar en símbolos delante de todo. Ahora, ¿cuándo hacemos parada, o ya ejecuto eso? Lo siento, micrófono, empieza. Ahora no vamos a ver el comando imprimirlo. Así que eso es sólo un poquito para conseguir cosas incluso aquí. Si queremos ejecutar nuestras pruebas unitarias, pruebas unitarias, que va a ejecutarlo contra nuestra aplicación de pruebas aquí, simplemente ejecutando este comando como hemos visto anteriormente. Bam, ahí vamos. Otro comando que tal vez queramos hacer es comprobar nuestro mecanografiado. Así podemos hacer chequeo. Y voy a ejecutar este comando aquí, o corriendo contra nuestro contenedor de prueba. Voy a correr mi pastel así, como hicimos anteriormente. Y entonces podemos hacer chequear tecleando eso a nuestro falso. Y diremos make check typing, que ahora debería verificar el mecanografiado contra nuestro contenedor de pruebas aquí. Mientras esto se está ejecutando, hagamos alguna taquigrafía porque a veces tal vez queremos ejecutar pruebas unitarias aquí en nuestro contenedor. Pero en algunos casos, si tus contenedores docker componen se vuelve muy grande y no quieres tener todas estas cosas funcionando que algo que podrías hacer en cambio es quizás también correr cosas a nivel local. Entonces tal vez a veces simplemente no quieres hacer girar un contenedor porque tal vez también el contenedor solo toma mucho. Entonces, lo que podemos hacer en cambio es también simplemente agregar tipo de alias para esto y luego reutilizarlos. Entonces, por ejemplo, vamos a crear un alias de pruebas unitarias. Y esto de aquí va a ser, perdón, debería haber un igual. Van a ser pruebas de pi como esta. Y ahora si queremos referirnos a como pruebas de prueba pi, en su lugar podemos referirnos a este alias usando el símbolo $1 aquí y luego abrir y cerrar paréntesis alrededor de él. Y así entonces podremos tener nuestras pruebas unitarias como las que teníamos anteriormente. Así. También podemos tener otra que va a ser pruebas unitarias. Local así, que sólo va a ejecutar nuestras pruebas unitarias. Y esto probablemente va a fallar porque no estoy en mi entorno virtual en este momento. Pero vamos a ver. Sí. Entonces sigamos adelante y vayamos a recoger a Penn shell. Y hagamos pruebas unitarias locales otra vez. Voy a abrir una nueva terminal aquí, me metí en un estado raro. Hacer pruebas unitarias, locales. Bien, entonces ahí vamos. Entonces esta es una buena manera cómo podemos reutilizar esto y cosas similares, y sobre todo donde los comandos se alargan. Sundance también es como tienes como comandos que van sobre múltiples líneas, que de nuevo, podemos separar como usando saltos de línea como este. ejemplo, si esto fuera a pasar a una nueva línea, en cambio podría separar eso. Pero si tenemos comandos más largos y a veces también es más agradable simplemente tener un alias para ellos aparece al que podemos hacer referencia aquí abajo. Solo para que, ya sabes, estas cosas se vuelvan más legibles y no se obstruyan tanto. Y sí, eso es lo que estamos haciendo para escribir. Y más, lo siento, no por escribir. Esto es lo que podemos hacer por nuestros makefiles aquí, que nuevamente solo agrega un poco más de simplicidad y hace que sus comandos sean un poco más cortos que hacer que se detenga a derribar o contenedores en su lugar de Docker Compose abajo. Si quiero construir, hago empezar a construir. Acaba de acortar dijo de nuevo. Sólo un poquito. Y si, ese tipo de eso envuelve esto. Hay una cosa más que quería mencionar, no relacionada con nuestros makefiles, que sólo va a estar mirando registros. Algo que me parece bastante fácil de hacer cuando tenemos como un contenedor Docker se está ejecutando es si realmente voy a nuestro escritorio Docker aquí arriba, puedes hacer clic en estos y ver los registros directamente aquí. Pero igual que un rápido aparte, porque realmente no hemos hecho esto, es si quieres mirar los registros y quieres hacer esto a través de la terminal, entonces ahí está el comando docker logs. Entonces, si hacemos referencia a un ID de contenedor, por ejemplo , nuestra aplicación principal, y queremos mirar los registros. Podemos mirarlo así. Phi uno para investigar nuestra aplicación de prueba y simplemente poner ese comando aquí. Ahí vamos. Entonces, obviamente no tenemos muchos registros en estos momentos. Pero por si acaso alguna vez quieras hacer esto y no quieras usar Docker Desktop para esto, entonces también puedes hacerlo a través de la línea de comandos. Ya que estamos haciendo muchas cosas para la línea de comandos. Y a veces esto también puede ser más fácil para ese proceso. Entonces, sí, ojalá, también te resulte útil tener estos makefiles. Probablemente los verás también y siendo usado en cualquier organización a la que te unirás que van a tener como makefiles ahí para solo tener una lista de comandos que hacen un cierto proceso, solo lo hace todo muy fácil solo tener makefiles para esto para que sea aún más fácil de ejecutar y no es necesario que le digas a alguien más cuál es el comando. Simplemente pueden ejecutar el comando make y muy sencillo de escribir. Y nuevamente, una manera muy agradable de conseguir estas cosas reproducibles. Y obviamente hacen que nuestra vida sea mucho más agradable porque tenemos que escribir aún menos.