CI/CD Homelab Services + Webs 🢃2
Voy a intentar explicar como es la estructura completa del stack de CI/CD que esta configurado en mi {{homelab}} y que actualmente estoy usando para hacer deploy de mi {{digital-garden}} y de los servicios satélites que están públicos.
Como repositorio estoy usando {{forgejo}}, como CI/CD {{woodpecker}} y como registry de Docker {{private-docker-registry}}.
Actualmente el job de CI/CD se corre en cada repo habilitado, cuando genero una nueva release desde el repositorio. Esta es la forma que vengo usando hace tiempo para dejar master
libre y poder ir pusheando cosas sin tener que andar pensando si eso iba a terminar subido o no a producción.
El proceso de CI/CD se encarga de hacer checkout del código para el tag que corresponde al release, después hace el build de la imagen de Docker con los pasos correspondientes, los pasos pueden variar dependiendo el proyecto, hay proyectos para los que necesito hacer un proceso de build mas completo y para otros con solo buildear {{Hugo}} alcanza. Dentro de ese build el resultado final (que comunmente es HTML, CSS y JS) se copia dentro del directorio base / default de Apache {{hhtpd}} que se encarga de servir el contenido. Por ultimo en esta etapa, la imagen se sube al registry y se tagea como latest
.
Para el deploy, lo que sucede es que desde el mismo action, se ejecuta un script en el server, que lo que hace es hacer un docker compose pull
para bajar la ultima versión de la imagen del servicio, y hacer un docker compose up
para reiniciar el servicio. Con eso queda deployada la nueva versión de la página / servicio.
Limpieza de Cache
Actualmente estoy usando {{Cloudflare}} como {{CDN}} y como proxy de entrada. Si bien me trae un montón de beneficios a nivel CDN, a nivel seguridad, a nivel proxy, también trae algunas desventajas sobre todo para páginas que son estáticas como las que estoy deployando yo. Es posible que una vez que la nueva versión de un página este deployada el usuario no la vea por tema de cache, el cache de Cloudflare esta configurado para estar disponible durante 8 horas, eso quiere decir que cuando alguien entra a una de mis páginas el navegador guarda los recursos durante 8hs y recién pasado ese tiempo vuelve a pedir datos a Cloudflare. En ese tiempo es posible que haya gente que vea una versión vieja y otros una versión nueva.
Como no tengo necesidad de que siempre sea la ultima version la que se vea, puedo aguantar ese tiempo, pero también puedo buscar formas de mejorar esto y por suerte existen.
Todavía no llegue a probarlo pero tengo la posibilidad de que el webserver que estoy usando, en mi caso Apache httpd, devuelva el contenido con unos headers especiales que Cloudflare puede usar para identificar versiones cacheadas del contenido. De esta forma si tengo deployada la versión 1.1
con el header correspondiente y deployo la versión 1.2
puedo avisarle a Cloudflare mediante una request a la API interna que invalide el contenido con la versión 1.1
y eso hace que Cloudflare no aguante el tiempo definido de vida del cache para invalidar el contenido que esta en los distintos edges.
Posibles mejoras
- Una mejora sería usar una imagen base, donde este configurado Apache Httpd. De esta forma cuando tenga que actualizar la versión, lo tendría que hacer solo en un lugar. O si tengo que hacer un ajuste de seguridad, también lo haría en un solo lugar.
- Ver de que forma se podría monitorear el proceso de CI/CD, sobre todo la parte de logs cuando algo falla. Tal vez agregar notificaciones extras.
- Alguna herramienta de provisioning o Infrastructure as Code ({{Ansible}}? {{Terraform}}?)