Docker Swarm + Traefik 2.2

Configuración de Docker Swarm, el archivo traefik-stack.yaml tiene la configuaración básica necesaria para hacer funcionar al proxy reverso, y un ejemplo con un servicio sonso en whoami-stack.yaml.

version: '3'
services:
reverse-proxy:
image: traefik:v2.2
command:
- --api.insecure=true
- --api.dashboard=true
- --providers.docker=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=proxy
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
ports:
# The HTTP port
- "80:80"
- "443:443"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
networks:
- proxy
deploy:
placement:
constraints:
- node.role == manager
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`dashboard.traefik.localhost`)"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.entrypoints=http"
- "traefik.http.services.api.loadbalancer.server.port=80"
networks:
proxy:
external: true
version: '3'
services:
whoami:
# A container that exposes an API to show its IP address
image: containous/whoami
networks:
- proxy
deploy:
labels:
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=http"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
proxy:
external: true

Teniendo los archivos de configuración listos, debemos ejecutar los siguientes comandos para levantar el cluster.

Ahora expliquemos un poco…

Como habran notado la magia para publicar servicios realmente esta en la siguiente sección, en los labels que le pongo al servicio dentro de deploy:

En la linea "traefik.http.routers.whoami.rule=Host(whoami.localhost)" lo que hacemos decirle a que URL va a responder.

En la linea "traefik.enable=true" le informamos a Traefik que nos interesa publicar este servicio. Esto es necesario ya que en la configuración de Traefik pusimos de que no queremos que tome todos los servicios publicados por default.

Ahora cuando dice "traefik.http.routers.whoami.entrypoints=http" le estamos diciendo que debe escuchar el puerto 80 (lo configuramos en el archivo traefik-stack.yaml:16) en el host y por último "traefik.http.services.whoami.loadbalancer.server.port=80" nos dice que puerto debemos mapear del contenedor/servicio.

Como implementar Doctrine Filter en Symfony 4

Esto es un poco de mi experiencia. En este caso vamos a poder filtrar entidades por una Cuenta.

Cada usuario va a pertencer a una Cuenta (Account.)

Aca definimos la cuenta, de vago no copie todos los setters y getters… usen la imaginacion… o el bin/console make:entity

Luego, si queremos filtrar los clientes por cuenta… para no repetir código utilizamos un Trait…

Aquí el Trait… como ven muy simple.

Ahora arrancamos con la magia… creamos un SQLFilter donde se agrega la logica.. de como vamos a filtrar y tambien importante cuando… el cuando lo sabemos con un Helper que definimos más abajo…

Para que esto funcione, debemos definir el «Id» a filtrar en el código anterior… esto se hace con un Configurator, el cual no es otra cosa que un EventListener al que se le hacemos un inject de Doctrine y el manejo de la sesión de usuarios. Tomando el usuario conectado, le preguntamos a que cuenta pertenece, tomamos el ID y lo seteamos al filtro de Doctrine.

Este Helper es para reconocer si la entidad debe ser filtrada por el AccountFilter o solo dejarla pasar.

Y aca las configuraciones… primero para que lo reconozca Doctrine al Filter.

Y ahora la definición para que se reconozca el EventListener.

That’s all folks.

PHP 7.2 + mcrypt en Mac OSX Sierra

Como putee por encontrar esto, ahora lo comparto, y me lo guardo… como siempre.

Supongo que tienen instalado PHP con Homebrew, ahora tenemos que hacer funcionar mcrypt por alguna dependencia de un paquete no actualizado.

Bueno, PHP no lo tiene como paquete oficial, pero esta en PECL. El otro problema es que hay que tener instalada la libreria mcrypt para que cuando PECL lo compile encuentre las cabeceras.

Tampoco es dificil, solo no esta muy bien documentado que digamos.

luego… hacemos la magia de PECL

Somos felices…

PHP 7+ en Debian Jessie y Stretch

Es fácil no tengo ganas de escribir, aca esta la papa:

https://packages.sury.org

Por lo que leí es un maintener de Debian, así que tiene un buen nivel de confiabilidad (no dejen de chequearlo ustedes).

Para sacar andando los repos… todo lo que necesitan es el siguiente README:

https://packages.sury.org/php/README.txt

Ok, me compadeci y agregue una lineas extras…

PHP CLI ya levanto todo bien desde el apt-get install.

 

Nos vemos…

 

 

Instalar Redmine usando Docker

La instalación de Redmine suele ser medio un dolor de cabeza si no estas en el palo de Ruby.

No quise sufrir está vez y lo levante desde un container de Docker especificamente de Redmine.

