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.