Desplegar una aplicación web desde GitHub: Python, Node, Go, Java o un sitio estático

Escribir un programa es una cosa; ponerlo en marcha en algún sitio que otras personas puedan abrir es otra, y es la parte a la que un aula normalmente no llega en absoluto. Aquí un alumno puede desplegar desde un repositorio público de GitHub, sin cuenta en la nube ni tarjeta, y un profesor puede pedir una aplicación desplegada como entrega de un trabajo.

Se pueden desplegar Python, Node, Go, Java y sitios estáticos en HTML, CSS y JavaScript. Es para aprender y hacer demostraciones, no para alojar servicios en producción: dura lo suficiente para enseñárselo a un profesor, compartirlo con unas pocas personas o entregar un enlace, y deliberadamente no lo suficiente para mantener un servicio en marcha.

Empezar por un ejemplo

En la página «Despliegues» hay una aplicación de ejemplo: File uploads, en Node, Python, Go y Java, la misma en cada lenguaje para poder compararlos. Subes un archivo, se guarda en S3 y dónde ha ido a parar se registra en Postgres. Pulsa «Desplegar este ejemplo» y se crea para ti todo lo que necesita, una base de datos y un entorno en la nube, y la aplicación se pone en marcha ya conectada a las dos. No hay nada que preparar antes ni ninguna cadena de conexión que copiar. «Rellenar el formulario» está para el otro caso: cambiar el repositorio o la rama antes de ponerla en marcha.

Se ve sin haber iniciado sesión, para que quien esté decidiendo si vale la pena dar una dirección de correo electrónico pueda ver primero una aplicación real funcionando. No se crea nada hasta que alguien pulsa el botón, así que no consume tiempo de aplicación de nadie. Un alumno que ya tiene una base de datos o un entorno en la nube recibe el que ya tiene en lugar de uno nuevo.

El código es público y merece la pena leerlo: es breve, y el README explica las tres cosas en las que los alumnos se equivocan primero: dirigirse a S3 por ruta en lugar de por nombre de host, crear su propio bucket porque el entorno en la nube empieza vacío, y escribir el archivo en S3 antes que la fila en la base de datos, para que un fallo nunca deje en la página un archivo que no se puede abrir.

Si prefieres no verlo, pulsa «Ocultar» en su fila y no se te volverá a ofrecer.

Probarlo sin cuenta

Nadie necesita una cuenta para ver la aplicación funcionando. Pulsar «Desplegar», o «Crear» en la pestaña «Base de datos» o «Nube», crea una cuenta temporal en ese navegador y inicia sesión con ella. Un invitado tiene límites propios, que un administrador del sistema puede cambiar: su cuenta se conserva 24 horas desde la última vez que se usó, cada despliegue se ejecuta como máximo 30 minutos, y puede hacer 2 despliegues en total y tener 1 base de datos, con un entorno en la nube aparte que no cuenta para el límite de bases de datos.

Un invitado no puede invitar a nadie a ver una aplicación, porque una invitación es un enlace que envía una persona con nombre, ni desplegar un repositorio privado, porque un token guardado en una cuenta a la que nadie puede volver no se podría retirar nunca. «Conservar esta cuenta» pide una dirección de correo electrónico y un código, y hace de esa misma cuenta la suya, con todo lo que desplegó. Un invitado al que nadie vuelve se elimina con sus aplicaciones, sus bases de datos, sus archivos y sus laboratorios de contenedores guardados.

Lo que indica el alumno

Un repositorio de GitHub y una rama, el lenguaje, un comando de compilación y un comando de inicio. El cuadro ya contiene algo que se despliega: el último repositorio del alumno o, si nunca ha desplegado, uno nuestro para el lenguaje elegido (hello-flask, hello-node, hello-go, hello-spring o hello-static), así que el primer intento funciona y el segundo es cosa suya. Cambiar de lenguaje sustituye un ejemplo por otro y nunca borra lo que el alumno haya escrito.

También funciona con un repositorio privado. Marca «Este repositorio es privado» debajo del cuadro del repositorio y pega un token de GitHub: un fine-grained personal access token, limitado a ese único repositorio, de solo lectura y con fecha de caducidad. Se guarda cifrado, nunca se vuelve a mostrar a nadie y solo se usa para obtener el código. Nunca llega a la aplicación en ejecución, así que nada de lo que despliegue el alumno puede leerlo, y quien califica el trabajo lo usa para compilar la aplicación sin verlo nunca. Desmarca la casilla para retirarlo.

