Una suave introducción al uso de un contenedor Docker como entorno de desarrollo

Índice
  1. kpero ¿por qué?
  2. VS Code y Remoto – Contenedores
  3. Agregar un contenedor a un proyecto
  4. Automatización de la configuración del proyecto
  5. Automatización de la configuración del entorno
  6. Configuración avanzada
  7. Ve suavemente

Descarga de responsabilidad sobre sarcasmo: este artículo es principalmente sarcasmo. No creo que hable en nombre de Dylan Thomas y nunca te animaría a imponer un tema ligero a personas que no lo quieren. No importa lo equivocados que puedan estar.

Cuando Dylan Thomas escribió las palabras “No entres amablemente en esa buena noche”, estaba hablando de la muerte. Pero si estuviera vivo hoy, podría estar hablando de contenedores de Linux. No hay forma de saberlo con certeza porque falleció en 1953, pero esto es Internet, por lo que me siento muy seguro de hablar con autoridad en su nombre.

Mi confianza proviene de una sobreestimación total de mis habilidades e inteligencia, junto con el hecho de que recientemente intenté configurar un contenedor Docker como mi entorno de desarrollo. Y me encontré furioso contra la muerte de la luz cuando Docker rechazó cada intento que hice como si fuera yo y fuera King James gritando: “¡NO EN MI CASA!”

El dolor es un excelente maestro. Y como me preocupa por usted y no tengo otros motivos ocultos, quiero utilizar esa experiencia para brindarle una introducción “suave” al uso de un contenedor Docker como entorno de desarrollo. Pero primero, hablemos de por qué querrías hacer eso.

kpero ¿por qué?

Cierra los ojos e imagina esto: un hombre adulto vestido como un zorro.

Esperar. No. Escenario equivocado.

En su lugar, imagine un proyecto que contenga no solo su código fuente, sino todo su entorno de desarrollo y todas las dependencias y tiempos de ejecución que necesita su aplicación. Luego, podría entregar ese proyecto a cualquier persona en cualquier lugar (como el tipo zorro) y ellos podrían ejecutar su proyecto sin tener que realizar un mínimo de cambios de configuración en su propio entorno.

Esto es exactamente lo que hacen los contenedores Docker. Un Dockerfile define un entorno de ejecución completo con un solo archivo. Todo lo que necesitarías es una forma de desarrollarte dentro de ese contenedor.

Espéralo…

VS Code y Remoto – Contenedores

VS Code tiene una extensión llamada Remote – Containers que le permite cargar un proyecto dentro de un contenedor Docker y conectarse a él con VS Code. Eso es algo del nivel Inception justo ahí. (¡¿Lo logró?! EL TALISMAN EN REALIDAD NUNCA DEJA DE GIRAR.) Es más fácil de entender si nosotros (y por “nosotros” me refiero a usted ) lo miramos en acción.

Agregar un contenedor a un proyecto

Digamos por un momento que estás en una PC para juegos de alta gama que creaste para tus hijos y luego decides conservarla para ti. Quiero decir, ¿por qué exactamente merecen una computadora nueva nuevamente? Oh, es cierto. No lo hacen. Ni siquiera pueden sacar la basura los domingos a pesar de que LES DICES CADA SEMANA.

Esta es una máquina Windows nueva con WSL2 y Docker instaladas, pero eso es todo. Si intentara ejecutar un proyecto Node.js en esta máquina, Powershell le diría que no tiene la menor idea de a qué se refiere y que tal vez haya escrito mal algo. Lo cual, para ser justos, eres un desastre en ortografía. Recuerda esa vez en 4ᵗʰ grado cuando te eliminaron de la primera ronda del concurso de ortografía porque no sabías eliminar “frito”. ¿FRITO? ¡No hay ninguna “Y” allí!

Ahora bien, esto no es un gran problema: siempre puedes saltarte e instalar Node.js. Pero decimos por un segundo que no te molestas en hacer eso y que estás bastante seguro de que saltar no es algo que hagan los adultos.

