Categoría: informática

Telegram y el precio de la luz

Telegram y el precio de la luz

Desde hace ya un tiempo, llevo usando Telegram como principal aplicación de mensajería con mis conocidos. En esta, existen los llamados bots, que pueden implementarse por cualquiera a través de un API. Hace algún tiempo, intenté crear una librería para poder tratar con esos bots desde Java de una forma sencilla, pero lo dejé de lado por falta de tiempo, y por los constantes cambios que se van introduciendo por parte de Telegram. Por suerte no fui el único con esa idea, y alguien terminó llevándola a buen puerto, e incluso mejorándola. La librería se integra de una forma sencillísima con Spring Boot, para hacer un bot completamente funcional integrado en el ecosistema de Telegram.

Para crear un bot con esa librería, solo hay que usar el starter que incluye, y arrancarlo como una aplicación más de Spring. Lo necesario también, es obtener el token necesario de Telegram a través del BotFather que tiene, y que sirve para poder hacer las peticiones, que se debe añadir dentro de tu aplicación.

En su día, ya había creado algún bot por mi cuenta con mi propia librería anticuada, pero que también había abandonado, y ya llevaba dando vueltas a la cabeza el hacer uno nuevo, que realmente fuese útil. Y con mi situación actual, no terminó siendo difícil encontrar lo que necesitaba.

Como ya sabéis de mi anterior post, tengo un coche eléctrico, con el que estoy encantado. Para recargarlo, el 99% de las veces lo hago a través de la propia electricidad de mi casa, después de haber instalado un punto de carga en el garaje, y eso nos lleva hasta 2021. El precio de la luz como todos sabemos se disparó de manera desproporcionada, y la factura, incluso no siendo un consumidor excesivo, subió un riñón, y parte del otro. De hecho subió tanto, que ha habido un tiempo que no me compensaba cargar el coche en mi casa, porque me salía más caro, que irme a uno de los cargadores rápidos que hay cerca de mi casa.

Con todo esto, decidí que si iba a cargar el coche en casa, tendría que saber cuando hacerlo, para que mi factura no fuese una autentica aberración. Encontré una página web donde te dice que precio tiene la luz a cada hora del día, pero consultarla cada día, me parecía un poco engorroso. Esa página tira de un api público accesible para todos, que se puede consultar sin ningún problema, y al que le di un par de vueltas para ver como funcionaba.

Con mis ganas de volver a hacer un bot para Telegram, y mi necesidad de saber el precio de la luz cada día de forma rápida y sencilla, estaba claro lo que había que hacer: Un bot que te mandase cada día los precios de la luz de las horas de ese día, de forma automática. Con todo esto en mente, me puse manos a la obra, y en menos de un fin de semana ya lo tenia listo, y desplegado en un servidor propio que tengo desde hace siglos y un poco desaprovechado.

PrecioDeLaLuzBot

El código del bot es muy sencillo en si mismo: Obtiene desde el api público el precio de la luz para el día actual (Y el día siguiente también), y se lo guarda en una base de datos MariaDB. También almacena en la base de datos el ID de Telegram de todos los usuarios que se van uniendo al bot, para poder enviarle el mensaje con los precios de la luz. Una vez hecho esto, con un proceso programado a las 00:00 de cada noche, se crea el mensaje con los precios de ese día, y se le manda el mensaje formateado a todos los usuarios. Por supuesto si un usuario decide parar el bot, se le elimina del listado para que no se le mande más. Todo esto desplegado en un servidor a través de Docker (Como ya sabéis, no despliego ya nada que no se pueda hacer a través de Docker).

Desde que lo desplegué lo consulto todos los días, y en el momento de escribir este post, ya hay 70 personas que lo están usando, cosa que ya es más de lo que esperaba. Podéis acceder al bot vosotros mismos escaneando el QR de abajo, o pulsando directamente sobre el, para abrirlo directamente en Telegram.

Wireguard: VPN en casa en 10 minutos

Si tenemos un poco de interés en servidores de algún tipo, o queremos no depender de servicios de terceros, es casi seguro que tendremos algún equipo en casa, que nos haga de servidor, al que poder acceder una vez estamos conectados a la red de nuestra casa. Pero exponer estos servicios a Internet, muchas veces puede llegar a ser un peligro, ya que estamos dando acceso de alguna manera a equipos que tenemos en casa.

Para solucionar este problema, existen las llamadas VPNs, que durante el confinamiento por COVID19 tanto se están usando, para poder acceder a los servicios de las empresas (Aunque ya se usaban VPNs anteriormente para eso mismo, y poder navegar de forma anónima por Internet, con un proveedor de VPN).

Pero este servicio no tiene porque estar acotado a las empresas. Si como decía antes tenemos algún servicio en nuestra casa al que podamos acceder por conexión de red, montar una VPN en nuestra casa, para poder acceder a esos servicios una vez que estamos fuera, es probablemente la mejor opción.

En mi caso, tengo un NAS donde tengo todos mis datos importantes, backups, y más cosas, a los que puedo acceder una vez estoy conectado a la red de mi casa, pero muchas veces quiero poder acceder a esos archivos desde fuera. Podria exponer estos archivos hacia fuera mediante un servicio FTP por ejemplo, pero eso daría pie a ataques por parte de terceros para acceder a esos archivos, comprometiendo muchisimos datos privados.