Los ajustes que la aplicación lee de su entorno se indican en el mismo formulario, en filas con un nombre y un valor: como máximo 20, de hasta 4 KB cada una. PORT y los nombres propios del entorno de ejecución se rechazan. Se guardan cifradas y, una vez guardadas, no se muestran a nadie: la página muestra puntos, con «Reemplazar» y «Quitar». Una entrega apunta al despliegue guardado, así que quien la califica despliega la aplicación con las variables del alumno y solo ve sus nombres. Una DATABASE_URL escrita junto a una base de datos elegida en el formulario se rechaza, con una frase que indica cuál quitar.

La aplicación tiene que escuchar en el puerto que se le asigna, que es la única lección de verdad del ejercicio y la que todas las plataformas de alojamiento enseñan por las malas.

Dos casillas del mismo formulario amplían lo que puede hacer la aplicación: una base de datos propia y un entorno en la nube con un almacén de objetos, una tabla NoSQL y una cola de mensajes. Las dos se inician con la aplicación y definen sus propias variables, así que un trabajo puede pedir una aplicación que guarde lo que la gente sube en lugar de una que solo muestre una página.

El formulario de despliegue: un repositorio de GitHub, una rama, un lenguaje, un comando de compilación y un comando de inicio
Un repositorio, un comando de compilación y un comando de inicio. El ejemplo que viene en los cuadros se despliega tal cual.

Qué lenguajes

Se pueden desplegar Python, Node, Go, Java y sitios estáticos en HTML, CSS y JavaScript, y nada más: cada uno se compila y se ejecuta en un contenedor para ese lenguaje, con acceso al registro de paquetes de ese lenguaje y a nada más. Python se ejecuta con gunicorn, así que funcionan tanto Flask como Django; en Node se ejecuta lo que indique su script de inicio; Go y Java se compilan desde el código fuente, Java como una aplicación de Spring Boot; un sitio estático se sirve exactamente como está en el repositorio.

Cada lenguaje tiene ya en el formulario un repositorio de ejemplo nuestro que funciona, para que un alumno que nunca ha desplegado nada tenga por dónde empezar.

Un sitio estático es el más restringido: no instala nada, así que su compilación solo llega a GitHub y a ningún otro host. Su comando de compilación comprueba que haya un index.html en la raíz del repositorio, porque unas páginas guardadas en docs/ o dist/ se desplegarían sin error y luego mostrarían un listado de archivos. Para servir una subcarpeta, añade --directory y su nombre al comando de inicio en lugar de mover las páginas.

Dónde se ejecuta y quién puede verla

Cada aplicación recibe una dirección propia bajo learntools.dev: dos palabras y un número, o un nombre que el alumno elige y conserva, para que un enlace que ponga en su currículum siga funcionando la próxima vez que despliegue. Una dirección elegida sigue siendo suya hasta que la elimina, y nadie más puede quedarse con una que esté reservada.

Nadie llega a una aplicación adivinando la dirección. El alumno invita por correo electrónico a un máximo de 5 personas; cada una sigue un enlace y confirma un código enviado a esa misma dirección, así que una invitación no se puede reenviar. La forma de entrar del propio alumno está en su página.

El personal puede detener una aplicación. Un administrador del sistema puede detener cualquier aplicación, base de datos o entorno en la nube; cualquier miembro del personal de un centro puede detener una que pertenezca a un alumno de ese centro, no solo el administrador del centro, porque a quien le llega una queja es a quien da la clase. Antes, lo único que detenía una aplicación eran sus propios límites de tiempo, lo que no sirve de nada cuando algo tiene que retirarse ya.

Detener es solo detener. Los datos guardados se quedan, la dirección se queda y el alumno puede volver a iniciarla; quitarle a alguien su trabajo es otra cosa y nadie puede hacerlo. Cada vez que alguien que no es el propietario la detiene, queda anotado en las páginas de «Despliegues», donde el alumno lee la misma entrada que el personal, y en el propio registro de administración del centro.

Cuánto tiempo se ejecuta

Una aplicación funciona al menos una hora y sigue mientras haya sitio, hasta 4 horas; se detiene tras 30 minutos sin visitas y cada cuenta tiene 8 horas de tiempo de aplicación al día.