En su lugar, podemos configurar este proyecto para que se ejecute en un contenedor que ya tenga Node.js instalado. Ahora, como ya mencioné, no tengo idea de cómo usar Docker. Apenas puedo usar el microondas. Afortunadamente, VS Code configurará su proyecto por usted, hasta cierto punto.

En la paleta de comandos, hay un comando “Agregar archivos de configuración del contenedor de desarrollo…”. Este comando analiza su proyecto e intenta agregar la definición de contenedor adecuada.

En este caso, VS Code sabe que tengo un proyecto de Node aquí, así que elegiré Node.js 14. Sí, soy consciente de que 12 es LTS en este momento, pero será 14 en [ver comprobaciones] uno. mes y soy uno de los primeros en adoptarlo, como lo demuestra mi interés en la tecnología de contenedores justo ahora en 2020.

Esto agregará una .devcontainercarpeta con algunos recursos dentro. Uno es el Dockerfileque contiene la imagen de Node.js que vamos a usar y el otro es el devcontainer.jsonque tiene alguna configuración a nivel de proyecto.

Ahora, antes de tocar algo y romperlo todo (llegaremos a eso, créame), podemos seleccionar “Reconstruir y reabrir en contenedor” en la paleta de comandos. Esto reiniciará VS Code y comenzará a construir el contenedor. Una vez que se complete (lo que puede llevar un tiempo la primera vez si no estás en una PC para juegos de alta gama que tus hijos nunca conocerán), el proyecto se abrirá dentro del contenedor. VS Code está conectado al contenedor, y lo sabes porque así lo dice en la esquina inferior izquierda.

Ahora, si abrimos la terminal en VS Code, Powershell está notoriamente ausente porque ya no estamos en Windows, Dorthy. Ahora estamos en un contenedor de Linux. Y podemos ambos npm instally npm starten esta tierra mágica.

Esta es una aplicación Express, por lo que debería ejecutarse en el puerto 3000. Pero si intenta visitar ese puerto, no se cargará. Esto se debe a que necesitamos asignar un puerto en el contenedor al 3000 en nuestro host local. Como uno lo hace.

Afortunadamente, existe una interfaz de usuario para esto.

La extensión Remote Containers coloca un icono de “Explorador remoto” en la barra de acción. Que está en el lado izquierdo para ti, pero en el lado derecho para mí. Porque yo lo moví y tú también deberías hacerlo.

Hay tres secciones aquí, pero mire la de abajo que dice "Reenvío de puertos", no soy el sándwich con más lechuga, pero estoy bastante seguro de que eso es lo que queremos aquí. Puede hacer clic en "Reenviar un puerto" y escribir "3000". Ahora, si intentamos acceder a la aplicación desde el navegador...

La mayoría de las cosas “simplemente funcionaron”. Pero la configuración también es bastante sencilla. Veamos cómo podemos comenzar a personalizar esta configuración automatizando algunos de los aspectos del proyecto en sí. La configuración específica del proyecto se realiza en el devcontainer.jsonarchivo.

Automatización de la configuración del proyecto

En primer lugar, podemos automatizar el reenvío de puertos agregando una forwardPortsvariable y especificando 3000como valor. También podemos automatizar el npm installcomando especificando la postCreateCommandpropiedad. Y seamos realistas, todos podríamos correr AL MENOS uno menos npm install.

