node.js: no, no y no…

Llevo en esto de la programación desde que tenía 11 años (y ya tengo casi 51) por lo que he tenido que aprenderme muchos lenguajes y trabajar con muchos entornos en mi carrera (Vale, de los 11 a los 18 todo era BASIC, pero luego…). Por poner un ejemplo, aprendí C en 1989 y sigo usándolo a día de hoy ¡Bendita IoT! y siempre he sido partidario de respetar todos los lenguajes y todos los entornos, ya que si alguien se ha tomado la molestia de crear un nuevo lenguaje, bueno, pues por algo será…

Lo que vengo a decir aquí es que no todos los lenguajes, frameworks o entornos sirven para todo y eso es algo que hay que evaluar antes de meterse a implementar un proyecto con todo lo que ello conlleva. Yo, particularmente, he hecho proyectos (que algunos siguen en producción a día de hoy) en casi cualquier lenguaje, desde cy c++ hasta Dart pasando por objective-c (sniff), java, javascript, python, php, swift y cosas más raras con usos más limitados (mira que se han hecho maravillas con ruby y no le encuentro todavía el punto), el caso es que no tengo una especial predilección por ninguno y programo en lo que creo más adecuado para el proyecto… Y aquí viene el tema, si quieres hacer un proyecto que envejezca bien NO LO HAGAS EN NODE

Entendedme bien, el concepto de node es brillante, el tomar un lenguaje construido en base a ñapas, una encima de otra, que tarda decenios en estandarizar las cosas más básicas y que tiene a una legión incansable de programadores generando frameworks y librerías que se pueden medir en frameworks por hora y sacarlo del navegador me parece bien. Hacer un repositorio central del librerías que cualquiera puede utilizar y que permita respetar las dependencias me parece bien también y te permite hacer cosas muy complejas en muy poco tiempo… Eso si, no quieras hacerlas durar en el tiempo…

Yo no tengo muchos proyectos en node (¡Gracias a Dios!) pero os pondré como ejemplo uno que terminé hace tres años… O eso creía yo. Es un proyecto hecho en node para el escritorio, que usa electron como motor (y se han hecho cosas simplemente magistrales con electron, como visual studio code) y unas pocas librerías de criptografía y acceso a blockchain (si, habéis acertado, es una aplicación de criptomonedas). Este proyecto, muy bien programado y probado en 2019 lo dejé aparcado (pero disponible para quien quisiera usarlo) y con el boom de las criptomonedas en 2020 quise volver a usarlo… Pero resulta que no solo ya no compilaba sino que no ejecutaba porque las librerías subyacentes se habían actualizado y sin ningún criterio de compatibilidad hacían que objetos que antes tenían ciertos métodos ahora no los tuviesen o la forma de llamar a las cosas en alguna librerías fuesen distnitas… Bueno, cosas que pasan, me pongo a intentar actualizar las dependencias de esas librerías y a cambiar el código afectado (cosa nada fácil lidiando con un año de cambios en el universo js) y consigo volver a compilar y empaquetar el programa (mediados de 2020)… Dejamos todo funcionando y, como somos gente de pocos recursos y trabajamos lo justo con criptomonedas, no volvemos a tocarlo hasta hoy… Dia en el que me encuentro que una librería de mi sistema no funciona con el electron de antes… Y el electron nuevo ha cambiado cosas fundamentales que me obligaran a cambiar todo el código… Y ya no se si estoy con ánimos para hacerlo.

Y esto es así porque el sistema de npm y node no exigen nada a nadie y hay muchos programadores (muchos más en el mundo js que en el resto del universo conocido) que tienen la santa manía de refactorizar cosas y no pensar en el mantenimiento de lo que se ha escrito sino en la virguería que se conseguirá con la siguiente versión…. Así pues, si queréis crear un sistema mantenible que no tenga que actualizarse cada semana con las últimas librerías y tengas que estar investigando qué es lo que han cambiado los mantenedores de ese paquete, por faor, usa cualquier otra cosa que no sea node

Para un prototipo está bien, para todo lo demás, usa algo distinto.

Dale nueva vida a tu viejo macbook pro

Aunque yo no soy muy fan de apple en nada (como podréis ver si miráis un poco en este blog), el hecho es que tuve que gastarme una cantidad ingente de dinero en comprarme un macbook pro en 2011 para tener la oportunidad de empezar a programar aplicaciones para iOS. Entonces no había otra manera, ahora, por suerte, si que la hay como podéis ver en este mismo blog.

Es la mayor inversión que he hecho nunca en un ordenador y, aunque mac os no es que sea el mejor sistema del mundo, el hardware si que estaba muy cuidado, la carcasa en aluminio y el teclado retroiluminado y amplio (además de una pantalla muy brillante) me hicieron tenerlo como portatil principal durante muchos años. Pero la obsolescencia programa de apple terminaría por llamar a la puerta. Primero fue el chip de la GPU que, aparentemente por exceso de calor, terminó por romperse y me obligaron a comprarme toda una nueva placa madre (coste superior a un portatil completo que no fuese apple), pero es que no contentos con esto dejaron de actualizar el sistema operativo en High Sierra y ya me he perdido 3 grandes actualizaciones. Después de que la «nueva» GPU terminase por romperse de nuevo decidí dejar de usarlo por un tiempo… Hasta ahora que he decidido ponerle un arranque dual y tener ubuntu y os x (lo que me permita apple) en el mismo ordenador (ahora mismo estoy escribiendo esto desde ubuntu en el macbook pro). Os comento en este post algunas cosas a hacer para resucitar un viejo macbook pro 2011 con la GPU radeon rota.