Es para aprender y hacer demostraciones, no para alojar servicios en producción: dura lo suficiente para enseñárselo a un profesor, compartirlo con unas pocas personas o entregar un enlace, y deliberadamente no lo suficiente para mantener un servicio en marcha.

La página indica cuánto queda del día antes de desplegar nada, muestra las últimas líneas que ha escrito la aplicación mientras se ejecuta y conserva su registro durante tres días después de que se detenga, que es cuando más se quiere leer.

Pasado su tiempo garantizado, una aplicación sigue ejecutándose mientras nadie más necesite el sitio, y es la primera en detenerse cuando alguien lo necesita: un despliegue que llega a una máquina llena detiene la aplicación que lleva más tiempo ejecutándose, y solo una que ya haya superado su tiempo garantizado. Una quinta cifra cuenta compilaciones en lugar de minutos, 20 despliegues al día por defecto, porque una compilación cuesta lo mismo aunque la aplicación viva después un minuto o una hora, y un alumno que vuelve a desplegar con cada commit es lo que pone en cola a una clase. Un administrador del sistema fija todas estas cifras para toda la plataforma y para cada centro.

Solo hay una aplicación a la vez. Mientras la actual no se haya detenido, el botón «Desplegar» está desactivado, y la página indica si está en cola, con cuántas hay delante, compilándose, en marcha o deteniéndose. Una aplicación que se detiene sola se notifica con su propia última salida, aparte de la que no se pudo compilar, para que nadie tenga que revisar un registro de compilación por un fallo de su programa. Las últimas diez líneas que imprimió se actualizan más o menos una vez por minuto, el registro completo se puede descargar, y los despliegues anteriores forman una tabla: cuándo fue, en qué lenguaje, desde qué repositorio, cómo terminó y su registro.

Una base de datos junto a la aplicación

La pestaña «Base de datos», junto a «Aplicación» en «Despliegues», permite a un alumno crear hasta tres bases de datos propias, de hasta 10 MB cada una: PostgreSQL o MySQL como servidor, o SQLite como archivo. Elegir una en el formulario de despliegue inicia el servidor con la aplicación y hace que DATABASE_URL apunte a él, así que el código que escribieron contra SQLite en un portátil lee aquí la misma variable; un archivo SQLite se coloca dentro de la aplicación y se vuelve a guardar cuando la aplicación se detiene.

No se le pide a nadie que le ponga nombre. Una base de datos toma el nombre de la dirección en la que responde la aplicación del alumno, con una palabra que indica cuál de las dos es: una aplicación en sams-shop.learntools.dev recibe una base de datos llamada sams_shop_db y un entorno en la nube llamado sams-shop-cloud. El nombre de una base de datos es un nombre SQL, así que los guiones de la dirección pasan a ser guiones bajos, que es lo que todos los motores y todos los controladores aceptan tal cual. Un entorno en la nube conserva sus guiones, porque su nombre pasa a ser el de un bucket de almacenamiento, que no puede contener un guion bajo. Una segunda base de datos a partir de la misma dirección se numera, sams_shop_db_2; una dirección que empieza por una cifra toma primero la palabra, db_2048_game; y quien aún no ha desplegado nada recibe db_1 o cloud-1. El formulario indica lo que va a crear antes de pulsar el botón.

Un servidor se ejecuta exactamente el mismo tiempo que la aplicación, y sus datos se guardan cuando se detiene y se restauran cuando se inicia. Solo una aplicación desplegada aquí puede acceder a él; la página muestra los datos de conexión para que un alumno pueda leer lo que significa la variable. Quien califica una aplicación entregada recibe con ella la base de datos del alumno, con sus datos, y no puede cambiar lo que hay guardado.

Cada base de datos tiene «Iniciar», «Detener», «Descargar» y «Eliminar». Un servidor se puede iniciar por sí solo, y los datos guardados se descargan como un volcado .sql, o como el archivo .sqlite en el caso de SQLite, que la aplicación encuentra en /data, con el nombre de la base de datos (/data/sams_shop_db.sqlite, por ejemplo), y con su ruta en DATABASE_PATH. Un servidor en marcha tiene un botón «Consulta» que abre las mismas pestañas Consulta y Esquema que el entorno de pruebas de SQL, contra la base de datos real y con el propio rol del alumno; la pestaña Esquema es de solo lectura ahí. Eliminarla se rechaza mientras se ejecuta o mientras la nombre un despliegue entregado, y un despliegue que no se ha entregado simplemente la pierde y se despliega sin ella. Al llegar al límite de 10 MB, un servidor pasa a solo lectura y la página indica que los últimos cambios no se guardaron. Las credenciales se generan, nunca se eligen, y la contraseña se guarda sellada: la página muestra la URL, el host, la base de datos y el usuario, y la contraseña cuando se pide.

