Este monorepo concentra todo lo necesario para levantar y mantener el ecosistema de mlorente.dev:
- Front‑end moderno en Astro (
apps/web) - Blog estático en Jekyll (
apps/blog) - API REST en Go 21 (
apps/api) - Automatización low‑code con n8n
- Observabilidad (Vector, Prometheus, Grafana, etc.)
- Gestión Docker con Portainer
- Traefik & Nginx como reverse proxies
- Orquestación de despliegues con Ansible
- GitHub Actions para CI (build + push imágenes)
- Makefile como interfaz de mando única (dev, build, deploy)
CD manual → Las imágenes se construyen y publican automáticamente, pero el despliegue se hace a mano ejecutando
make deploysobre el servidor remoto.
- Estructura del repositorio
- Requisitos
- Puesta en marcha rápida
- Workflow de desarrollo local
- CI en GitHub Actions
- Despliegue manual
- Referencia de comandos Makefile
- Preguntas frecuentes
- Licencia
.
├── apps/ # Micro‑servicios y apps de usuario
│ ├── api/ # API Go (Dockerised)
│ ├── blog/ # Jekyll site
│ ├── web/ # Astro front‑end
│ ├── n8n/ # n8n + flows
│ ├── monitoring/ # Vector, Prometheus, Grafana
│ └── portainer/ # Portainer stack
├── infra/ # Infra as Code
│ ├── ansible/ # Playbooks, roles, inventories
│ ├── traefik/ # Dyn. & static config
│ └── nginx/ # Error pages, fallback
├── scripts/ # Bash utilidades (generar configs, secrets…)
├── .github/workflows/ # CI (build/push) — *no* despliegue
├── Makefile # Punto de entrada (dev / build / deploy)
├── .env.example # Variables globales
└── docs/ # Contribución, CubeLab, etc.
| Herramienta | Versión mínima | Uso |
|---|---|---|
| Docker Engine | 24 + | Contenedores local/prod |
| Docker Compose v2 | 2.20 + | Orquestación dev/prod |
| Make | 4.2 + | DSL de automatización |
| Git | — | SCM |
| Node 20 & npm 10 | (solo para frontend) | |
| Ruby 3.2 & Bundler | (solo para blog) | |
| Go 21 | (solo para API) | |
| Ansible | 9 + | Playbooks remotos |
Opcional: gh CLI para gestionar secrets y jq para utilidades.
# 1. Clona el repo
$ git clone git@github.com:mlorente/mlorente.dev.git && cd mlorente.dev
# 2. Crea tus variables (globales)
$ cp .env.example .env && ${EDITOR} .env
# 3. Prepara dependencias locales (node, ruby, etc.)
$ make env-setup # instala toolchain necesaria
# 4. Levanta todo en modo dev
$ make up # Traefik + todas las apps
# 5. Accede ↴
# http://site.mlorentedev.test (web)
# http://blog.mlorentedev.test (blog)
# http://api.mlorentedev.test/api (API)
# http://traefik.mlorentedev.test:8080 (dashboard)Tips:
- Añade las entradas
*.mlorentedev.testa/etc/hostssi no usas DNS local. - Cada app tiene su
.env.example; cópialo si necesitas variables adicionales. - ¿Solo quieres una app?
make up-web/make up-blog/ …
graph TD;
A[make up‑traefik] --> B1[make up‑blog];
A --> B2[make up‑web];
A --> B3[make up‑api];
subgraph Navegador
C1(site.mlorentedev.test) --> A;
end
- Traefik se levanta primero y expone los nombres de host locales.
- Cada servicio se reconstruye en caliente (
docker compose ...dev.yml). - Hot‑reload: Astro (port 4321), Jekyll (4000), Go (air auto‑reload).
- Logs en vivo:
make logs. - Para parar todo:
make downodocker compose down -vpor carpeta.
| Fase | Workflow | Descripción |
|---|---|---|
| Dispatcher | ci-01-dispatch.yml |
Detecta apps cambiadas y llama a build por matriz |
| Build + Push | ci-02-pipeline.yml → ci-03-publish.yml |
Linter + tests → docker buildx multi‑arch → push a Docker Hub con etiquetas:latest, semver (vX.Y.Z), rama (develop, feature/…) & short‑SHA |
| Release | ci-04-release.yml |
Versión oficial manual (gh release) → retag imágenes → bundle global-release-vX.Y.Z.zip |
Resultado: imágenes listas en el registry no se despliegan solas.
Recomendación: usa un usuario dedicado (
mlorente-deployer) con acceso passwordless sudo y Docker ya instalado.
-
Pre‑bootstrap (solo primera vez)
make setup ENV=production SSH_HOST=mlorente-deployer@my.vps.ip
Instala paquetes, crea red docker, copia configs base…
-
Desplegar / actualizar
make deploy ENV=production
Internamente ejecuta:
ansible-playbook infra/ansible/playbooks/deploy.yml -e env=production. -
Comprobar
make status ENV=production # docker ps remoto make logs ENV=production # tail -f de contenedores
-
Rollback: todo está versionado con tags → basta con cambiar variables y relanzar
make deploy.
| Categoría | Comando | Acción |
|---|---|---|
| Setup | make check |
Verifica prerequisitos locales |
make env-setup |
Instala toolchain Node, Ruby, Go | |
make create-network |
Crea red mlorente_net si falta |
|
| Desarrollo | make up |
Levanta Traefik + todas las apps |
make up-web / up-api / up-blog |
Solo un servicio | |
make down |
Derriba todo | |
| Build / Push | make push-app APP=web |
Construye + push multi‑arch |
make push-all |
Todas las apps | |
| Deploy | make setup ENV=staging |
Bootstrap servidor remoto |
make deploy ENV=staging |
Despliega imágenes ya publicadas | |
| Utilidades | make generate-config |
Renderiza templates Traefik + Ansible |
make setup-secrets |
Sincroniza .env → GitHub Secrets |
Ejecuta
make helppara ver la lista completa y descripciones coloreadas.
- 📖 Wiki - Índice Completo - Punto de entrada principal - Navegación por roles, búsqueda rápida y enlaces cruzados
- ⚡ How-To - Referencia Rápida - Comandos y tareas comunes organizados por categorías
- 🏗️ ADRs - Decisiones Arquitectónicas - 10 Architecture Decision Records explicando el "por qué" del diseño
- 🏷️ Estrategia de Versionado - Cómo funcionan las imágenes Docker y releases por rama
- 🚀 Despliegue Avanzado - Configuración avanzada de servidores y despliegues
- 🔧 Resolución de Problemas - Solución a problemas comunes y debugging
- ⚙️ Internals CI/CD - Funcionamiento interno de los workflows (1,388 líneas)
- 👥 Guía de Contribución - Convenciones de código, flujo de desarrollo y mejores prácticas
¿Necesito Ansible para desarrollo local? No. Solo para despliegues remotos.
¿Se podría automatizar el CD? Sí; bastaría con añadir un job que, tras ci-02-pipeline, ejecute make deploy con ansible-playbook en el runner o self‑hosted.
¿Cómo gestiono certificados en staging? Usa make copy-certificates ENV=staging y añádelos a tu almacén de confianza local.
¿Puedo usar otra URL local? Sí, cambia DOMAIN_LOCAL en .env y actualiza /etc/hosts.
“Works on my machine” no es suficiente. Con este Makefile y Ansible el despliegue es reproducible y predecible.