Lo primero es poder arrancar una vez que la tarjeta gráfica se ha estropeado, para ello lo que hay que hacer es arrancar en modo superusuario (arrancar con cmd+s pulsado) y en esa terminal escribir:

nvram fa4ce28d-b62f-4c99-9cc3-6815686e30f9:gpu-power-prefs=%01%00%00%00
reboot

Una vez reiniciado ya con la pantalla normal (esto es temporal) habría que hacerlo un poco más permanente, para ello he creado un script que podríais lanzar desde cualquier distribución live (yo uso ubuntu) y que de hecho yo tengo almacenada en el usb arrancable (en la particion writable). El script es este:

echo "Ejecutar como root este script"
printf "\x07\x00\x00\x00\x01\x00\x00\x00" > /sys/firmware/efi/efivars/gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9
chattr +i "/sys/firmware/efi/efivars/gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9"
cd /
umount /sys/firmware/efi/efivars/
echo "Ahora deberías reiniciar la máquina para que tenga efecto"

Arrancar con la live (tener pulsado la tecla alt mientras se arranca y luego seleccionar el disco arrancable de ubuntu) y ejecutar como root el script. Esto hace que el cambio sea permanente (hasta que se actualice de nuevo la información de la EFI, pero eso solo pasa con las instalaciones grandes del sistema operativo).

Lo siguiente ya es más entretenido… Actualizar el hardware (yo le he puesto dos ssd y estoy pensando en actualizar la memoria), instalar linux, intentar actualizar high sierra a otro sistema (yo he conseguido instalarle mojave), limpiarle por dentro y cambiar la pasta térmica (esto no es tan complicado pero hay que lidiar con la forma de integrar componentes que tiene mac). En fin, entretenimiento para rato.

Por suerte, parece que todo funciona (menos la maldita GPU de AMD) y puedo volver a usar el trasto cuando quiera.

Emprendiendo en comercio electrónico

Ya os he hablado otras veces de lo complicado que es emprender, es algo que no todo el mundo está preparado para hacer y que muy pocos se atreven a afrontar en serio. Hoy os traigo un ejemplo muy cercano, una tienda de productos de cosmética natural que se está currando mi hermana… Aprovecho que tengo blog y os la presento aquí:

PADIY Mi tiendecita.

Todavía no está abierta, pero ya está casi casi, un sitio donde encontrarás jabón artesanal, jabón natural o jabón eco responsable. Los inicios siempre son muy duros, más en estos tiempos de pandemia y mucho más en la selva del comercio electrónico.

En su web encontrarás productos de marsella, productos nacionales, productos de oporto y otros muchos más cercanos pero no por ello de menor calidad. Todo artesano y con gusto.

Mucha suerte a mi hermana y a todos los emprendedores que quieran jugársela día a día y, recordad, si queréis jabones artesanales no dejéis de visitar padiy, que incluso podéis encontrar en facebook.

Nueva tienda en el ciberespacio... Ánimo padiy!

Variables de entorno y docker

Después de un tiempo definiendo distintos contenedores docker y coordinando despliegues con docker compose me he encontrado con circunstancias que me obligaban a modificar los archivos de definición cada vez que necesitaba hacer un nuevo despliegue o paso a producción y eso, bueno, eso es un poco molesto. Así que sabiendo que la gente que ha desarrollado todo esto era más lista que yo me puse a buscar cómo proponen que lo hagamos.

Y la respuesta es… Mediante varibles de entorno (al menos una de ellas), así que vamos a ver cómo podemos, como ejercicio, poner el número de versión de nuestro despliegue como varible de entorno..

Uno de mis docker-composes tenía este aspecto:

    web-php:
        container_name: web-php
        build: .
        image: nexus.biblioetech.com/biblioeteca/nomorepass:1.0.0
        ports:
            - "80:80"
        environment: 
            DBHOST: "db"
        links:
            - "web-mysql:db"

Como véis el número de versión acompañaba al nombre de la imagen y esto es así para que al construirla ya llevase la etiqueta adecuada para subirla al repositorio privado. El problema era que cada vez que hacíamos una release nueva teníamos que tocar este archivo a mano… Si queremos no tener que tocar el archivo tenemos que poner algo así:

    web-php:
        container_name: web-php
        build: .
        image: nexus.biblioetech.com/biblioeteca/nomorepass:${VERSION}
        ports:
            - "80:80"
        environment: 
            DBHOST: "db"
        links:
            - "web-mysql:db"

De esta forma solo hay que definir la varible de entorno VERSION al valor que acabamos de generar. Ahora bien, es fácil que nos olvidemos de asignar esta variable de entorno si no está en ningún sitio del repositorio, así que lo más sencillo es incluirla en un archivo .env que será el que docker-compose cargue antes de ejectuar el build… Y quedaría así:

VERSION=1.0.0

En este archivo podemos incluir todas las variables que necesitemos y, lo que es más, podremos pasarselas al Dockerfile si lo necesitamos, eso si, el método es un poco más rebuscado (eso lo veremos un poco más adelante).