Una sola sesión: la aplicación, una base de datos, un entorno en la nube y un terminal

«Despliegues» es un solo elemento de la barra, con pestañas «Aplicación», «Base de datos» y «Nube», y cada pestaña dibuja arriba la misma imagen de la sesión del alumno: una red privada con la aplicación, una base de datos, un entorno en la nube y un terminal, y cada hueco indica lo que contiene. Todo lo que se ejecuta llega a lo demás por nombres fijos, app, db y cloud, así que la configuración de un tutorial funciona tal cual y no hace falta ninguna URL.

«Abrir el terminal», en cualquiera de las pestañas, inicia una consola junto a la sesión con psql, mariadb, aws y curl ya apuntando a su base de datos, su entorno en la nube y su aplicación. Hay un terminal por sesión y cuenta como tiempo de base de datos. Su carpeta personal va con la sesión: lo que perdura es lo que el alumno puso en la base de datos o en el bucket.

Como trabajo evaluable: entregar una aplicación desplegada

Un trabajo escrito puede pedir una aplicación desplegada en lugar de un archivo. El enunciado lo escribes tú como siempre; lo que cambia es la entrega.

  1. Configurar el trabajo. En «Qué hay que entregar», elige «Una aplicación desplegada» y después en qué lenguaje deben desplegar los alumnos.
  2. El alumno despliega. La página de su tarea muestra «Desplegar tu aplicación», que abre la página de despliegue con ese lenguaje ya elegido. Despliega, comprueba que funciona y pulsa «Entregar».
  3. Qué se entrega. El despliegue completo: su nombre y cada aplicación que contiene, con el repositorio, la rama y los dos comandos con los que se ejecutó. Un alumno con un front-end y una API entrega un solo trabajo, no dos. Se guarda con la tarea como cualquier otra entrega: se califica, se devuelve y se versiona de la misma forma.
  4. Calificarla ejecutándola. Abre su trabajo y pulsa «Desplegar aplicación». La misma aplicación vuelve a ponerse en marcha en una dirección propia, y desplegar las entregas de toda una clase no gasta tu propia cuota diaria de tiempo de aplicación. Cuando el despliegue contiene varias aplicaciones, cada una aparece con su propio enlace, y se ponen en marcha de una en una.

Calificar un despliegue, y límites para un concurso

Una entrega no tiene por qué ser un despliegue que funcione. Un alumno cuya compilación no funciona puede entregar igualmente y explicarlo en la conversación; lo que se rechaza es un repositorio o una rama que la propia página de despliegue rechazaría, de modo que lo entregado es al menos algo que se podría compilar.

Quien la califica no tiene límite diario de tiempo de aplicación, y solo para el trabajo que está calificando: poner en marcha veinticinco entregas agotaría la cuota del propio alumno en las primeras, así que los minutos del día y la regla de una sola aplicación a la vez ceden, y la página lo dice. El tope de la sesión no cede, así que una aplicación olvidada acaba terminando, y un profesor que despliega una idea propia está sujeto a los límites ordinarios como cualquiera.

Una tarea puede fijar límites propios, que es para lo que sirve un concurso o un examen. Su pestaña de ajustes pide cuántos despliegues permite y cuánto vive después cada aplicación. Se cuentan dentro del propio cronómetro de la tarea, así que quien empieza tarde tiene su propia ventana, y se aplican a cada aplicación que ese alumno despliegue mientras el cronómetro corre, no solo a las que diga que son para la tarea. Una tarea solo puede acortar lo que permite el centro.

Preguntas frecuentes

