428 - Mejores prácticas con contenedores Docker
Ultimamente ando haciendo imágenes Docker como si la vida me fuera en ello. Por esta razón he recopilado las mejores prácticas con contenedores Docker
Aunque creo que ya te lo he mencionado anteriormente, lo cierto es que ando confabulando con Dani, de Daniel Primo. Estamos tramando algo. No se exactamente el que, porque los detalles, los maneja él en absoluto secreto, pero ahà andamos. Tampoco creas, que lo que hago es secreto, ni mucho menos, porque prácticamente todo queda en Internet, y en particular, todo lo que hago queda registrado perfectamente en GitHub, para que todo el mundo lo pueda aprovechar, si asà lo considera. Sea, como fuere, lo cierto es que ando haciendo un servicio en Rust, y para utilizarlo con facilidad, lo estoy contenerizando… Creo que esto de contenerizar no está muy bien, pero, vaya, básicamente lo estoy metiendo en un contenedor, y no precisamente de barco, para poder desplegarlo en un VPS y asà poder hacer pruebas tanto él como yo. AsÃ, en estas últimas semanas he estado preocupándome de hacer los contenedores con cariño, y es de aquà precisamente de donde sale esta guÃa de mejores prácticas con contenedores Docker. Si bien, los contenedores los estoy haciendo para un servicio en Rust, lo cierto, es que esta guÃa la puedes aplicar a cualquier contenedor que hagas.
Mejores prácticas con contenedores Docker
Inicialmente esta guÃa está pensada mas para la construcción de imágenes Docker, sin embargo, te recomiendo que la leas al completo aunque no hagas imágenes, y ya te digo que deberÃas, porque te puede ayudar en el uso de contenedores.
Versiona las imágenes
En general estamos muy acostumbrados a no poner etiqueta a las imágenes que utilizamos en nuestros contenedores, o bien a utilizar la etiqueta latest
, que al fin y al cabo es lo mismo.
Sobre esto, ya te he hablado en alguna que otra ocasión, los problemas que me ha traÃdo cuando he hecho actualizaciones con WatchTower.
Está bien tener tu imagen a la última pero hay que ser muy consciente de lo que estás haciendo y de los problemas que esto te puede traer.
Pero sobre todo, para la construcción de tus propios imágenes evita a toda costa utilizar esa etiqueta para el caso de la imagen base. Aquà es mas que fundamental, porque las dependencias de una versión, como bien sabes son distintas de las de otra versión.
Cuidado con el contenido sensible
Ni se te ocurra meter el contenido sensible dentro de tus imágenes. Y cuando hablo de contenido sensible no me refiero a fotografÃas tuyas en la playa, como ya te puedes imaginar. Básicamente me refiero a claves SSH, contraseñas certificados y cualquier otra información que no te gustarÃa encontrarte a lo largo y ancho de internet. Probablemente tampoco te gustarÃa esas fotografÃas.
Sobre todo, tienes que tener especial cuidado en el caso de que tus imágenes estén disponibles en un repositorio público.
En general utiliza utiliza variables de entorno, y en la medida de lo posible procura que estas variables de entorno estén cifradas.
Sin embargo, en el contenedor estarán disponibles, y se pueden ver. Tan sencillo como ejecutar esto,
docker inspect <nombre-del-contenedor> --format='{{range .Config.Env}}{{println .}}{{end}}'
Con este comando obtendrás una bonita lista con todas las variables de entorno que estés utilizando en el contenedor. AsÃ, que lo mejor es que tus contraseñas vayan cifradas, y en tu proceso, las descifres para hacer uso de ellas.
Utiliza un .dockerignore
Al igual que en Git tienes el .gitignore
en el caso de Docker tienes el .dockerignore
. Este archivo se utiliza para definir el contexto de construcción. Antes de evaluar los comandos COPY
y ADD
, el proyecto entero se envÃa a Docker, evita hacerlo para no volverte loco. Esto, me está siendo de especial interés en la compilación de los proyectos en Rust.
En un momento comenzaron a volverse algo imposible de gestionar, pero fue añadir el dockerignore
y mano de santo.
Utiliza un linter
Gracias a Neovim, del cual como bien sabes, estoy completamente enamorado, tengo también un linter
o analizador estático de código para, analizar mis Dockerfiles
, y dejarlos limpitos y aseados.
Por supuesto que analizadores de código no solo hay para Neovim, no te preocupes. Yo lo he estado utilizando en PyCharm y otros fantásticos editores.
El mundo de las multietapas
Este mundo lo conocÃa, pero no lo habÃa utilizado con la profusión con lo que lo estoy haciendo actualmente. Tanto con Python como con Rust, lo estoy haciendo ya de forma habitual.
AsÃ, por ejemplo, en el caso de Rust en concreto, puedes utilizar una etapa preliminar para construir el ejecutable, y solo copias este en la etapa final ese ejecutable. De esta forma te quitas de encima todas las dependencias que aparecen en la construcción de la imagen.
Esto mismo lo estoy utilizando en Python, donde creo un entorno virtual, y luego solo tengo que copiar ese entorno virtual a la imagen final, olvidándome del resto.
Imágenes slim
Esta es otra de las caracterÃsticas que me tienen totalmente obsesionado y la razón de que Alpine Linux se haya convertido en un compañero inseparable de aventuras. Actualmente utilizo la última versión de Alpine Linux, en concreto, en el momento de preparar el podcast es la 3.16 y solo añado aquellas dependencias que me hacen falta.
Por supuesto, respecto a las dependencias, decirte que, como indiqué al principio del podcast, las voy versionando, para evitar encontrarme en una versión con la que mi código no es compatible.
Cuantas menos capas mejor
Aquà es justo lo contrario de lo que sucede en el caso con la ropa. Yo prefiero llevar mas capas que menos, mas que nada, porque si hace frÃo voy preparado, pero si hace calor, no tengo que hacer nada mas que ir quitando capas. Si, en ocasiones, parece que vaya disfrazado, pero *¿y lo calentito que voy?.
En el caso de las imágenes no es nada bueno, porque las capas lo que hacen es aumentar el tamaño final de la imagen resultante por el cacheo. Puedes reducir el número de capas combinando. Esto lo puedes ver fácilmente en mis Dockerfile con los pasos que son RUN
.
COPY mola mas que ADD
COPY
y ADD
no son exactamente iguales. El primero se utiliza para copiar imágenes locales, mientras con ADD
puedes hacer operaciones mas ambiciosas como puede ser descargar archivos externos.
Un proceso un contenedor
Esto es algo que ya he comentado en mas de una ocasión. Lo mas interesante es utilizar un único proceso por cada contenedor. Si necesitas utilizar varios procesos simplemente tienes que combinarlos entre ellos en un docker-compose
, por ejemplo.
Esto te da una serie de ventajas como,
- creas contenedores reutilizables
- Para realizar actualizaciones o parcheos de seguridad es algo relativamente sencillo, dado que solo tienes un proceso.
- Puedes aumentar el número de procesos aumentando el número de contenedores si lo necesitas.
En general, prefiero tener tres contenedores coordinados con un docker-compose antes que uno. Si tengo que actualizar uno de ellos, simplemente, lo que tengo que hacer es descargarlo y levantarlo… y resuelto.
Espero que te haya gustado este nuevo episodio del podcast. Si puedes, te agradecerÃa una valoración en iVoox y/o en Apple Podcast.
Buenas gracias por tus podcast / videos, pero en este caso, cuando dices esbeltas, tendrÃa que ser livianas