Basándome en la documentación del link anterior, mejore algunas configuraciones para extraer los datos que maneja el sistema de adentro del contenedor (no esta bueno dejar datos que uno quiere persistir dentro del contenedor).

¿Como lo instale?

Primero necesito levantar una base de datos:

¿Que tiene diferente el comando con el del tutorial original?

  • Saco el directorio /var/lib/mysql para persistirlo si borro el contenedor.
  • Público el puerto 3066 para poder conectarme desde afuera de los contenedores al MySQL.

Sobre este ultimo bullet, es necesario hacer un cambio para poder conectarse desde afuera:

Accedo al contenedor, abro el cliente MySQL local y ejecuto el siguiente comando:

En nuestro caso teníamos una base vieja, por lo que cargue el backup dentro del MySQL antes de arrancar el contenedor de Redmine para que en lugar de crear una base nueva, intente migrarla, no voy a explicar el como, supongo que lo saben hacer.

Sigo con la instalación levantando el contenedor de Docker.

¿Que tiene diferente el comando con el del tutorial original?

  • Cargo la configuración desde afuera /usr/src/redmine/config/configuration.yml
  • Utilizamos SAML, por lo que cargo una configuración especifica /usr/src/redmine/config/initializers/saml.rb
  • Extraigo el directorio plugins por fuera del container, para poder persitir
  • Extraigo el directorio files por fuera del container, para poder persitir
  • Público el puerto 3000 para poder conectarme desde afuera.

Luego con un apache en modo proxy, transformo el puerto 80 en 3000. (Ahora que lo pienso podría no ser necesario ya que con el mismo Docker lo puedo transformar de 3000 a 80)

¿Como actualizar?

Los pasos básicamente son:

  1. Actualizo la imagen
  2. Paro el contenedor
  3. Borro el contenedor
  4. Creo nuevamente el contenedor (pero está vez lo hace con la imagen nueva)

La versión en comandos es:

¿Si está caído?

Proba si realmente está caído.

Y si lo está:

¿Y si quiero ver algo dentro del docker?

Con esto nos da una consola bash dentro del container

Implementando g3w3 (SIU-Guaraní para alumnos) y que se la banque!

logo_medio

Me toco una difícil, y que no sabia realmente como solucionar. Fue un trabajo muy fuerte en equipo:

  • Daniel Palazzo (DBA) @palazzo_d http://danielpalazzo.com.ar/
  • Lucas Szczuczko (sysadmin)
  • Nicolas Samus (Sysadmin) @nikosamus

Lo que implementamos fue una solución con un frontend que balance carga y varios nodos backend con la aplicación. La aplicación se conecta a una base de datos (DB1) y por seguridad generamos dos replicas, en el mismo cluster y otro cluster (para no tener dependencia de ningun tipo). Como al empezar a tener mucho trafico se generaban demasiadas conexiones contra la base instalamos un pgPool para manejarlo de una manera mas eficiente.

Por ahora ahora la solución que buscamos es solo performance y seguridad de datos (¡que no se pierda nada!), próximamente buscamos alta disponibilidad.

DiagramaImplementacionG3W3-2

Y que la fuerza nos acompañe, después les cuento como nos fue…

No se la banco!… la base volo por los aires. Y miren que si salio mal que nos dedicaron un meme.

Mejorando performance de Apache

apache-logo

Espero que esto sea la «parte 1», esto es una primera aproximación, claramente despues hay que ajustar las configuraciones a cada sitio, pero por ahora con esto mejora sustancialmente.

Lo que propongo es agregar un par de configuraciones para reducir la cantidad de contenido que se trafica después de la primera visita.

Sigue leyendo

Logstash filter para PHP errors

logstash-logoLas aplicaciones tienen errores, algunos mas graves otros menos graves. Algunos mas visibles, otros irreproducibles. Los distintos lenguajes y servidores de aplicación hacen logs de los errores que se encuentran. Pero seamos sinceros, a menos que nos llamen para decirnos de que algo anda mal, el 90% de las veces no nos entereamos y probablemente ni nos interese (hay cosas mas divertidas para hacer que casar bugs).

Para ser un poco mas pro activo en la búsqueda de problemas, o para hacernos la vida un poco mas facil a la hora de buscar la causa del error cuando ya no nos lo reportaron, es necesario revisar los logs de la aplicación. Pero es un dolor de cabeza!!!

Por todo esto estoy trabajando un poco para poner en funcionamiento una instancia del stack ELK (intentando sin exito hacer algunos dashboards útiles) y no pude encontrar un parsing decente de los logs de Apache para los errores PHP, y así tener datos mas útiles sobre los errores, por lo que arme uno propio.

Aquí lo comparto en un gist la configuración que arme (próximamente mas info).

Sigue leyendo