¿Qué lenguajes se pueden desplegar?
Se pueden desplegar Python, Node, Go, Java y sitios estáticos en HTML, CSS y JavaScript. El alumno puede editar los comandos de compilación y de inicio dentro de ese lenguaje, y un repositorio en cualquier otro no se compilará.
¿Es un servicio de alojamiento?
No. Es para aprender y hacer demostraciones, no para alojar servicios en producción: dura lo suficiente para enseñárselo a un profesor, compartirlo con unas pocas personas o entregar un enlace, y deliberadamente no lo suficiente para mantener un servicio en marcha. Una aplicación se detiene sola, y un alumno la vuelve a desplegar cuando la necesita de nuevo, en la misma dirección si eligió una.
¿Puede la aplicación tener una base de datos?
Sí. PostgreSQL o MySQL como servidor que se ejecuta junto a la aplicación, o SQLite como archivo que se coloca dentro de ella, de hasta 10 MB cada una y tres por alumno, creadas en la pestaña «Base de datos» y elegidas en el formulario de despliegue, que define DATABASE_URL. Un servidor se ejecuta el mismo tiempo que la aplicación y conserva sus datos entre ejecuciones. Solo puede acceder a él una aplicación desplegada aquí, no un portátil.
¿Se puede probar sin cuenta?
Sí. Pulsar «Desplegar» crea una cuenta de invitado temporal en ese navegador, con límites propios, y «Conservar esta cuenta» la convierte en una cuenta de verdad con una dirección de correo electrónico y un código, conservando todo lo que desplegó.
¿Puede una aplicación tener secretos, como una clave de API?
Sí. El formulario de despliegue admite hasta 20 filas de nombre y valor, guardadas cifradas y que no se vuelven a mostrar una vez guardadas. Llegan a la aplicación en ejecución como variables de entorno, y un profesor que califica el trabajo solo ve sus nombres.
¿Necesita el alumno una cuenta de GitHub?
Necesita un repositorio al que apuntar, lo que en sí mismo merece la pena enseñar: el control de versiones y el despliegue son la misma lección. Puede ser público o privado; uno privado se despliega pegando un token de GitHub de solo lectura, que se guarda cifrado y no se muestra a nadie.
¿Pueden los alumnos elegir la dirección?
Sí, en «Crear una aplicación», que es donde ponen nombre al trabajo y eligen la dirección en la que responde: un nombre propio, con letras minúsculas, cifras y guiones, que nadie más tenga y que no sea una de las palabras reservadas. El formulario de despliegue que hay debajo no pide ninguna de las dos cosas, así que la decisión se toma una sola vez. Sigue siendo suya hasta que la eliminan de la tabla de despliegues guardados que hay debajo del formulario, que es también lo que permite que otra persona la use.
¿Puede un alumno volver a poner en marcha la misma aplicación sin rellenar otra vez el formulario?
Sí. Cada fila de la tabla de despliegues guardados que hay debajo del formulario tiene «Volver a desplegar», que vuelve a poner en marcha exactamente ese repositorio, esa rama, esos comandos y esas variables en la misma dirección con una sola pulsación. «Usar» sigue ahí para el otro caso: cambiar algo antes. No pregunta nada antes de hacerlo, porque «Detener» es la forma de dar marcha atrás; lo único que avisa de antemano es que un despliegue sin dirección propia vuelve en una nueva, así que un enlace antiguo deja de funcionar. Un despliegue entregado para un trabajo se puede volver a poner en marcha de esta forma y no se puede cambiar de ninguna otra, que es exactamente lo que aquí significa de solo lectura.
¿Puede un centro desactivarlo?
No se puede desactivar, pero sí limitar. Un administrador del sistema fija cinco cifras para toda la plataforma y para cada centro: cuánto tiempo se garantiza a una aplicación, el máximo que puede ejecutarse, cuánto tiempo puede seguir sin que nadie la use, el total del día y cuántos despliegues al día; cada una se puede bajar hasta unos pocos minutos o un solo despliegue.
¿Qué pasa cuando se detiene?
La aplicación desaparece y su registro se conserva tres días. Una dirección elegida se conserva, así que volver a desplegar pone la aplicación en el mismo enlace; una aleatoria, no.
¿Puede un profesor retirar la aplicación de un alumno?
Sí. Cualquier miembro del personal del centro puede detener la de uno de sus alumnos, y un administrador del sistema la de cualquiera, así que una queja sobre algo que un alumno ha publicado tiene a alguien que puede actuar ese mismo día. Detiene la aplicación en lugar de eliminar nada: los datos y la dirección se quedan y el alumno puede volver a iniciarla. El alumno ve quién la detuvo y cuándo, en la misma página desde la que despliega.