Para evitar esto, me he instalado un servidor de VPN al que obviamente, si que he dado acceso hacia el exterior mediante el mapeo del correspondiente puerto en el router, y consiguiendo el acceso seguro a todos los datos de mi casa.

Además este acceso por VPN sería una capa de seguridad muy buena, si estáis de viaje y os tenéis que conectar desde una red WiFi pública, desde las cuales jamás deberías usar ningún servicio importante, debido a la posibilidad que hay de que se intercepten las comunicaciones, y que al conectarte a la VPN de tu casa, quedaría resulto sin ningún problema.

Normalmente se usaría en estos casos una VPN de tipo OpenVPN que es probablemente el servicio más extendido. Investigando un poco más encontré un servicio muy actual para VPN que usa algoritmos de criptografía modernos, y con una velocidad asombrosa, llamado Wireguard.

Esta VPN se puede configurar en cualquier servidor que tengas en casa (En mi caso una Raspberry Pi 4), y su configuración gracias a Docker (Como ya os dije, no instalo ya de forma tradicional ningún servicio. Absolutamente todo con Docker, o sino no se usa), resulta ser de lo más sencillo.

Antes de nada, deberéis tener un nombre de dominio asociado a vuestra IP de casa. Para ello con algún tipo de DNS dinámico, os valdría perfectamente.

Os dejo por aquí el docker-compose que uso para poder crear el servicio de Wireguard

version: "3"

services:
  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
      - SERVERURL=midominio.decasa.com #optional
      - SERVERPORT=51821 #optional
      - PEERS=2 #optional
      - PEERDNS=8.8.8.8 #optional
      - INTERNAL_SUBNET=10.13.13.0/24 #optional
    volumes:
      - /home/misuuario/wireguard:/config
      - /lib/modules:/lib/modules
    ports:
      - 51821:51820/udp
    restart: unless-stopped

Lo imporante de este archivo son los siguientes puntos:

  • SERVERURL: Este debe ser el dominio que tiene que apuntar a vuestra casa.
  • SERVERPORT: Por defecto se pone a 51820, pero si a su vez quereis desde vuestra casa, poder conectar como cliente a otras VPN Wireguard, os recomiendo poner el 51821
  • /home/misuuario/wireguard: Este será el directorio donde se guarde toda vuestra configuración de la VPN
  • 51821:51820/udp Hay que asegurarse de que el puerto interno del contenedor 51820 queda mapeado al externo en el 51821, y por supuesto, mapear en vuestro router el puerto 51821 hacia vuestro servidor.

Una vez arrancado el servidor, si vemos los logs con

docker logs -f wireguard

se nos mostrarán dos códigos QR correspondientes a los dos clientes creados para la VPN. Estos códigos QR deben ser escaneados con las aplicaciones correspondientes de móviles (Android e IOS) para poder acceder a la VPN de forma sencilla desde nuestro dispositivo.

Si queremos poder acceder desde un PC, desde Windows o Mac no hace falta más que instalar su cliente desde https://www.wireguard.com/install/

En Linux, Wireguard ya va integrado en el Kernel, por lo cual solo hay que seguir las instrucciones que se dan en la misma página para poder configurarlo.

Para encontrar el archivo de configuración que se debe importar en estos clientes, solo haría falta ir al directorio /home/misuuario/wireguard y entrar a los sub-directorios de los clientes generados (peer1 y peer2), y en ellos se encontrarán los ficheros peerX.conf, que al importarlos en el cliente de Wireguard te deja la configuración lista para activarse. También en estos directorios encontrareis los ficheros de imagen del código QR por si queréis volver a configurarlos en dispositivos móviles.

El proceso de instalación no os llevará más de diez minutos, entre la configuración del fichero docker-compose, el mapeado del puerto correspondiente en el router, y la configuración de un cliente para tener listo un acceso privado a vuestra casa.

Servicios básicos para startups con Ansible y Docker

Por anteriores post, habéis podido ver, que tengo una predilección enorme por Ansible y Docker, y todas sus posibilidades. Tanto es así que en mis servidores, ya no despliego nada que no vaya en contenedores, y si puedo, lo automatizo a través de Ansible.

Mi último descubrimiento fue Nextcloud: Un servicio de nube privada, que a su vez tiene mensajería instantánea, y videoconferencia integrada, que una vez instalado en tu servidor no necesitas depender de servicios de terceros. Si a eso se le añade la compatibilidad para poder editar documentos on-line gracias a Collabora y Onlyoffice, el potencial de este servicio se dispara hasta limites insospechables.

Teniendo un servidor infra utilizado, decidí instalarlo en el, para tener mis archivos sin que ninguno de los gigantes tecnológicos tuviera acceso a mis datos, pero me quedé prendado de la cantidad de posibilidades que presenta, y me di cuenta de algo tan obvio que no podia dejarlo pasar.

Nextcloud es el servicio perfecto para pequeñas empresas o startups que estén empezando, y no necesiten una infraestructura enorme, sin tener que depender de servicios de terceros, con una inversión mínima. Y ese es justo el punto en el que se me encendió la bombilla.

Servicios cloud

¿Por que no crear un instalador de servicios básicos para startups con Nextcloud? ¿Y si lo llevo un paso más allá, y no solo le añado un cloud privado, sino también un servidor propio de e-mail? Dos pájaros de un tiro, y los servicios básicos que toda empresa pequeña pueda necesitar, listos y preparados de forma sencilla. Encontré una solución integral de servidor de e-mail llamado Poste.io gratuito (Aunque con versión de pago con más características) que también se despliega con Docker, y es perfecto para el objetivo que tenía en mente.

Era el pequeño proyecto perfecto para poder usar Ansible y Docker unidos en todo su potencial.

Servicios para desarrollo de software

Una vez puesto al tema, y ver que todo iba viento en popa, la bombilla se volvió a encender, y lleve el instalador un paso más allá para crear el instalador definitivo para startups que se dediquen a desarrollo de software.

Ya tenía experiencia montando Gitlab, Jenkins y Nexus en mi empresa, así que… ¿Por qué no añadirlo al paquete? La combinación de nube privada, y servicios privados para entornos de desarrollo quedaba perfecta.


Manos a la obra…

Os explicaré brevemente los pasos que da el instalador, para tener todo listo simplemente con cambiar 2 variables, ponerle los datos de acceso de la máquina destino, configurar DNS para que apunten a tu máquina, y si no es un servidor que esté directamente en Internet, un mapeo de puertos.

1 – Instalación de dependencias

Para poder lanzar los servicios, se necesita tener instalado en la máquina docker, y docker-compose para un manejo mas simple de los contenedores. Además se le instalan dependencias de Python necesarias para que Ansible ejecute correctamente algunas tareas de Docker.

Se le da permisos al usuario para poder ejecutar contenedores de Docker si no es root, y listo: Máquina preparada para empezar

2 – Comprobación de DNS

Dado que van a ser unos servicios que tengan acceso desde Internet, compruebo mediante unas consultas de DNS si las IPs de los sub-dominios donde se van a desplegar los servicios, concuerdan con la IP pública del servidor.

3 – Instalación de proxy base

Para poder manejar todos los servicios desde una misma máquina, y además con Docker, es necesario ponerle delante un proxy para poder tratar las peticiones, y lo más importante, usar https sin tener que configurarlo en todos y cada uno de los servicios. En este caso he usado Nginx ya que tengo experiencia con el, y siempre me ha funcionado bien.

En este punto cabe destacar, que los certificados https pueden llevar un coste asociado, que no cuadra mucho con la filosofía de este instalador (Aunque al final se pueden añadir manualmente en la instalación si ya los tienes). ¿Solución? Let’s Encrypt: Con esto siempre que tengas configurado tu servidor web de una forma específica, puedes generar certificados https de forma gratuita, y además incluso renovarlos de forma automática para desentenderte de todo.

En este punto, le añado opcionalmente un servidor web con https al dominio raíz, por si en el futuro se quiere desplegar algo aquí.

4 – Instalación de proxy para servicios

Cada servicio lleva asociado un subdominio para su despliegue (Los despliegues en subdirectorios de un dominio, generan muchos dolores de cabeza, e incompatibilidades que no son recomendables), y por supuesto su certificado https, por lo cual, aplicando el mismo procedimiento que en el anterior punto, se genera certificados para los subdominios de Nextcloud, Poste.io, Collabora, Onlyoffice, Gitlab, Jenkins y Nexus, dejándolos preparados para el despliegue de cada uno de ellos

5 – Instalación de todos los servicios

Cada servicio tiene sus configuraciones específicas, redirecciones, restricciones de seguridad, triquiñuelas, etc… , que requieren muchas horas de investigación en base a documentación y prueba y error.

Al final de cada despliegue hecho a base de ficheros docker compose que agrupan todas las dependencias de un posible servicio, se le añade la configuración específica al proxy, para que sea capaz de redirigir las peticiones correctamente mediante https con el certificado generado anteriormente.

Sin duda este es el paso más laborioso, ya que todos los servicios son completamente distintos y requieren de laboriosas configuraciones que lleva su tiempo entender.

5 – Obtención de passwords de admin

Los servicios de Jenkins y Nexus, al arrancar generan una password de administrador, que solo se puede ver a través de la consulta de determinados ficheros generados tras completar la instalación. Yo quería que la instalación fuera lo menos dolorosa posible, así que al finalizar, saco por pantalla las passwords de administrador iniciales de estos servicios, para que puedan usarse de forma inmediata.


Con este proceso te queda un servidor listo para poder acceder a el, y crear usuarios y configuraciones ya especificas para cada servicio, pero sin haberte preocupado de toda su instalación, que ha durado poco más de 10 minutos.

Toda la codificación en scripts de Ansible me ha llevado unas 40 horas, pero me lo he pasado en grande combinando todas estas herramientas para poder tener un instalador muy completo. Algunas personas se divierten viendo la tele, otras haciendo deporte, y los que tenemos alma de programador, haciendo cosas como esta.

ACTUALIZACIÓN: Pues la cuarentena del corona virus, me ha dejado tiempo, y ahora también incluye un servidor de OpenLDAP y su administrador web.

ACTUALIZACIÓN 2: Y para seguir pasando la cuarentena, se incluye un Sonar.

Github

¿Que sentido tiene aprovechar unas herramientas gratuitas, si luego otra gente no puede aprovecharlas de la misma forma? Así que toca compartirlo con todo el mundo, y si alguno se decide a mejorarlo, los pull request son bienvenidos 😉

Ansible Web Tools installer

Ansible: La automatización definitiva para servidores

El término ansible se usa en la literatura de ciencia ficción para describir un dispositivo hipotético de comunicación más rápida que la luz.

Ansible logo

Los creadores de la tecnología llamada Ansible, se basaron en este sistema para darle nombre, y aunque obviamente no hayan conseguido que vaya más rápido que la luz, si que esta tecnología consigue hacer muchísimo más simple la configuración remota de equipos.

Ansible se basa en el más que probado protocolo SSH, con el cual se pueden ejecutar ordenes remotas mediante un terminal introduciendo comandos. Además se han abstraído estos comandos (Llamados tasks en Ansible), para que no tengan que escribirse como tal, y que escribiendo un trozo de código en formato yml, Ansible lo traduzca a comandos Linux. Lo bueno de Ansible, es que no hay que instalar en servidor nada más que un servidor de SSH, y listo, Ansible funcionará perfectamente, ya que en realidad no ejecuta en servidor, sino en la máquina cliente que ataca esos servidores, por eso desde la máquina donde se lance la ejecución, si que debe tener Ansible instalado.

Inventarios

El inventario en Ansible no es mas que un archivo de texto plano, donde se definen los hosts a los que podemos atacar. Un fichero de inventario podría tener el siguiente aspecto

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

Se puede ver, que tiene una dirección por defecto como mail.example.com, y ademas mediante corchetes, se pueden crear grupos de máquinas como en este caso [webservers] o [dbservers], por si queremos ejecutar los mismos comandos directamente contra varios servidores de una sola vez.

A su vez, Ansible tiene unos posibles hosts donde ejecutar estos comandos. Estos hosts no son mas que configuraciones de conexión a los servidores donde se tiene que ejecutar los tasks. Se puede tener un solo host, o varios a la vez donde ejecutarse. Por supuesto, se debe tener el acceso correspondiente a cada máquina, ya sea via usuario y contraseña (Nada recomendable), o mediante una clave publica/privada que se haya instalado en el servidor donde se ejecutarán las tareas.

tareas

Un ejemplo básico de una tarea Ansible, en la que se copia un fichero de un directorio local, a uno remoto en el servidor sería este

- name: example copying file with owner and permissions
  copy:
    src: /srv/myfiles/foo.conf
    dest: /etc/foo.conf
    owner: foo
    group: foo
    mode: 0644

Los elementos son los siguientes:

  • name: Nombre de la tarea a ejecutar que la identifica de forma unica
  • copy: etiqueta que identifica el comando de la tarea. En este caso el tipo copy sirve para copiar archivos en servidor.
    • src: Fichero local a subir en nuestro servidor
    • dest: Ruta donde se dejará el fichero a subir. Se puede poner un nombre distinto al original si queremos renombrarlo.
    • owner: Propietario del fichero que se pondrá al subirlo.
    • group: Grupo del fichero que se pondrá al subirlo.
    • mode: Permisos en formato octal, que se le darán al fichero en servidor.

Como podéis ver es un formato yml muy claro, y fácilmente entendible. Por supuesto existen muchos mas tipos de tareas en Ansible que se traducirán a comandos ssh automáticamente cuando se ejecuten. Los ficheros que agrupan estas tareas, se les denomina en Ansible, playbooks, ya que pueden contener varias tareas a ejecutar.

ejecución

Una vez creado nuestro primero playbook, ya podremos ejecutarlo. Una ejemplo de ejecución seria este

ansible-playbook -i hosts.cfg -l webservers myPlaybookFile.yml

Este comando usa un fichero hosts.cfg (El del ejemplo escrito arriba), y un fichero de playbook llamado myPlaybookFile.yml donde se encuentran las tareas a ejecutar. Al ejecutar este comando, subirá a los hosts definidos dentro del grupo webservers (Con el argumento -l nombregrupo se indica que se quiere ejecutar contra un grupo de hosts) del ficheros hosts.cfg, el fichero que se indica en la tarea copy de nuestro fichero myPlaybookFile.yml.

Variables

La gran mayoria de veces las tareas que necesitamos ejecutar deben ser parametrizadas, ya que seguramente cambien con el tiempo. Para eso pueden usarse variables que puedan cogerse desde el mismo fichero de playbook, una fuente externa como un fichero de variables, o como parámetros dentro del propio comando de ejecución.

Para usar variables dentro de una tarea se debe poner el nombre de la variable dentro de dobles llaves {{ nombre_variable }}.

Un ejemplo dentro de una tarea podria ser el siguiente

- name: example copying file with owner and permissions
  copy:
    src: /srv/myfiles/{{ file_name }}
    dest: /etc/{{ file_name }}
    owner: foo
    group: foo
    mode: 0644

Y el comando a ejecutar pasándole la variable file_name

ansible-playbook -i hosts.cfg -l webservers myPlaybookFile.yml --extra-vars "file_name=ficherodeprueba.txt"

Con el parámetro –extra-vars (Aunque también vale con -e) se le pueden pasar variables extras que después se usen dentro de los playbooks.

Módulos

Ansible tienes unas tareas básicas que prácticamente pueden ejecutar en cualquier servidor Linux, sin embargo, estas son ampliables y pueden añadírsele módulos adicionales para poder manejar determinadas partes del host destino, como por ej. docker.

En la página web de Ansible tenéis todos los módulos disponibles que se pueden instalar para poder ampliar su funcionalidad.


Con esto espero haberos dado una idea aproximada de la potencia de Ansible, ya que para mi es imprescindible en estos momento, porque mis backups automatizados de servidores están hechos sobre Ansible, y en un futuro lo usaré para configuración completa de servidores nuevos.

La historia de mis Linux

Antes de nada, estoy haciendo pruebas con el nuevo sistema de Telegram de blogs instantáneos Telegraph, y esta entrada la he publicado también a través de Telegram, en el nuevo canal de Learning the Force en Telegram.



Llevo usando Linux, prácticamente desde el primer día que entré en la universidad, y de eso ha pasado hace ya mucho tiempo.
Antes de entrar en la universidad, sabía que existía Linux, pero no había tenido la oportunidad de trastear un rato con el, o simplemente estaba muy cómodo con Windows. Pero eso cambio mi primera semana en la universidad. Nos dieron una clase de introducción a Linux para la asignatura de programación, ya que íbamos a tener que manejarnos con el sistema en las aulas de prácticas. Me llamó tanto la atención, que me apunté a una charla de iniciación del GUL (Grupo de Usuarios de Linux), donde se explicaban los comandos básicos y alguna cosa más interesante sobre Linux. No faltó mucho más que esa charla para engancharme.
Cuando llegué a mi casa ese mismo día, entré en Internet, y gracias al nuevo y flamante ADSL de 256kbps que me acababan de instalar (Si, ya os dije que de eso hacía muuuuucho tiempo), bajé mi primera distribución de GNU/Linux para instalarla en mi PC.

 

Mandrake


Según leí en su momento, Linux Mandrake era una de las distribuciones más sencillas de instalar, ya que en ese instante, no tenía demasiada experiencia como para instalar algo desde consola. Mandrake, estaba basado en Red Hat, pero simplificando todo el proceso de instalación, y haciendo más amigable para alguien como yo en ese momento.
Guardo un buen recuerdo de esta distribución, ya que es donde empecé a ver otro entorno que no fueran las típicas ventanitas.
Mandrake pasó a mejor vida en 2011, aunque dejando un sucesor llamado Mandriva, que al final también paso a mejor vida, dejando un proyecto abierto llamado OpenMandriva que aun sobrevive.

Red hat


Después de un tiempo con Mandrake, me atreví a dar el paso a algo más puro, y más estable: Red Hat
Mandrake estaba basado en Red Hat, por lo que no me supuso mucho cambio, sobre todo a la hora de instalar paquetes, y demás entorno. Durante mucho mucho tiempo, fue mi sistema operativo principal, excepto las veces que quería jugar una partida a algo, que inevitablemente tenía que volver a Windows.
Red Hat, a día de hoy se encuentra activo, y se ha orientado a empresas, ya que el servicio técnico que ofrece, es sin duda el camino a seguir para los que quieran ganarse la vida con proyectos de software libre.

Ubuntu


Resulta curioso que no probase ninguna otra distribución hasta la llegada del todopoderoso Ubuntu, ya que pasaron unos cuantos años entre que empecé usar Red Hat, e instalé por primera vez Ubuntu en su versión 8.04.
A estas alturas, poca gente no conoce Ubuntu. Es sin ninguna duda la distribución de Linux más usada por la gente del mundillo, y tiene multitud de sabores a su alrededor (Kubuntu, Ubuntu Gnome, Ubuntu Mate, Lubuntu…) como para estar días y días intentando elegir cual instalar. Su facilidad de uso e instalación, su soporte LTS, y las continuas actualizaciones hicieron de él, lo que es hoy en día.
Ubuntu está basado en Debian, una de las distribuciones más antiguas, y más estables que sigue existiendo a día de hoy, y que gracias a sus paquetes de tipo deb se ha ganado su puesto a pulso.
Sigo usando Ubuntu a día de hoy, en su sabor Lubuntu, que es perfecto para dispositivos antiguos, o con poca capacidad gracias a su escritorio ligero LXDE. Aunque tengo que reconocer que también a la hora de trabajar sigo usando Ubuntu en su variante de Ubuntu Mate, ya que a la hora de tener compatibilidad con nuevo software, hay que reconocer que una Ubuntu, no tiene competencia.

Debian


Debian. Para todos los metidos en el mundillo de Linux, es imposible no haber oído hablar de esta distribución. Desde mi punto de vista, la más estable, con menos fallos, y con toda la potencia de los paquetes deb, de los que Debian fue origen.
La primera vez que toqué una Debian, fue en los PCs que había en las aulas de informática de la universidad, con la versión Potato instalada (Para los que no lo sepan, los nombres de las versiones en Debian, llevan nombres de personajes de Toy Story: Potato, Sid, Woody, Jessie, Whezzy…), casi recién salida del horno y con el entorno XFCE. Por ese entonces la instalación no era demasiado sencilla, y yo no tenía los conocimientos necesarios, por lo cual la descarté como mi primer Linux a instalar.
Después de algunas frustraciones pasadas con Ubuntu, decidí pasarme a Debian, y fue una de las mejores decisiones que pude haber tomado: Mi PC no se colgaba ni queriendo, y podía con todo lo que le pedía. Acierto al cien por cien, y en mi PC sigue instalado como un campeón.
A día de hoy, si tuviera que recomendar una distribución para su día a día, definitivamente Debian sería mi elección sin ninguna duda.

Arch Linux


Llegamos hasta la actualidad. Arch Linux, es un concepto de distribución distinto de todos los demás que he tenido instalados: Los paquetes que llevan siempre están actualizados a su última versión estable liberada por cada desarrollador, en vez de tener una sola versión estable de los paquetes, que solo se actualiza a una nueva versión cuando los creadores de la distribución deciden que así sea.
Esta distribución no es para todo el mundo, ya que en cuanto se insertar el CD/USB de instalación lo único que te da, es un terminal, y a partir de ahí apáñatelas tu como puedas, por lo que el proceso es complejo para alguien no iniciado en el mundo de Linux.
Y os preguntareis: ¿Por qué instalar Arch Linux, cuando Debian funciona tan bien? La respuesta es más sencilla de lo que os imagináis: Me aburro. Simple y llanamente. Hacía mucho tiempo que no probaba nada nuevo en Linux. Estaba asentado en mi Debian que no fallaba ni aunque se le azotara con un palo, y necesitaba algo nuevo que probar.
Primero lo instalé en máquina virtual, para estar seguro del proceso que había que seguir para su instalación, y una vez teniéndolo claro, cogí mi antiguo portátil del trabajo, y repliqué paso a paso lo que había hecho, junto con alguna variación para los drivers gráficos.
Éxito total es lo que yo definiría al ver Arch Linux instalado y funcionando a la perfección. Y lo mejor de todo es que simplemente con el comando

pacman -Syu

el sistema se actualiza a la última versión de todos sus componentes, sin ningún problema adicional. Lo dicho un autentico éxito, que acaba de dividir mi corazón entre Debian y Arch Linux.
 
Espero que esta historia de mis Linux, os sirva como inspiración para entrar en un mundo increíble, y empecéis a olvidaros de una vez de esas ventanitas que tantos quebraderos de cabeza nos dan a los informáticos.

El vicio de Docker

¿Alguna vez os habéis encontrado una tecnología/gadget tan versátil que os gustaría que estuviera todo ahí? Algo así como el smartphone actual, donde si pudieras, pedirías que con pulsar una sola tecla en la pantalla, que te preparase el café, te leyese las noticias, te pusiera en la cama la ropa que te vas a poner ese día, y que además te teletransportase al trabajo. Pues eso mismo me pasó a mi con Docker.
Docker
En una entrevista de trabajo que tuve, me hablaron de Docker por primera vez, como una forma de virtualizar aplicaciones, pero que no requería un OS completo de por medio. Para mi eso era toda una novedad, ya que me habría venido muy bien para virtualizar los servidores que uso para CoResponde en vez de tener que configurármelos uno a uno con todos los pequeños detalles. Solo crear una imagen de Docker especifica con todas las configuraciones, y lanzar contenedores de esa imagen en otros servidores. Más fácil imposible.
Desde el momento que empecé a enredar más a fondo con ello, vi que si pudiera, Dockerizaria hasta las sartenes de la cocina. Su potencia me sorprendió, y el rendimiento era extremadamente bueno.
Debo deciros antes de nada, que Docker está pensado para ejecutar en máquinas Linux, por lo cual si queréis hacerlo desde Windows o Mac, debereis usar una máquina virtual intermedia para poder funcionar. Pero por supuesto, esto no tiene ningún sentido, ya que si vamos a usar Docker, es porque no queremos hacer una virtualización tradicional. Así que si quieres usar Docker, ya estás tardando en pasarte a Linux.
Ahora entramos en la chicha de Docker. Esto es como funcionaría una máquina virtual tradicional, con su sistema operativo completo corriendo por encima de un sistema de virtualización o hypervisor elegido.

stackvm

Solo con el sistema operativo completo, el rendimiento se reduce dramáticamente. Sin embargo, este es el stack de Docker.

stackdocker

Con esto nos quitamos de en medio todo el sistema operativo de la máquina virtual, y el motor de Docker usará los recursos nativos de la máquina, junto con los binarios y librerías estrictamente necesarios para poder correr las aplicaciones que se requiera.
El funcionamiento de Docker es relativamente sencillo: Se basa en imágenes que contienen todo lo necesario para ejecutar una, o varias aplicaciones, y lanzar contenedores (Instancias) de estas imagenes. Contruir una imagen propia es tan sencillo como crear un fichero de texto plano llamado Dockerfile en el cual, se configura la aplicación que quieras correr.
Ej. de fichero Dockerfile