{  // ...  // Use 'forwardPorts' to make a list of ports inside the container available locally.  "forwardPorts": [3000],  // Use 'postCreateCommand' to run commands after the container is created.  "postCreateCommand": "npm install",  // ...}

Además, podemos incluir extensiones de VS Code. El código VS que se ejecuta en el contenedor Docker no obtiene automáticamente todas las extensiones que haya instalado. Tienes que instalarlos en el contenedor, o simplemente incluirlos como lo estamos haciendo aquí.

Extensiones como Prettier y ESLint son perfectas para este tipo de escenario. También podemos aprovechar esta oportunidad para imponer un tema claro a todos porque resulta que los temas oscuros son peores para la lectura y la comprensión. Me siento como un profeta.

// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:// https://github.com/microsoft/vscode-dev-containers/tree/v0.128.0/containers/javascript-node-14{  // ...  // Add the IDs of extensions you want installed when the container is created.  "extensions": [    "dbaeumer.vscode-eslint",    "esbenp.prettier-vscode",    "GitHub.github-vscode-theme"  ]  // ...}

Si se pregunta dónde encontrar esos ID de extensión, aparecen en Intellisense ( Ctrl/ Cmd+ Shift) si los tiene instalados. De lo contrario, busque en el mercado de extensiones, haga clic derecho en la extensión y diga "Copiar ID de extensión". O mejor aún, simplemente seleccione "Agregar a devcontainer.json".

De forma predeterminada, el contenedor Node.js que le proporciona VS Code tiene cosas como git y cURL ya instaladas. Lo que no tiene es "cowsay". Y no podemos tener un entorno Linux sin "cowsay". Eso está en los estatutos de Linux (no lo está). Yo no hago las reglas. Necesitamos personalizar este contenedor para agregar eso.

Automatización de la configuración del entorno

Aquí es donde las cosas se descarrilaron para mí. Para agregar software a un contenedor de desarrollo, debe editar el Dockerfile. Y Linux no tolera sus travesuras o errores.

El contenedor Docker base que obtiene con las configuraciones de contenedor en VS Code es Debian Linux. Debian Linux utiliza el administrador de dependencias apt-get.

apt-get install cowsay

Podemos agregar esto al final del Dockerfile. Siempre que instales algo desde apt-get, ejecuta un apt-get updateprimero. Este comando actualiza la lista de paquetes y repositorios de paquetes para que tenga la lista más actual en caché. Si no hace esto, la compilación del contenedor fallará y le indicará que no puede encontrar "cowsay".

# To fully customize the contents of this image, use the following Dockerfile instead:# https://github.com/microsoft/vscode-dev-containers/tree/v0.128.0/containers/javascript-node-14/.devcontainer/DockerfileFROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-14# ** Install additional packages **RUN apt-get update   apt-get -y install cowsay

Algunas cosas a tener en cuenta aquí...

  1. Ese RUNcomando es cosa de Docker y crea una nueva "capa". Las capas son la forma en que el contenedor sabe qué ha cambiado y qué debe actualizarse en el contenedor cuando lo reconstruya. Son como capas de pastel, excepto que no quieres muchas porque los pasteles enormes son increíbles. Los contenedores enormes no lo son. Deberías intentar mantener la lógica relacionada junta en el mismo RUNcomando para no crear capas innecesarias.
  2. Eso denota un salto de línea al final de una línea. Lo necesita para comandos de varias líneas. Déjelo así y sabrá el dolor de muchas compilaciones fallidas de Docker.
  3. Así es como agregas un comando adicional a la RUNlínea. Por el amor de Dios, no lo olvides en la línea anterior.
  4. La -ybandera es importante porque, de forma predeterminada, apt-get le pedirá que se asegure de que realmente desea instalar lo que acaba de intentar instalar. Esto hará que la construcción del contenedor falle porque no hay nadie ahí para decir Yo N. La -ybandera es una abreviatura de "no me molestes con tus tontas indicaciones de confirmación". Aparentemente todo el mundo debería saber esto ya. No lo supe hasta hace unas cuatro horas.

Utilice el símbolo del sistema para seleccionar "Reconstruir contenedor"...

Y así, sin más…

No funciona.

Esta es la primera lección de lo que me gusta llamar "Linux Vertigo". Hay tantas distribuciones de Linux y no todas manejan las cosas de la misma manera. Puede resultar difícil descubrir por qué las cosas funcionan en un lugar (Mac, WSL2) y no funcionan en otros. La razón por la cual “cowsay” no está disponible es que Debian coloca “cowsay” /usr/games, que no está incluido en la PATHvariable de entorno.

Una solución sería agregarlo al PATHDockerfile. Como esto…

FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-14RUN apt-get update   apt-get -y install cowsayENV PATH="/usr/games:${PATH}"

EXCELENTE. Estamos resolviendo problemas reales aquí, amigos. A la gente le gustan las frases ingeniosas sobre vacas. Creo que lo he encontrado en alguna parte.

En resumen, la configuración del proyecto (reenvío de puertos, instalación de dependencias del proyecto, etc.) se realiza en devcontainer.jsonel "Dockerfile" y la configuración del entorno (instalación de software). Ahora seamos valientes y probemos algo un poco más atrevido.

Configuración avanzada

Digamos por un momento que tienes una configuración de terminal hermosa y glamorosa que también quieres poner en el contenedor. Quiero decir, sólo porque estés desarrollando en un contenedor no significa que tu terminal tenga que ser aburrido. Pero tampoco querrás volver a configurar tu pretenciosa configuración zsh para cada proyecto que abras. ¿Podemos automatizar eso también? Vamos a averiguar.

Afortunadamente, zsh ya está instalado en la imagen que obtienes. El único problema es que no es el shell predeterminado cuando se abre el contenedor. Hay muchas formas de hacer que zsh sea el shell predeterminado en un escenario normal de Docker, pero ninguna de ellas funcionará aquí. Esto se debe a que no tienes control sobre la forma en que se construye el contenedor.

En su lugar, vuelva a consultar el devcontainer.jsonarchivo confiable. En él hay un "settings"bloque. De hecho, ya hay una línea que muestra que el terminal predeterminado está configurado en "/bin/bash". Cambie eso a "/bin/zsh".

// Set *default* container specific settings.json values on container create."settings": {  "terminal.integrated.shell.linux": "/bin/zsh"}

Por cierto, puedes configurar CUALQUIER configuración de VS Code allí. Como, ya sabes, mover la barra lateral hacia el lado derecho. Ahí, te lo arreglé.

// Set default container specific settings.json values on container create."settings": {  "terminal.integrated.shell.linux": "/bin/zsh",  "workbench.sideBar.location": "right"},

¿Y qué hay de esos complementos pretenciosos que te hacen mejor que los demás? Para aquellos necesitarás tu .zshrcarchivo. El contenedor ya tiene oh-my-zsh y está en la carpeta "raíz". Solo necesita asegurarse de establecer la ruta ZSHen la parte superior .zshrcpara que apunte a la raíz. Como esto…

# Path to your oh-my-zsh installation.export ZSH="/root/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will# load a random theme each time oh-my-zsh is loaded, in which case,# to know which specific one was loaded, run: echo $RANDOM_THEME# See https://github.com/ohmyzsh/ohmyzsh/wiki/ThemesZSH_THEME="cloud"
# Which plugins would you like to load?plugins=(zsh-autosuggestions nvm git)
source $ZSH/oh-my-zsh.sh

Luego puede copiar ese .zshrcarchivo sexy a la carpeta raíz en el Dockerfile. Puse ese .zshrcarchivo en la .devcontainercarpeta de mi proyecto.

COPY .zshrc /root/.zshrc

Y si necesita descargar un complemento antes de instalarlo, hágalo en Dockerfile con un RUNcomando. Solo recuerde agruparlos todos en un solo comando, ya que cada uno RUNes una capa nueva. Ahora eres casi un experto en contenedores. El siguiente paso es escribir una publicación de blog al respecto e instruir a las personas sobre los métodos de Docker como si usted lo hubiera inventado.

RUN git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

¡Mira la hermosa terminal! ¡Mirad los colores! ¡El complemento de git que te indica la rama y agrega un emoji de relámpago! Nada dice “sé lo que estoy haciendo” como un terminal personalizado. Me gusta llevar el mío a Starbucks y dejar que la gente lo vea en acción y se pregunte si soy una celebridad.

Ve suavemente

Ojalá hayas llegado a este punto y hayas pensado: “Caray, este tipo está exagerando. Esto no es tan difícil”. Si es así, te he salvado exitosamente. De nada. No tienes que agradecerme. Sí, tengo una lista de deseos de Amazon.

Para obtener más información sobre Remote Containers, incluido cómo hacer cosas como agregar una base de datos o usar Docker Compose, consulte los documentos oficiales de Remote Container, que brindan mucha más claridad con un 100% menos de comentarios neuróticos.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion