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).

PC-COMPONENTES? nunca más

Soy un asiduo comprador por internet desde que el e-commerce se inventó, compraba libros en Amazon antes de que llegasen a España y metí mi tarjeta de crédito en optize allá por los años 90 cuando nadie se fiaba de ello. No he dejado de comprar en tiendas virtuales desde entonces (y hasta he tenido las mías propias en las que he vendido desde impresoras hasta leds), por eso se me hace tan complicado de entender como pueden existir todavía empresas que no saben tratar las incidencias que se dan regularmente en el comercio electrónico. Para ello os voy a poner una imagen:

Esta es la ¿ruta? que ha seguido GLS para entregarme un portatil que compré en pccomponentes el día 3 de Mayo. La fecha prevista de entrega era el día 5 (como es habitual en las entregas nacionales), pero como ese día no llegó les di un poco de margen por eso del coronavirus… El día 6 no llegó tampoco, el día 7 entro en la web del transportista y les digo que quiero que me llegue por la mañana (a ver si respiran) y nada, ahí seguimos, el día 8 viernes tampoco y el día 11 tampoco y lo más sangrante es que NO SABEN DONDE ESTÁ.

Llegado a este punto y dado que el portatil lo ha comprado mi empresa y lo necesito para trabajar, intento contactar con pccomponentes para que me busquen una solución (esto ya me había pasado con Amazon y lo habitual es devolverte el dinero o enviarte otra vez la mercancía) y la respuesta de pccomponentes es: «nada que hacer». Todas las respuestas son igualitas a esta:

Les llamo por teléfono y me dicen que no nos pueden devolver el dinero hasta que ellos no reciban devuelta la mercancía.. ¿¿Se puede ser más inútil?? El cliente no recibe la mercancía que tu has cobrado en una semana y le dices que no le vas a devolver el dinero hasta que la reciban ellos… Eso suponiendo que alguien, en algún momento, encuentre esa mercancía y decida devolverla, si no… Esperar a que el transportista decida declarar que ha perdido la mercancía y mientras ellos se quedan con mi dinero.

No entiendo esta actitud. Me he gastado muchos miles de euros comprando cosas en esa tienda en el pasado y al primer problema que tienen dejan indefenso y cabreado al cliente. Cliente que, obviamente, dejará de serlo inmediatamente.

Bye, bye PC-Componentes, no se si recibiré la mercancía o me devolveréis el dinero (o tendré que formular una denuncia por estafa), pero se acabó eso de compraros nada más (y mi opinión sobre vuestro servicio no dejaré de expresarla allá por donde me pregunten). Si la culpa es del transporte (que lo es), los responsables seguís siendo vosotros que sois los que tenéis mi dinero.

La verdad en tiempos del coronavirus

Decía Hiram Johnson en 1917 que la primera víctima de una guerra era la verdad, y esto es completamente cierto, ya que cada bando debe utilizar la propaganda para desconcertar y desmoralizar al enemigo. Hay grandes ejemplos de contraespionaje que fueron decisivos en muchas guerras – sin ir más lejos en la segunda guerra mundial cuando hicieron creer al reich que el desembarco de normandía sería por el paso de Calais (operación fortaleza) – y grandes ejemplos de propaganda en tiempos de guerra, que podemos resumir en el decálogo que ya publicaba Arthur Ponsonby en 1928:

  1. “Nosotros no queremos la guerra”.
  2. “El enemigo es el único responsable de la guerra”
  3. “El enemigo es un ser execrable”
  4. “Pretendemos nobles fines”
  5. “El enemigo comete atrocidades voluntariamente. Lo nuestro son errores involuntarios”
  6. “El enemigo utiliza armas no autorizadas”
  7. “Nosotros sufrimos pocas pérdidas. Las del enemigo son enormes”
  8. “Los artistas e intelectuales apoyan nuestra causa”
  9. “Nuestra causa tiene un carácter sagrado, divino, o sublime”
  10. “Los que ponen en duda la propaganda de guerra son unos traidores”.

A estos elementos hay que sumar la desinformación, como un elemento presente en toda competición donde la opinión pública tenga alguna participación, como ya sucedía en la antigua roma y viene sucediendo periódicamente en todas las elecciones, siendo la más descarada la campaña de Trump y el escándalo de cambridge analítica.

Sin embargo, cuando la guerra es contra un enemigo que no es humano, como es el caso actual donde nos enfrentamos a una pandemia sin precedentes, ¿qué hacemos con la información y desinformación? En otros países lo tienen claro, hay que mantener informada a la población de la evolución de la guerra, premiar a los heroes y felicitar a los voluntarios que estén apoyando los esfuerzos por superar la crisis, en España, se prefiere otro enfoque – Spain is different – y se ha optado por buscar un enemigo en casa.

Al igual que los nacionalismos perifericos eligieron el concepto de «Madrid» como el enemigo a batir, el que les impedía su tan utópica independencia y el que le robaba los recursos. Al igual que los ultraderechistas trasnochados buscaron a los emigrantes, a los diferentes como el enemigo que les quitaba los trabajos y les limitaba la asistencia médica, de la misma manera una parte mezquina de la sociedad española ha decidido que es el gobierno el enemigo a batir.

La campaña de descrédito ha sido desmesurada desde el primer momento, un gobierno de coalición es algo inédito en la democracia española y cualquier ocasión es buena para intentar romperlo y volver a ocupar el espacio de poder que la derecha española cree suyo por derecho de nacimiento. Pero tanto es así que han utilizado todas las armas a su alcance para, en lugar de aportar soluciones, propuestas o apoyo a los profesionales que están al pié del cañon intentando paliar los efectos del virus, demonizar la gestión del ejecutivo para culparles de las muertes por el coronavirus.

Nadie en su sano juicio sería capaz de algo tan abyecto como acusar a otro de la muerte de un semejante (seguramente en persona serían incapaces de hacerlo, aunque fuese por verguenza), pero no hay nada que una más que un enemigo asesino al que poder poner en el punto de mira de su guerra particular (ver los puntos de arriba), tanto en los nacionalismos, en el fascismo o en las películas de hollywood. Pero España es así, ya no es posible emitir opiniones imparciales porque eres etiquetado como de un bando o de otro, independientemente de la verdad o del mensaje que emitas. Estamos en guerra y ahora o estás con nosotros o estás contra nosotros.

Y de esta manera todo lo que se ha conseguido es eliminar cualquier atisbo de espíritu crítico. Las críticas son meras representaciones de estrategia política, cada cifra, cada gráfico, cada anuncio se convierte en un campo de batalla por saber quien es más mezquino. Si eres de un bando y te atreves a criticar a los tuyos por cualquier cosa (aunque sea verdad) te conviertes en un traidor y así, simplemente, no hay manera de avanzar. Al igual que a mi me da cosa presumir de bandera porque el símbolo de todos los españoles se lo han apropiado gente que no tiene ningún reparo en presumir de machismo, xenofobia, y homofobia y pretenden que cualquiera que ondee la bandera comparte con ellos esos valores; ahora me es imposible criticar al gobierno (que tiene cosas que mejorar) porque parecería que soy uno más de los bots lanzados por la oposición para destruir al gobierno.

Pero lo que es peor, el nivel de virulencia de esta guerra sucia en los medios es tan alto que las consecuencias pueden ser terribles para nuestro futuro. La censura real (no la que falsamente afirman que ya hay en whatsapp) puede estar a la vuelta de la esquina, mediante cambios legislativos, solo porque hay quien ha decidido que el enemigo a batir no es el virus, es el gobierno.

Mover el directorio docker en ubuntu

Usar docker es sencillo y rápido, pero, como todo, tienes que tener cuidado con todo lo que ocupa espacio ya que los discos y las particiones son finitas… Y los contendores docker ocupan espacio (bastante), así que aquí dejo el método para mover el directorio de datos de la partición por defecto a otra cualquiera que queramos y para la que tengamos espacio de sobra.

Docker y ubuntu

Lo primero que hay que saber es que el directorio por defecto donde docker guarda sus imágenes, contenedores y demás cosas que ocupan espacio es:

/var/lib/docker

Que, generalmente, está en la partición raiz (o la que tengamos para var) que no suele ser muy grande. Supongamos que queremos moverla a un disco de datos con capacidad suficiente como este:

/mnt/disks/data/docker

Para ello lo que tendremos que hacer es: parar el servicio docker

sudo service docker stop

Crear un archivo llamado daemon.json en el directorio /etc/docker con este contenido:

{ 
   "graph": "/path/to/your/docker" 
}

Copiamos el directorio original al nuevo y lo renombramos por seguridad (ya lo borraremos después)

sudo rsync -aP /var/lib/docker/ /path/to/your/docker
sudo mv /var/lib/docker /var/lib/docker.old

Reiniciamos el servicio docker y todo debería estar como antes del cambio (podéis comprobar con un docker ps si se ha levantado todo lo que teníais funcionando antes).

sudo service docker start

Después de comprobar que todo está ok, ya podemos borrar el original y habremos terminado con la operación del todo:

sudo rm -rf /var/lib/docker.old

Docker para desarrollar con tomcat

Las ventajas de utilizar docker para desarrollar y desplegar la aplicaciones nunca deja de sorprenderme. Conseguimos con una simple definición en texto crear máquinas con configuraciones exactas a ejecutar en todas partes. Una de las cosas en donde todavía no había aplicado docker es en la aplicaciones web que desarrollo en Java. Habitualmente se requiere de un servidor tomcat (con cierta versión de máquina virtual de java) y una base de datos (yo he trabajado con mysql mayoritariamente) con otra versión particular.

Dado que las versiones de base de datos y de tomcat y de java han sido muy variables con el tiempo y que los proyectos no solo hay que desarrollarlos y entregarlos sino que hay que mantenerlos, nos encontramos con una situación imposible en que cualquier combinación de estos elementos es posible y necesaria para probar cualquier mínimo cambio que queramos realizar (si hay cosas muy compatibles que se pueden hacer con versiones nuevas y muchas otras que no)… El caso es que esta vez voy a deciros cómo podemos olvidarnos de una vez por todas de estos problemas utilizando docker y docker-compose.

Si eres el desgraciado usuario de una versión de windows las cosas pueden ser un poco más complicadas, pero si usas un sistema operativo de verdad la instalación y puesta en marcha de docker es trivial e inmediata (ya lo he tratado antes en el blog). Voy a dar por hecho que ya tienes un proyecto Java a ejecutar con tomcat (si es con maven o gradle que te generen el .war automáticamente, mejor) y que ya tienes docker instalado en tu equipo (y docker-compose). Lo que sigue es lo que tienes que hacer para probar tu war en un tomcat con una versión determinada que use una base de datos de una versión determinada:

Crea un directorio docker al mismo nivel que tienes el pom.xml si usas maven y dentro de ese directorio crea el archivo docker-compose.yml

version: "3"
services:

  tomcat:
    container_name: miproyecto-tomcat
    image: tomcat:8-jdk8
    ports:
      - 8080:8080
    volumes:
      - ../target/miproyecto.war:/usr/local/tomcat/webapps/miproyecto.war
      - ../target/miproyecto:/usr/local/tomcat/webapps/miproyecto
    links:
      - "mysql:db"

  mysql:
    container_name: miproyecto-mysql
    image: mysql:8.0
    environment:
       MYSQL_ROOT_PASSWORD: "mipassword"
    volumes:
      - ../mysql:/var/lib/mysql
    ports:
      - "3306:3306"
    restart: unless-stopped

En el directorio del pom.xml ejecuta lo siguiente:

mvn package

Esto te genera el war dentro de target y ya estarás en disposición de entrar dentro del directorio docker y ejecutar:

docker-compose up -d

Quiá la primera vez podrías querer ejecutarlo sin la opción -d para ver todo el log que sale (también es cierto que la primera vez se descarga todos los contenedores y tardará un poco). A partir de que haya arrancado podemos acceder a la aplicación en:

http://localhost:8080/miproyecto

También se puede acceder a la base de datos directamente:

mysql -h 127.0.0.1 -u root -p

Y yasta… En próximas entradas veremos como depurar con docker también.