FROM buildpack-deps:jessie-scm
# A few problems with compiling Java from source:
# 1. Oracle. Licensing prevents us from redistributing the official JDK.
# 2. Compiling OpenJDK also requires the JDK to be installed, and it gets
# really hairy.
RUN apt-get update && apt-get install -y --no-install-recommends \
 bzip2 \
 unzip \
 xz-utils \
 && rm -rf /var/lib/apt/lists/*
RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list
# Default to UTF-8 file.encoding
ENV LANG C.UTF-8
# add a simple script that can auto-detect the appropriate JAVA_HOME value
# based on whether the JDK or only the JRE is installed
RUN { \
 echo '#!/bin/sh'; \
 echo 'set -e'; \
 echo; \
 echo 'dirname "$(dirname "$(readlink -f "$(which javac || which java)")")"'; \
 } > /usr/local/bin/docker-java-home \
 && chmod +x /usr/local/bin/docker-java-home
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
ENV JAVA_VERSION 8u72
ENV JAVA_DEBIAN_VERSION 8u72-b15-1~bpo8+1
# see https://bugs.debian.org/775775
# and https://github.com/docker-library/java/issues/19#issuecomment-70546872
ENV CA_CERTIFICATES_JAVA_VERSION 20140324
RUN set -x \
 && apt-get update \
 && apt-get install -y \
 openjdk-8-jdk="$JAVA_DEBIAN_VERSION" \
 ca-certificates-java="$CA_CERTIFICATES_JAVA_VERSION" \
 && rm -rf /var/lib/apt/lists/* \
 && [ "$JAVA_HOME" = "$(docker-java-home)" ]
# see CA_CERTIFICATES_JAVA_VERSION notes above
RUN /var/lib/dpkg/info/ca-certificates-java.postinst configure
ENTRYPOINT /usr/lib/jvm/java-8-openjdk-amd64/bin/java -version 

Este es el código del Dockerfile para tener un contenedor con java 8 instalado.
Lo primero que se puede observar es el siguiente texto :

FROM buildpack-deps:jessie-scm

Esto indica que estás heredando de la imagen con nombre buildpack-deps y la versión jessie-scm. Casi la totalidad de las imágenes de docker, heredan de una más básica (Existen imágenes de Ubuntu o Debian básicas muy útiles de las cuales partir), y van añadiendo funciones extra.
Todo lo demás son intrucciones de que debe tener instalado nuestra imagen, excepto la orden final, que debe ser un ENTRYPOINT o CMD que es la orden que se ejecuta cuando se inicia una instancia de esta imagen. En el ejemplo anterior simplemente se ejecuta un java -version que mostraría simplemente la versión de java. Este parámetro de entrada, puede ser sustituido por nuestro propio punto de entrada para una imagen propia.
Para convertir este archivo Dockerfile en una imagen lista para ejecutar, simplemente con ejecutar este comando desde el propio directorio donde se encuentra el Dockerfile, crearemos una imagen:

docker build -t imagen-java .

En este caso, estamos construyendo una imagen con nombre imagen-java, diciéndole que nuestro fichero Dockerfile, se encuentra en el directorio actual. Dependiendo de todo lo que hayamos definido en el fichero, tardará más o menos tiempo, y al final si ejecutamos

docker images

veremos que ya tenemos nuestra imagen lista.
A partir de aquí ya tenemos lo básico para empezar a trabajar con ella. Lo siguiente es lanzar un contenedor de docker. Un contenedor no es más que una instancia de esta imagen base, y que será equivalente a nuestra máquina virtual tradicional para poder entenderlo bien. Para lanzar un nuevo contenedor solo necesitamos el siguiente comando:

docker run --name container-java imagen-java

Y listo, ya tenemos nuestro primer contenedor creado, y veremos como por pantalla nos sale la versión de java que configuramos en nuestra imagen base.
Los contenedores de Docker se paran, en cuanto no tienen una aplicación en primer plano ejecutándose. Esto significa que si lanzas un proceso que empieza y termina, como por ej. el contenedor lanzado antes con java -version, en cuanto se acabe de ejecutar, el contenedor se para, y tendrías que volver a ejecutarlo con

docker start container-java

ya que no habría que crear otro, solamente re-arrancar el ya creado.
Por supuesto esto es algo demasiado básico que no nos sirve para nada, ya que no tenemos ninguna aplicación real corriendo.
Llegados a este punto, toca explicar que es Docker Hub. Docker Hub es una plataforma, donde almacenar y poner disponibles imágenes de Docker pre-compiladas, para poder ejecutar desde cualquier sitio. Resumiendo: Si ejecutamos

docker run tomcat:8.0

primero se comprobará que no tenemos disponible en local una imagen con ese nombre, irá a docker hub, comprobará que existe una imagen con ese nombre y versión, se la bajará a tu equipo, y después lanzará un contenedor que se quedará ejecutando un servidor tomcat versión 8. Como podéis ver la simplicidad de esto es infinita, y nos permite lanzar contenedores extremadamente rápido.
Hay que tener en cuenta, que estos contenedores son como máquina virtuales, y los puertos que usan las aplicaciones dentro, están aislados, por lo cual si queremos que estén accesibles en la máquina, debemos mapearlos. La sintaxis es la siguiente:

docker run <nombreimagen> -p <puerto externo>:<puerto del contenedor>

Un ejemplo de esto con un contenedor de tomcat sería

docker run tomcat:8.0 -p 80:8080

Con esto mapeamos el puerto por defecto del tomcat del contenedor, a nuestro puerto 80 de la máquina, por lo que con acceder a http://localhost/  estariamos ejecutando ya todo lo que contenga nuestro tomcat.
Se pueden tener múltiples contenedor de la misma imagen, por lo que tener dos servidores a la vez sería tan fácil como

docker run tomcat:8.0 -p 81:8080

y ya tendríamos otro tomcat corriendo en la misma máquina. Por supuesto, tiene que ser en un puerto distinto, ya que nuestro puerto 80 estaría ocupado por el contenedor anterior, y crearía un conflicto.

Espero que os haya servidor de ayuda, y a pesar de que no es un tutorial completo, hayáis echado un vistazo a una de las tecnologías que más me ha impresionado en los últimos tiempos.

Concepto de orientación a objetos

Probablemente el concepto que más me costó comprender cuando empecé a programar fue la orientación a objetos. El primer día de programación, van y me sueltan tan tranquilamente la definición estándar: Un objeto es una instancia de una clase. Ajam… si… muy bien… No se vosotros pero yo me quedé exactamente igual que estaba. Para mi en ese momento, una clase no era más que un archivo con cierto formato, donde yo ponía ordenes, y al compilarlas se ejecutaban una detrás de otra. Pero claro, eso se queda muy lejos de lo que es realmente programar.

Tardé bastante tiempo en entender claramente el significado de que era un objeto, y cómo usarlo. Y estoy seguro de que no he sido el único que ha estado tan perdido en este sentido. Pero un día, no se muy bien cómo, me di cuenta de que era, y cómo funcionaba. Fue un flash instantáneo que me vino a la mente, y de repente todo cobró sentido. Era un concepto tan simple que no sabía como había podido no entenderlo. Bueno, si lo se: Me estaban metiendo tantas cosas nuevas en la cabeza, que comprender en profundidad todo, era casi imposible. Pero a partir de ese momento todo fue viento en popa.

Por eso hoy, os voy a intentar enseñar cómo comprendí la orientación a objetos, y que siempre uso de ejemplo cada vez que intento explicarle a un alumno mío, que no tiene ni idea de que es un objeto.

Voy a dar por hecho que sabéis los conceptos de clase (Al menos con saber, burdamente explicado, que es un fichero donde se mete código y se ejecuta, suficiente), el de función o método (Definición simple: Una forma de agrupar instrucciones para hacer más legible el código), y la de variables (Esta lo siento, pero si no sabes lo que es una variable es que estás en el día 0 de aprender a programar xD), para explicaros la forma de entender la orientación a objetos

Esto es una clase

Clase coche
A partir de ahora, para vosotros esta clase es intocable, el código que escribáis en ella, NO PODÉIS EJECUTARLO. Hay formas de hacerlo obviamente (El concepto de static me costó comprenderlo bastante más, y no voy a meterme ahora con ello), pero por ahora para tener las cosas claras, ese código es intocable.
La cosa es que necesitamos ejecutar código de esa clase, y acceder a la variable que hay en ella para cambiarla, o ver que valor tiene. Aquí es cuando entra el concepto de objeto. Mi propia definición de objeto: Un objeto, es una copia usable de una clase. Dicho así, suena casi tan raro como la definición original de objeto, así que vamos a desarrollarlo un poco.
Para poder usar ese código hacemos una copia de nuestra clase:
Clase cocheClase coche
 
 
 
 
 
 
 
Hasta aquí todo bien, ya tenemos nuestra copia usable. La cosa es que, en esta copia, para vosotros, no es visible su código realmente, solo podrás hacer cosas con el, pero no ver las instrucciones que ejecuta. Por lo cual podría resumirse en que ahora mismo tienes esto:

CLASE   –   OBJECTO

Clase coche

 
 
 
 
 
 
 
Esta es la mejor imagen para definir un objeto, porque literalmente ES un objeto: Una cosa con la que podemos hacer algo.
Ahora a ese objeto le podemos decir que haga cosas. En nuestro caso, tenemos un objeto de la clase coche por lo cual podemos llamar a los métodos que tiene:

LLAMADA AL MéTODO/función ARRANCAR DEL OBJETO

Por supuesto, podemos crear tanto objetos como queramos. Podemos tener un array de esos objetos por ej:

Objecto cocheObjecto cocheObjecto coche

Y podemos decirle al segundo solamente que arranque.

Objecto cochearrancarObjecto cocheObjecto coche

Así es como lo veo yo, y al menos a mi me sirvió para captar de forma crucial el concepto de objeto, y por ahora, parece que mis alumnos también consiguen captarlo y entenderlo, por lo cual, algo de bueno tiene que tener verlo así.

Espero que a vosotros también os sirva para entenderlo si estáis empezando. Y si tenéis que enseñarle a alguien este concepto, tener una idea de cómo simplificar el proceso para que lo aprendan.