<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Webmago Dev</title>
	<atom:link href="https://webmago.dev/feed/" rel="self" type="application/rss+xml" />
	<link>https://webmago.dev</link>
	<description>Creando codigo desde 1990</description>
	<lastBuildDate>Mon, 28 Jul 2025 19:45:31 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
<image>
	<url>https://webmago.dev/buvytsan/2019/09/cropped-WebMago2019-2-32x32.png</url>
	<title>Webmago Dev</title>
	<link>https://webmago.dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>🚀 ¿Tu equipo aún gestiona versiones con Excel o mensajes sueltos en Archivos de Texto? Es momento de evolucionar</title>
		<link>https://webmago.dev/%f0%9f%9a%80-tu-equipo-aun-gestiona-versiones-con-excel-o-mensajes-sueltos-en-archivos-de-texto-es-momento-de-evolucionar/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Mon, 28 Jul 2025 18:38:50 +0000</pubDate>
				<category><![CDATA[devops]]></category>
		<category><![CDATA[wintercms]]></category>
		<category><![CDATA[ambientes]]></category>
		<category><![CDATA[atlasversion]]></category>
		<category><![CDATA[gestion]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=5925</guid>
					<description><![CDATA[<p>La gestión de versiones y despliegues es un reto real para startups y empresas de software en crecimiento. Entornos múltiples, cambios constantes, auditorías, errores humanos… todo se vuelve más complejo sin una herramienta que lo centralice todo. &#160; 🎯 AtlasVersion es la solución mexicana creada pensando en los desafíos reales que enfrentan los equipos de [&#8230;]</p>
The post <a href="https://webmago.dev/%f0%9f%9a%80-tu-equipo-aun-gestiona-versiones-con-excel-o-mensajes-sueltos-en-archivos-de-texto-es-momento-de-evolucionar/">🚀 ¿Tu equipo aún gestiona versiones con Excel o mensajes sueltos en Archivos de Texto? Es momento de evolucionar</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<div>La gestión de versiones y despliegues es un reto real para startups y empresas de software en crecimiento. Entornos múltiples, cambios constantes, auditorías, errores humanos… todo se vuelve más complejo sin una herramienta que lo centralice todo.</div>
<p>&nbsp;</p>
<div>🎯 AtlasVersion es la solución mexicana creada pensando en los desafíos reales que enfrentan los equipos de desarrollo locales. Con trazabilidad completa, alertas automáticas por Slack o correo, exportación de reportes para auditoría, e integración con tus pipelines CI/CD, AtlasVersion convierte el caos en control.</div>
<p>&nbsp;</p>
<div>¿Lo mejor? No necesitas cambiar tu stack. AtlasVersion se adapta a tu flujo y no al revés.</div>
<p>&nbsp;</p>
<div>👨‍💻 Desde CTOs hasta DevOps, quienes ya lo usan saben que es más que una herramienta: es un aliado estratégico para liberar versiones de forma segura, ordenada y sin dolores de cabeza.</div>
<p>&nbsp;</p>
<div>📌 Porque nadie conoce mejor tu realidad que una solución hecha en México para empresas mexicanas.</div>
<p>&nbsp;</p>
<div>👉 Agenda tu demo sin costo y conoce cómo AtlasVersion puede transformar tu gestión de versiones:</div>
<div>🔗<a title="Agendar una demo" href="https://www.atlasversion.dev" target="_blank" rel="noopener"> www.atlasversion.dev</a></div>The post <a href="https://webmago.dev/%f0%9f%9a%80-tu-equipo-aun-gestiona-versiones-con-excel-o-mensajes-sueltos-en-archivos-de-texto-es-momento-de-evolucionar/">🚀 ¿Tu equipo aún gestiona versiones con Excel o mensajes sueltos en Archivos de Texto? Es momento de evolucionar</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Infrastructure as Code con Pulumi: Mejores Prácticas para DevOps y Startups SaaS</title>
		<link>https://webmago.dev/infrastructure-as-code-con-pulumi-mejores-practicas-para-devops-y-startups-saas/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Thu, 03 Jul 2025 13:09:56 +0000</pubDate>
				<category><![CDATA[devops]]></category>
		<category><![CDATA[digital ocean]]></category>
		<category><![CDATA[gcp]]></category>
		<category><![CDATA[pulumi]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[IaC]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=5921</guid>
					<description><![CDATA[<p>En el mundo moderno de la infraestructura cloud, Infrastructure as Code (IaC) se ha convertido en un pilar fundamental para equipos de DevOps, ingenieros de infraestructura y startups SaaS. Entre las herramientas disponibles, Pulumi destaca por su flexibilidad, soporte multi-cloud y capacidad de utilizar lenguajes de programación tradicionales como Python, TypeScript y Go. En este artículo, exploraremos las mejores prácticas [&#8230;]</p>
The post <a href="https://webmago.dev/infrastructure-as-code-con-pulumi-mejores-practicas-para-devops-y-startups-saas/">Infrastructure as Code con Pulumi: Mejores Prácticas para DevOps y Startups SaaS</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p class="ds-markdown-paragraph">En el mundo moderno de la infraestructura cloud, <strong>Infrastructure as Code (IaC)</strong> se ha convertido en un pilar fundamental para equipos de DevOps, ingenieros de infraestructura y startups SaaS. Entre las herramientas disponibles, <strong>Pulumi</strong> destaca por su flexibilidad, soporte multi-cloud y capacidad de utilizar lenguajes de programación tradicionales como Python, TypeScript y Go.</p>
<p class="ds-markdown-paragraph">En este artículo, exploraremos las <strong>mejores prácticas para implementar IaC con Pulumi</strong>, con ejemplos prácticos en <strong>GCP, AWS y DigitalOcean</strong>, estrategias avanzadas para <strong>Kubernetes</strong> y consideraciones clave en <strong>Disaster Recovery Planning (DRP)</strong>.</p>
<hr />
<h2><strong>1. ¿Por qué Pulumi para IaC?</strong></h2>
<p class="ds-markdown-paragraph">Pulumi ofrece ventajas únicas frente a alternativas como Terraform o CloudFormation:</p>
<p class="ds-markdown-paragraph">✅ <strong>Lenguajes familiares</strong> (Python, TypeScript, Go) en lugar de DSLs propietarios.<br />
✅ <strong>Soporte multi-cloud</strong> (AWS, GCP, Azure, DigitalOcean, Kubernetes).<br />
✅ <strong>Estado de infraestructura gestionado</strong> (Pulumi Service, S3, etc.).<br />
✅ <strong>Integración con CI/CD</strong> nativa.<br />
✅ <strong>Reutilización de código</strong> mediante componentes y librerías.</p>
<h3><strong>Ejemplo: Desplegando un cluster Kubernetes en DigitalOcean con Pulumi (Python)</strong></h3>
<pre><code class="language-python" data-line="">import pulumi
import pulumi_digitalocean as do
# Crear un cluster Kubernetes en DigitalOcean
cluster = do.KubernetesCluster(
    &quot;saas-cluster&quot;,
    region=&quot;nyc1&quot;,
    version=&quot;1.25.4-do.0&quot;,
    node_pool={
        &quot;name&quot;: &quot;default-pool&quot;,
        &quot;size&quot;: &quot;s-2vcpu-4gb&quot;,
        &quot;node_count&quot;: 3,
    }
)
# Exportar el kubeconfig
pulumi.export(&quot;kubeconfig&quot;, cluster.kube_configs[0].raw_config)</code>

</pre>
<p class="ds-markdown-paragraph">Este código despliega un cluster gestionado en DigitalOcean con tres nodos, listo para integrarse en un pipeline de CI/CD.</p>
<hr />
<h2><strong>2. Mejores Prácticas para IaC con Pulumi</strong></h2>
<h3><strong>🔹 Modularización y Reutilización</strong></h3>
<p class="ds-markdown-paragraph">Evitar scripts monolíticos. En su lugar, estructurar el código en <strong>componentes reutilizables</strong>:</p>
<pre><code class="language-python" data-line=""># Ejemplo: Módulo para un bucket S3 con políticas de acceso
class SecureBucket(pulumi.ComponentResource):
    def __init__(self, name, **kwargs):
        super().__init__(&quot;custom:SecureBucket&quot;, name, **kwargs)
        
        self.bucket = aws.s3.Bucket(name)
        aws.s3.BucketPolicy(
            f&quot;{name}-policy&quot;,
            bucket=self.bucket.id,
            policy=json.dumps({
                &quot;Version&quot;: &quot;2012-10-17&quot;,
                &quot;Statement&quot;: [{
                    &quot;Effect&quot;: &quot;Deny&quot;,
                    &quot;Principal&quot;: &quot;*&quot;,
                    &quot;Action&quot;: &quot;s3:*&quot;,
                    &quot;Resource&quot;: [self.bucket.arn, f&quot;{self.bucket.arn}/*&quot;],
                    &quot;Condition&quot;: {&quot;Bool&quot;: {&quot;aws:SecureTransport&quot;: False}}
                }]
            })
        )
# Uso del módulo
bucket = SecureBucket(&quot;prod-data-lake&quot;)</code></pre>
<p>&nbsp;</p>
<h3><strong>🔹 Gestión de Estado (State Management)</strong></h3>
<p class="ds-markdown-paragraph">Pulumi guarda el estado de la infraestructura. Opciones recomendadas:</p>
<ul>
<li>
<p class="ds-markdown-paragraph"><strong>Pulumi Service</strong> (gratis para proyectos pequeños).</p>
</li>
<li>
<p class="ds-markdown-paragraph"><strong>Amazon S3 / Google Cloud Storage</strong> (para mayor control).</p>
</li>
</ul>
<p>&nbsp;</p>
<pre><code class="language-bash" data-line=""># Inicializar un proyecto con backend en S3
pulumi login s3://my-pulumi-state-bucket</code></pre>
<h3><strong>🔹 CI/CD Integrado</strong></h3>
<p class="ds-markdown-paragraph">Ejemplo con GitHub Actions:</p>
<pre><code class="language-bash" data-line="">name: Deploy Infrastructure
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: pulumi/actions@v3
        with:
          command: up
          stack-name: prod
        env:
          PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}</code></pre>
<p>&nbsp;</p>
<h2><strong>3. Kubernetes con Pulumi: Gestión Eficiente</strong></h2>
<p class="ds-markdown-paragraph">Pulumi permite gestionar <strong>Kubernetes de forma declarativa</strong> sin necesidad de <code class="" data-line="">kubectl</code> manual.</p>
<h3><strong>Ejemplo: Despliegue de una App en Kubernetes</strong></h3>
<pre><code class="language-python" data-line="">import pulumi_kubernetes as k8s
# Crear un Namespace
app_ns = k8s.core.v1.Namespace(&quot;app-ns&quot;)
# Desplegar una aplicación
app = k8s.apps.v1.Deployment(
    &quot;app-deployment&quot;,
    metadata={&quot;namespace&quot;: app_ns.metadata[&quot;name&quot;]},
    spec={
        &quot;replicas&quot;: 3,
        &quot;selector&quot;: {&quot;match_labels&quot;: {&quot;app&quot;: &quot;my-saas&quot;}},
        &quot;template&quot;: {
            &quot;metadata&quot;: {&quot;labels&quot;: {&quot;app&quot;: &quot;my-saas&quot;}},
            &quot;spec&quot;: {
                &quot;containers&quot;: [{
                    &quot;name&quot;: &quot;app&quot;,
                    &quot;image&quot;: &quot;my-registry/my-saas-app:latest&quot;,
                    &quot;ports&quot;: [{&quot;container_port&quot;: 8080}]
                }]
            }
        }
    }
)
# Exponer el servicio
service = k8s.core.v1.Service(
    &quot;app-service&quot;,
    metadata={&quot;namespace&quot;: app_ns.metadata[&quot;name&quot;]},
    spec={
        &quot;selector&quot;: {&quot;app&quot;: &quot;my-saas&quot;},
        &quot;ports&quot;: [{&quot;port&quot;: 80, &quot;target_port&quot;: 8080}],
        &quot;type&quot;: &quot;LoadBalancer&quot;
    }
)
pulumi.export(&quot;service_url&quot;, service.status[&quot;load_balancer&quot;][&quot;ingress&quot;][0][&quot;hostname&quot;])</code></pre>
<p>&nbsp;</p>
<hr />
<h2><strong>4. Disaster Recovery Planning (DRP) con Pulumi</strong></h2>
<p class="ds-markdown-paragraph">Un buen DRP define <strong>RTO (Recovery Time Objective)</strong> y <strong>RPO (Recovery Point Objective)</strong>.</p>
<h3><strong>Visualización de RTO/RPO</strong></h3>
<p class="ds-markdown-paragraph">(Imagen conceptual: Tabla comparando estrategias de backup y replicación)</p>
<div class="markdown-table-wrapper">
<table>
<thead>
<tr>
<th>Estrategia</th>
<th>RTO (Tiempo de recuperación)</th>
<th>RPO (Pérdida de datos máxima)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Backup Diario</td>
<td>Horas</td>
<td>24 horas</td>
</tr>
<tr>
<td>Replicación en Caliente</td>
<td>Minutos</td>
<td>Segundos</td>
</tr>
<tr>
<td>Multi-Región AWS</td>
<td>Minutos</td>
<td>Casi cero</td>
</tr>
</tbody>
</table>
</div>
<h3><strong>Ejemplo: Configuración de DRP en AWS</strong></h3>
<pre><code class="language-python" data-line="">import pulumi_aws as aws
# Replicación de buckets S3 entre regiones
primary_bucket = aws.s3.Bucket(&quot;primary-bucket&quot;, acl=&quot;private&quot;)
replica_bucket = aws.s3.Bucket(&quot;replica-bucket&quot;, acl=&quot;private&quot;)
aws.s3.BucketReplication(
    &quot;replication&quot;,
    bucket=primary_bucket.id,
    role=replication_role.arn,
    rules=[{
        &quot;status&quot;: &quot;Enabled&quot;,
        &quot;destination&quot;: {
            &quot;bucket&quot;: replica_bucket.arn,
            &quot;storage_class&quot;: &quot;STANDARD&quot;
        }
    }]
)</code></pre>
<h2><strong>5. Conclusión</strong></h2>
<p class="ds-markdown-paragraph">Pulumi es una herramienta poderosa para <strong>automatizar infraestructura cloud</strong> con código real, mejorando la productividad de equipos DevOps y startups SaaS.</p>
<p class="ds-markdown-paragraph">🔹 <strong>Mejores prácticas clave:</strong></p>
<ul>
<li>
<p class="ds-markdown-paragraph">Modularizar el código IaC.</p>
</li>
<li>
<p class="ds-markdown-paragraph">Gestionar el estado de forma segura.</p>
</li>
<li>
<p class="ds-markdown-paragraph">Integrar con CI/CD.</p>
</li>
<li>
<p class="ds-markdown-paragraph">Planificar Disaster Recovery (RTO/RPO).</p>
</li>
</ul>
<p class="ds-markdown-paragraph">¿Listo para probar Pulumi? Comienza con su <a href="https://www.pulumi.com/docs/" target="_blank" rel="noopener noreferrer">documentación oficial</a>.</p>
<hr />
<p class="ds-markdown-paragraph">📢 <strong>¿Quieres más detalles sobre algún tema?</strong> ¡<a title="Contactame" href="https://webmago.dev/#contact" target="_blank" rel="noopener">Contactame</a>!</p>
<p class="ds-markdown-paragraph">#DevOps #InfrastructureAsCode #Pulumi #Kubernetes #CloudComputing #SaaS #DisasterRecovery</p>
<p>&nbsp;</p>The post <a href="https://webmago.dev/infrastructure-as-code-con-pulumi-mejores-practicas-para-devops-y-startups-saas/">Infrastructure as Code con Pulumi: Mejores Prácticas para DevOps y Startups SaaS</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automatizando Resultados Electorales en Kubernetes: Un Cron Job Crítico para México</title>
		<link>https://webmago.dev/automatizando-resultados-electorales-en-kubernetes-un-cron-job-critico-para-mexico/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Fri, 27 Jun 2025 19:42:31 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=5915</guid>
					<description><![CDATA[<p>1. Contexto del Proyecto El 1 de junio de 2025, durante las elecciones judiciales en México, mi equipo fue responsable de una misión crítica: garantizar la descarga, validación y publicación automatizada de resultados electorales provenientes del INE (Instituto Nacional Electoral). Este flujo de datos tenía que funcionar 24/7, con una frecuencia de actualización de cada [&#8230;]</p>
The post <a href="https://webmago.dev/automatizando-resultados-electorales-en-kubernetes-un-cron-job-critico-para-mexico/">Automatizando Resultados Electorales en Kubernetes: Un Cron Job Crítico para México</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<h3 data-start="109" data-end="137">1. Contexto del Proyecto</h3>
<p data-start="139" data-end="573">El <strong data-start="142" data-end="164">1 de junio de 2025</strong>, durante las elecciones judiciales en México, mi equipo fue responsable de una misión crítica: garantizar la descarga, validación y publicación automatizada de resultados electorales provenientes del <strong>INE</strong> (Instituto Nacional Electoral). Este flujo de datos tenía que funcionar <strong data-start="455" data-end="463">24/7</strong>, con una <strong data-start="473" data-end="522">frecuencia de actualización de cada 5 minutos</strong>, y con <strong data-start="530" data-end="572">máxima seguridad y tolerancia a fallos</strong>.</p>
<p data-start="575" data-end="907">Operamos bajo un entorno regulado y expuesto mediáticamente, donde cualquier retraso, inconsistencia o vulnerabilidad sería inaceptable. Para esto, diseñamos una solución de automatización sobre <strong data-start="770" data-end="784">Kubernetes</strong>, combinando scripting en <strong data-start="810" data-end="818">Bash</strong>, tokens de autenticación y firmas criptográficas GPG. Aquí les comparto cómo lo hicimos.</p>
<hr data-start="909" data-end="912" />
<h3 data-start="914" data-end="938">2. Desafíos Técnicos</h3>
<ul data-start="940" data-end="1441">
<li data-start="940" data-end="1066">
<p data-start="942" data-end="1066"><strong data-start="942" data-end="965">Alta disponibilidad</strong>: La solución debía ejecutarse cada 5 minutos, sin interrupciones, durante toda la jornada electoral.</p>
</li>
<li data-start="1067" data-end="1175">
<p data-start="1069" data-end="1175"><strong data-start="1069" data-end="1091">Seguridad de datos</strong>: Era indispensable garantizar la autenticidad y no-repudio de los datos publicados.</p>
</li>
<li data-start="1176" data-end="1301">
<p data-start="1178" data-end="1301"><strong data-start="1178" data-end="1202">Tolerancia a errores</strong>: El sistema debía manejar fallos parciales en servicios externos sin detener la operación general.</p>
</li>
<li data-start="1302" data-end="1441">
<p data-start="1304" data-end="1441"><strong data-start="1304" data-end="1334">Infraestructura controlada</strong>: El ambiente se desplegó sobre clústeres Kubernetes autoescalables con nodos específicos para tareas cron.</p>
</li>
</ul>
<hr data-start="1443" data-end="1446" />
<h3 data-start="1448" data-end="1476">3. Solución Implementada</h3>
<p data-start="1478" data-end="1560">Decidimos implementar un <strong data-start="1503" data-end="1543">cron job especializado en Kubernetes</strong>, responsable de:</p>
<ol data-start="1562" data-end="1831">
<li data-start="1562" data-end="1626">
<p data-start="1565" data-end="1626">Autenticarse con un sistema remoto mediante un <strong data-start="1612" data-end="1625">API Token</strong>.</p>
</li>
<li data-start="1627" data-end="1678">
<p data-start="1630" data-end="1678">Recuperar el archivo de los resultados.</p>
</li>
<li data-start="1679" data-end="1739">
<p data-start="1682" data-end="1739">Verificar y validar digitalmente los datos recibidos usando <strong data-start="1731" data-end="1738">GPG</strong>.</p>
</li>
<li data-start="1740" data-end="1831">
<p data-start="1743" data-end="1831">Publicar los datos procesados en uno micrositio (con backup inmediato).</p>
</li>
</ol>
<h3 data-start="2003" data-end="2044">4. Detalles de Implementación Técnica</h3>
<p data-start="2046" data-end="2089"><strong data-start="2046" data-end="2089">Archivo YAML del CronJob en Kubernetes:</strong></p>
<pre><code class="language-bash" data-line="">apiVersion: batch/v1
kind: CronJob
metadata:
  name: resultados-electorales
spec:
  schedule: &quot;*/5 * * * *&quot;
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: recolector
            image: myregistry.com/electoral-job:latest
            imagePullPolicy: Always
            env:
            - name: API_TOKEN
              valueFrom:
                secretKeyRef:
                  name: electoral-secrets
                  key: api-token
            volumeMounts:
            - name: gpg-keys
              mountPath: /gpg
            command: [&quot;/bin/sh&quot;]
            args: [&quot;-c&quot;, &quot;/scripts/monitor.sh&quot;]
          restartPolicy: OnFailure
          volumes:
          - name: gpg-keys
            secret:
              secretName: gpg-secret
</code></pre>
<p data-start="1833" data-end="1996">El job se ejecuta cada 5 minutos utilizando una imagen liviana basada en Alpine, con herramientas mínimas necesarias, reforzada para evitar accesos no autorizados.</p>
<p data-start="3569" data-end="3606"><strong data-start="3569" data-end="3606">Mecanismo de seguridad adicional:</strong></p>
<ul data-start="3608" data-end="3822">
<li data-start="3608" data-end="3664">
<p data-start="3610" data-end="3664">Las claves GPG se inyectan como secreto de Kubernetes.</p>
</li>
<li data-start="3665" data-end="3739">
<p data-start="3667" data-end="3739">Las salidas del script se redirigen a logs centralizados para auditoría.</p>
</li>
<li data-start="3740" data-end="3822">
<p data-start="3742" data-end="3822">Las fallas se notifican vía webhook a un canal Slack monitoreado en tiempo real.</p>
</li>
</ul>
<h3 data-start="3829" data-end="3861">5. Resultados y Aprendizajes</h3>
<ul data-start="3863" data-end="4233">
<li data-start="3863" data-end="3921">
<p data-start="3865" data-end="3921">🕔 <strong data-start="3868" data-end="3886">100% de uptime</strong> durante más de 24 horas continuas.</p>
</li>
<li data-start="3922" data-end="4006">
<p data-start="3924" data-end="4006">🔐 <strong data-start="3927" data-end="3956">0 incidentes de seguridad</strong>, gracias al control estricto de accesos y firmas.</p>
</li>
<li data-start="4007" data-end="4106">
<p data-start="4009" data-end="4106">📉 <strong data-start="4012" data-end="4032">Carga minimizada</strong> gracias a imágenes optimizadas y nodos taintados solo para procesamiento.</p>
</li>
<li data-start="4107" data-end="4233">
<p data-start="4109" data-end="4233">🔁 <strong data-start="4112" data-end="4142">Escalabilidad futura lista</strong>: el diseño permite extender el flujo a múltiples fuentes de datos judiciales o comiciales.</p>
</li>
</ul>
<p data-start="4235" data-end="4436">Este tipo de soluciones no solo demandan experiencia técnica, sino <strong data-start="4302" data-end="4324">criterio operativo</strong> y sentido de urgencia. Lo que está en juego es la <strong data-start="4375" data-end="4396">confianza pública</strong> y la <strong data-start="4402" data-end="4435">responsabilidad institucional</strong>.</p>
<h3 data-start="4443" data-end="4499">🚨 ¿Necesitas diseñar soluciones críticas como esta?</h3>
<p data-start="4501" data-end="4593">Si estás enfrentando un proyecto sensible en medios, gobierno o datos públicos, y necesitas:</p>
<ul data-start="4595" data-end="4731">
<li data-start="4595" data-end="4639">
<p data-start="4597" data-end="4639">Consultoría para despliegues en Kubernetes</p>
</li>
<li data-start="4640" data-end="4680">
<p data-start="4642" data-end="4680">Implementación de cron jobs confiables</p>
</li>
<li data-start="4681" data-end="4731">
<p data-start="4683" data-end="4731">Diseño de infraestructura segura y autoescalable</p>
</li>
</ul>
<p data-start="4733" data-end="4897">📩 <strong data-start="4736" data-end="4799"><a title="Contáctame para una sesión gratuita de diagnóstico técnico." href="https://webmago.dev/#contact" target="_blank" rel="noopener">Contáctame para una sesión gratuita de diagnóstico técnico</a>.</strong><br data-start="4799" data-end="4802" />Haz que tu próxima implementación funcione como un reloj suizo, incluso bajo presión electoral.</p>The post <a href="https://webmago.dev/automatizando-resultados-electorales-en-kubernetes-un-cron-job-critico-para-mexico/">Automatizando Resultados Electorales en Kubernetes: Un Cron Job Crítico para México</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automatizando el despliegue de artefactos Java: Mi experiencia con Cloud Build, Bash y Archiva en VMs</title>
		<link>https://webmago.dev/automatizando-el-despliegue-de-artefactos-java-mi-experiencia-con-cloud-build-bash-y-archiva-en-vms/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Thu, 15 May 2025 19:51:37 +0000</pubDate>
				<category><![CDATA[cloudbuild]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[gcp]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[cicd]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=5910</guid>
					<description><![CDATA[<p>Introducción En el mundo del desarrollo de software, la implementación de una pipeline de CI/CD robusta y eficiente es fundamental para mantener la agilidad y calidad del producto. Como desarrollador, me he enfrentado al reto de automatizar el despliegue de artefactos Java en múltiples entornos. En este artículo, compartiré mi experiencia implementando pipelines con Google [&#8230;]</p>
The post <a href="https://webmago.dev/automatizando-el-despliegue-de-artefactos-java-mi-experiencia-con-cloud-build-bash-y-archiva-en-vms/">Automatizando el despliegue de artefactos Java: Mi experiencia con Cloud Build, Bash y Archiva en VMs</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Introducción</h2>
<p class="whitespace-normal">En el mundo del desarrollo de software, la implementación de una pipeline de CI/CD robusta y eficiente es fundamental para mantener la agilidad y calidad del producto. Como desarrollador, me he enfrentado al reto de automatizar el despliegue de artefactos Java en múltiples entornos. En este artículo, compartiré mi experiencia implementando pipelines con Google Cloud Build, scripts Bash y el repositorio de artefactos Archiva para gestionar despliegues en máquinas virtuales.</p>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">El problema inicial</h2>
<p class="whitespace-normal">Antes de implementar nuestra solución automatizada, nos enfrentábamos a varios desafíos:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Despliegues manuales propensos a errores</li>
<li class="whitespace-normal break-words">Falta de consistencia entre entornos</li>
<li class="whitespace-normal break-words">Tiempos de entrega prolongados</li>
<li class="whitespace-normal break-words">Dificultad para rastrear qué versión estaba desplegada en cada entorno</li>
<li class="whitespace-normal break-words">Complejidad para gestionar dependencias y artefactos Java</li>
</ul>
<p class="whitespace-normal">Necesitábamos una solución que pudiera gestionar el ciclo completo: desde la compilación del código fuente hasta el despliegue en nuestras máquinas virtuales, manteniendo un registro central de los artefactos generados.</p>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Componentes de la solución</h2>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Google Cloud Build</h3>
<p class="whitespace-normal">Elegimos Cloud Build como el motor principal de nuestra pipeline de CI/CD por varias razones:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Integración nativa con Google Cloud Platform</li>
<li class="whitespace-normal break-words">Escalabilidad automática según las necesidades</li>
<li class="whitespace-normal break-words">Facilidad para definir pasos de construcción mediante archivos YAML</li>
<li class="whitespace-normal break-words">Capacidad para utilizar imágenes Docker personalizadas</li>
<li class="whitespace-normal break-words">API robusta para la integración con otros servicios</li>
</ul>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">SonarQube</h3>
<p class="whitespace-normal">Implementamos SonarQube como parte esencial de nuestra pipeline para garantizar la calidad del código:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Análisis estático para detectar bugs y vulnerabilidades</li>
<li class="whitespace-normal break-words">Medición de cobertura de pruebas</li>
<li class="whitespace-normal break-words">Evaluación continua de la deuda técnica</li>
<li class="whitespace-normal break-words">Verificación del cumplimiento de estándares de codificación</li>
<li class="whitespace-normal break-words">Integración perfecta con el flujo de CI/CD</li>
</ul>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Apache Archiva</h3>
<p class="whitespace-normal">Para la gestión de artefactos, implementamos Apache Archiva, un repositorio de artefactos que nos permitió:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Almacenar y versionar nuestros JAR, WAR y otros artefactos Java</li>
<li class="whitespace-normal break-words">Gestionar dependencias de manera centralizada</li>
<li class="whitespace-normal break-words">Establecer políticas de retención de artefactos</li>
<li class="whitespace-normal break-words">Controlar el acceso a los diferentes repositorios</li>
<li class="whitespace-normal break-words">Rastrear metadatos de los artefactos</li>
</ul>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Scripts Bash</h3>
<p class="whitespace-normal">El pegamento que unía todo nuestro sistema eran los scripts Bash, que nos proporcionaron:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Flexibilidad para adaptarnos a casos específicos</li>
<li class="whitespace-normal break-words">Capacidad para interactuar con APIs y servicios externos</li>
<li class="whitespace-normal break-words">Manejo de errores y reintentos personalizados</li>
<li class="whitespace-normal break-words">Despliegue en máquinas virtuales mediante SSH</li>
</ul>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Arquitectura de la pipeline</h2>
<p class="whitespace-normal">Nuestra pipeline de CI/CD sigue este proceso:</p>
<ol class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-decimal space-y-1.5 pl-7">
<li class="whitespace-normal break-words"><strong>Trigger</strong>: Un push a una rama específica o la creación de una tag desencadena la pipeline</li>
<li class="whitespace-normal break-words"><strong>Build</strong>: Cloud Build compila el código Java utilizando Maven o Gradle</li>
<li class="whitespace-normal break-words"><strong>Test</strong>: Se ejecutan pruebas unitarias e integración</li>
<li class="whitespace-normal break-words"><strong>Análisis de calidad</strong>: SonarQube realiza un análisis estático y evaluación de calidad del código</li>
<li class="whitespace-normal break-words"><strong>Empaquetado</strong>: Se generan los artefactos (JAR, WAR)</li>
<li class="whitespace-normal break-words"><strong>Publicación</strong>: Los artefactos se suben a Apache Archiva</li>
<li class="whitespace-normal break-words"><strong>Despliegue</strong>: Scripts Bash se conectan por SSH a las VMs y despliegan los artefactos</li>
</ol>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Implementación estratégica</h2>
<p class="whitespace-normal">La implementación de nuestra pipeline requirió un enfoque meticuloso para integrar correctamente todos los componentes. La configuración de Cloud Build con los pasos adecuados fue fundamental, así como la integración de SonarQube para garantizar que solo el código que cumpliera con los estándares de calidad pudiera pasar a producción.</p>
<p class="whitespace-normal">Desarrollamos scripts personalizados para manejar la comunicación entre los diferentes sistemas y establecimos puertas de calidad (quality gates) en cada etapa del proceso. El diseño modular nos permitió tener un sistema fácilmente adaptable a diferentes proyectos y entornos.</p>
<p class="whitespace-normal">La integración entre SonarQube, Archiva y nuestros scripts de despliegue fue uno de los aspectos más desafiantes, pero también uno de los más gratificantes una vez implementado correctamente. Cada componente tenía un papel bien definido en la cadena de CI/CD, lo que permitía identificar rápidamente cualquier problema y solucionarlo sin afectar al resto del sistema.</p>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Configuración de SonarQube</h3>
<p class="whitespace-normal">La integración de SonarQube fue crucial para mantener la calidad del código:</p>
<ol class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-decimal space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Establecimos Quality Gates con umbrales estrictos:
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Cobertura de código mínima del 80%</li>
<li class="whitespace-normal break-words">Cero vulnerabilidades críticas</li>
<li class="whitespace-normal break-words">Menos de 5% de código duplicado</li>
</ul>
</li>
<li class="whitespace-normal break-words">Configuramos reglas personalizadas según los estándares de nuestra organización</li>
<li class="whitespace-normal break-words">Implementamos webhooks para notificar al equipo sobre problemas detectados</li>
<li class="whitespace-normal break-words">Integramos los resultados del análisis como un paso bloqueante en nuestra pipeline</li>
</ol>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Configuración de Archiva</h3>
<p class="whitespace-normal">Para Archiva, creamos un repositorio interno y configuramos las políticas de seguridad:</p>
<ol class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-decimal space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Creamos usuarios específicos para despliegue con permisos limitados</li>
<li class="whitespace-normal break-words">Configuramos la retención de snapshots y releases</li>
<li class="whitespace-normal break-words">Establecimos políticas de proxy para dependencias externas</li>
<li class="whitespace-normal break-words">Configuramos índices para búsquedas eficientes</li>
</ol>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Lecciones aprendidas</h2>
<p class="whitespace-normal">Durante la implementación de esta solución, aprendí varias lecciones valiosas:</p>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Calidad como prioridad</h3>
<p class="whitespace-normal">La integración de SonarQube desde el principio nos ahorró innumerables horas de depuración y problemas en producción:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">El análisis continuo permite detectar problemas temprano en el ciclo de desarrollo</li>
<li class="whitespace-normal break-words">Los desarrolladores mejoraron sus prácticas al recibir retroalimentación inmediata</li>
<li class="whitespace-normal break-words">La visualización de métricas de calidad motivó al equipo a mejorar constantemente</li>
</ul>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Gestión de secretos</h3>
<p class="whitespace-normal">Implementamos un sistema robusto para la gestión de credenciales:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Secretos almacenados en Secret Manager de GCP</li>
<li class="whitespace-normal break-words">Variables de entorno seguras en Cloud Build</li>
<li class="whitespace-normal break-words">Cuentas de servicio con privilegios mínimos</li>
</ul>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Tolerancia a fallos</h3>
<p class="whitespace-normal">Los despliegues a veces fallaban por problemas de red o recursos. Mejoramos la resiliencia con:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Reintentos automáticos con backoff exponencial</li>
<li class="whitespace-normal break-words">Validaciones de estado tras el despliegue</li>
<li class="whitespace-normal break-words">Capacidad de rollback automático</li>
</ul>
<h3 class="text-lg font-bold text-text-100 mt-1 -mb-1.5">Paralelización</h3>
<p class="whitespace-normal">Para reducir los tiempos de despliegue en entornos con muchas VMs, implementamos:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words">Despliegues paralelos con control de concurrencia</li>
<li class="whitespace-normal break-words">Caché de artefactos entre pasos de la pipeline</li>
<li class="whitespace-normal break-words">Optimización de la compilación con compilación incremental</li>
</ul>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Resultados</h2>
<p class="whitespace-normal">La implementación de esta pipeline nos proporcionó beneficios significativos:</p>
<ul class="[&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-1.5 pl-7">
<li class="whitespace-normal break-words"><strong>Reducción del tiempo de despliegue</strong>: de 45 minutos a menos de 5 minutos</li>
<li class="whitespace-normal break-words"><strong>Eliminación de errores humanos</strong>: gracias a la automatización completa</li>
<li class="whitespace-normal break-words"><strong>Mejora en la calidad del código</strong>: las métricas de SonarQube mostraron una reducción del 40% en la deuda técnica</li>
<li class="whitespace-normal break-words"><strong>Mayor trazabilidad</strong>: registro completo de qué versión está en cada entorno</li>
<li class="whitespace-normal break-words"><strong>Mejora de la colaboración</strong>: el equipo puede concentrarse en desarrollo en lugar de operaciones</li>
<li class="whitespace-normal break-words"><strong>Escalabilidad</strong>: añadir nuevos entornos o servidores es trivial</li>
</ul>
<h2 class="text-xl font-bold text-text-100 mt-1 -mb-0.5">Conclusión</h2>
<p class="whitespace-normal">La combinación de Cloud Build, SonarQube, scripts Bash y Apache Archiva nos ha permitido crear una solución robusta para el despliegue de aplicaciones Java. Si bien he compartido algunos aspectos de nuestra implementación, las soluciones específicas para cada organización requieren un análisis detallado de su infraestructura, procesos y necesidades particulares.</p>
<p class="whitespace-normal">Esta arquitectura nos permitió no solo automatizar despliegues, sino también elevar significativamente la calidad del software entregado, reduciendo incidentes en producción y acelerando el ciclo de desarrollo.</p>
<p class="whitespace-normal">Para equipos que enfrentan retos similares, recomiendo un enfoque incremental y personalizado. Cada organización tiene necesidades únicas que deben ser cuidadosamente analizadas para implementar la solución óptima.</p>
<hr />
<p class="whitespace-normal"><em>¿Necesitas implementar una solución similar en tu organización? En <a href="https://webmago.dev/" target="_blank" rel="noopener">webmago.dev</a> ofrecemos consultoría especializada en la implementación de pipelines de CI/CD para entornos Java. <a title="Contactanos" href="https://webmago.dev/#contact" target="_blank" rel="noopener">Contáctanos</a> para explorar cómo podemos ayudarte a optimizar tus procesos de desarrollo y despliegue.</em></p>The post <a href="https://webmago.dev/automatizando-el-despliegue-de-artefactos-java-mi-experiencia-con-cloud-build-bash-y-archiva-en-vms/">Automatizando el despliegue de artefactos Java: Mi experiencia con Cloud Build, Bash y Archiva en VMs</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mi Experiencia con Google Cloud Functions: Validación y Procesamiento Seguro de Archivos</title>
		<link>https://webmago.dev/mi-experiencia-con-google-cloud-functions-validacion-y-procesamiento-seguro-de-archivos/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Fri, 09 May 2025 16:12:08 +0000</pubDate>
				<category><![CDATA[development]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[gcp]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=5903</guid>
					<description><![CDATA[<p>En este post, compartiré mi experiencia desarrollando una solución en Google Cloud Platform (GCP) que automatiza la validación y procesamiento de archivos utilizando Cloud Functions, Cloud Storage y validación de firmas digitales. 🔹 El Problema: Procesamiento Seguro de Archivos Un cliente necesitaba un sistema donde: Al subir un archivo cifrado y comprimido a un bucket de Cloud Storage, [&#8230;]</p>
The post <a href="https://webmago.dev/mi-experiencia-con-google-cloud-functions-validacion-y-procesamiento-seguro-de-archivos/">Mi Experiencia con Google Cloud Functions: Validación y Procesamiento Seguro de Archivos</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p class="ds-markdown-paragraph">En este post, compartiré mi experiencia desarrollando una solución en <strong>Google Cloud Platform (GCP)</strong> que automatiza la validación y procesamiento de archivos utilizando <strong>Cloud Functions, Cloud Storage y validación de firmas digitales</strong>.</p>
<h2><strong>🔹 El Problema: Procesamiento Seguro de Archivos</strong></h2>
<p class="ds-markdown-paragraph">Un cliente necesitaba un sistema donde:</p>
<ol start="1">
<li>
<p class="ds-markdown-paragraph"><strong>Al subir un archivo cifrado y comprimido a un bucket de Cloud Storage</strong>, se validara su autenticidad mediante una <strong>firma compartida</strong> entre emisor y receptor.</p>
</li>
<li>
<p class="ds-markdown-paragraph">Si el archivo era válido, se <strong>descomprimía</strong> y se verificaba la integridad de los archivos internos usando <strong>SHA-256</strong>.</p>
</li>
<li>
<p class="ds-markdown-paragraph">Solo los archivos que pasaran todas las validaciones serían procesados.</p>
</li>
</ol>
<h2><strong>⚡ La Solución: Automatización con Cloud Functions</strong></h2>
<h3><strong>1️⃣ Trigger por Eventos de Cloud Storage</strong></h3>
<p class="ds-markdown-paragraph">Configuré una <strong>Cloud Function</strong> activada por eventos de Cloud Storage (<code class="" data-line="">google.storage.object.finalize</code>), lo que permite ejecutar código cada vez que se sube un archivo.</p>
<h3><strong>Validación de Firma Compartida</strong></h3>
<p class="ds-markdown-paragraph">El archivo ZIP incluía un archivo <code class="" data-line="">.signature</code> con una firma generada mediante un <strong>secreto compartido</strong>. Usé <strong>HMAC-SHA256</strong> para asegurar que el archivo no fuera alterado.</p>
<div class="md-code-block md-code-block-light">
<div class="md-code-block-banner-wrap">
<div class="md-code-block-banner md-code-block-banner-lite">
<div class="_121d384">
<div class="d2a24f03">
<div class="efa13877">
<div class="ds-button ds-button--secondary ds-button--borderless ds-button--rect ds-button--s _7db3914" tabindex="0" role="button"></div>
</div>
</div>
</div>
</div>
</div>
<pre><code class="language-python" data-line="">import hmac
import hashlib
def validate_signature(secret_key, file_content, received_signature):
    generated_signature = hmac.new(secret_key.encode(), file_content, hashlib.sha256).hexdigest()
    return hmac.compare_digest(generated_signature, received_signature)</code></pre>
</div>
<h3><strong>3️⃣ Descompresión y Validación SHA-256</strong></h3>
<p class="ds-markdown-paragraph">Una vez validada la firma, el sistema descomprimía el archivo y verificaba cada archivo interno contra un hash predefinido.</p>
<div class="md-code-block md-code-block-light">
<pre><code class="language-python" data-line="">import zipfile
import hashlib
def check_file_hash(file_path, expected_hash):
    with open(file_path, &quot;rb&quot;) as f:
        file_data = f.read()
        computed_hash = hashlib.sha256(file_data).hexdigest()
        return computed_hash == expected_hash</code></pre>
</div>
<h3><strong>4️⃣ Notificación y Manejo de Errores</strong></h3>
<p class="ds-markdown-paragraph">Si alguna validación fallaba, el sistema enviaba una alerta por <strong>Pub/Sub</strong> o <strong>Correo Electrónico</strong> para notificar al administrador.</p>
<h2><strong>📊 Resultados</strong></h2>
<p class="ds-markdown-paragraph">✅ <strong>Procesamiento automatizado y seguro</strong> sin intervención manual o humana.<br />
✅ <strong>Reducción de errores</strong> por archivos corruptos o no autorizados.<br />
✅ <strong>Escalabilidad</strong> gracias a Cloud Functions (pago por uso).</p>
<h2><strong>🚀 ¿Necesitas una Solución Similar?</strong></h2>
<p class="ds-markdown-paragraph">Si buscas automatizar procesos en la nube con <strong>GCP, AWS o Azure</strong>, puedo ayudarte a diseñar e implementar una solución robusta y segura.</p>
<p class="ds-markdown-paragraph">📩 <a href="https://webmago.dev/#contact"><strong>¡Contáctame y hablemos de tu proyecto!</strong></a></p>The post <a href="https://webmago.dev/mi-experiencia-con-google-cloud-functions-validacion-y-procesamiento-seguro-de-archivos/">Mi Experiencia con Google Cloud Functions: Validación y Procesamiento Seguro de Archivos</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>¡Descongela tu Desarrollo con Winter CMS! ❄️ Tu Entorno Docker Listo para la Acción</title>
		<link>https://webmago.dev/descongela-tu-desarrollo-con-winter-cms-%e2%9d%84%ef%b8%8f-tu-entorno-docker-listo-para-la-accion/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Fri, 09 May 2025 15:21:43 +0000</pubDate>
				<category><![CDATA[development]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[wintercms]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=5901</guid>
					<description><![CDATA[<p>¿Cansado de lidiar con configuraciones complejas y entornos de desarrollo inconsistentes? ¡Dile adiós al frío de la incertidumbre y da la bienvenida a Winter CMS, mi imagen Docker preconfigurada lista para potenciar tus proyectos! Hace apenas dos semanas, compartí contigo una herramienta que he estado afinando para simplificar tu flujo de trabajo. Winter CMS encapsula [&#8230;]</p>
The post <a href="https://webmago.dev/descongela-tu-desarrollo-con-winter-cms-%e2%9d%84%ef%b8%8f-tu-entorno-docker-listo-para-la-accion/">¡Descongela tu Desarrollo con Winter CMS! ❄️ Tu Entorno Docker Listo para la Acción</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p data-sourcepos="5:1-5:231">¿Cansado de lidiar con configuraciones complejas y entornos de desarrollo inconsistentes? ¡Dile adiós al frío de la incertidumbre y da la bienvenida a <strong>Winter CMS</strong>, mi imagen Docker preconfigurada lista para potenciar tus proyectos!</p>
<p data-sourcepos="7:1-7:288">Hace apenas dos semanas, compartí contigo una herramienta que he estado afinando para simplificar tu flujo de trabajo. <strong>Winter CMS</strong> encapsula un entorno de desarrollo robusto y eficiente, ahorrándote horas de configuración y garantizando la consistencia en cada paso de tu proceso creativo.</p>
<p data-sourcepos="9:1-9:26"><strong>¿Qué te ofrece Winter CMS?</strong></p>
<ul data-sourcepos="11:3-15:0">
<li data-sourcepos="11:3-11:158"><strong>Un entorno consistente:</strong> Olvídate de los &#8220;funciona en mi máquina&#8221;. Winter CMS asegura que todos los miembros de tu equipo trabajen en un ambiente idéntico.</li>
<li data-sourcepos="12:3-12:127"><strong>Ahorro de tiempo invaluable:</strong> Dedica tu energía a lo que realmente importa: ¡codificar! Winter CMS viene listo para usarse.</li>
<li data-sourcepos="13:3-13:151"><strong>Flexibilidad total:</strong> Adapta Winter CMS a tus necesidades específicas. Su diseño modular te permite integrar las herramientas que realmente utilizas.</li>
<li data-sourcepos="14:3-15:0"><strong>La base de mis servicios:</strong> Winter CMS no es solo una imagen Docker, es la demostración de mi compromiso con la eficiencia y la calidad en el desarrollo. Utilizo esta misma base para ofrecerte soluciones robustas y escalables.</li>
</ul>
<p><strong>¿Qué Versiones de Winter CMS se han liberado?</strong></p>
<ul>
<li>1.2.7 php 8.2 fpm</li>
<li>1.2.7 php 8.2 apache</li>
<li>1.2.7 php 8.1 fpm</li>
<li>1.2.7 php 8.1 apache</li>
<li>1.2.7 php 8.0 fpm</li>
<li>1.2.7 php 8.0 apache</li>
</ul>
<p><strong>¿Listo para experimentar la calidez de un desarrollo sin complicaciones?</strong></p>
<p><a href="https://webmago.dev/#contact">¡Quiero saber cómo Winter CMS puede impulsar mi próximo proyecto!</a></p>
<p data-sourcepos="20:1-20:228">Al hacer clic en el botón de arriba, podrás contactarme directamente para discutir tus necesidades y descubrir cómo mis servicios, basados en la eficiencia de herramientas como Winter CMS, pueden llevar tus ideas al siguiente nivel.</p>
<p data-sourcepos="22:1-22:202">Ya sea que necesites ayuda para optimizar tu flujo de trabajo, construir aplicaciones robustas o implementar soluciones escalables, estoy aquí para ofrecerte mi experiencia y las herramientas adecuadas.</p>
<p data-sourcepos="24:1-24:164"><strong>¡No esperes más para descongelar tu potencial! Explora Winter CMS en Docker Hub:</strong> <a class="ng-star-inserted" href="https://hub.docker.com/r/webmago/winter" target="_blank" rel="noopener">https://hub.docker.com/r/webmago/winter</a></p>The post <a href="https://webmago.dev/descongela-tu-desarrollo-con-winter-cms-%e2%9d%84%ef%b8%8f-tu-entorno-docker-listo-para-la-accion/">¡Descongela tu Desarrollo con Winter CMS! ❄️ Tu Entorno Docker Listo para la Acción</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WinterCMS, Testing Docker Image</title>
		<link>https://webmago.dev/wintercms-testing-docker-image/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Tue, 04 May 2021 04:25:15 +0000</pubDate>
				<category><![CDATA[docker]]></category>
		<category><![CDATA[wintercms]]></category>
		<category><![CDATA[docker-compose]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=1206</guid>
					<description><![CDATA[<p>Some days ago, I created the WinterCMS Docker image for use with PHP 7.2 &#8211; 7.4 on Apache2 or FPM variants; those images/versions are publicly available, is my donation to the OpenSource and WinterCMS communities. Today I put my hands to write a basic docker-compose.yml to test the Docker Image using Docker Compose, SQLite as [&#8230;]</p>
The post <a href="https://webmago.dev/wintercms-testing-docker-image/">WinterCMS, Testing Docker Image</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p>Some days ago, I created the <a title="WinterCMS, descarga la imagen Docker." href="https://webmago.dev/wintercms-descarga-la-imagen-docker/" target="_blank" rel="noopener">WinterCMS Docker image</a> for use with PHP 7.2 &#8211; 7.4 on Apache2 or FPM variants; those images/versions are publicly available, is my donation to the OpenSource and <a title="WinterCMS, descarga la imagen Docker." href="https://wintercms.com" target="_blank" rel="noopener">WinterCMS</a> communities.</p>
<p>Today I put my hands to write a basic <code class="" data-line="">docker-compose.yml</code> to test the Docker Image using Docker Compose, SQLite as a database.</p>
<p>I decided to bind to my SSD local directories with <code class="" data-line="">storage, themes, plugins, and database</code> container directories to keep this data safe if the container crashes or is removed.</p>
<div id="attachment_1211" style="width: 770px" class="wp-caption aligncenter"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-1211" class="size-full wp-image-1211" src="https://webmago.dev/buvytsan/2021/05/WinterCMS-bind-dirs.png" alt="WinterCMS binding directories" width="760" height="352" srcset="https://webmago.dev/buvytsan/2021/05/WinterCMS-bind-dirs.png 760w, https://webmago.dev/buvytsan/2021/05/WinterCMS-bind-dirs-300x139.png 300w" sizes="(max-width: 760px) 100vw, 760px" /><p id="caption-attachment-1211" class="wp-caption-text">WinterCMS binding directories</p></div>
<p>I created an <code class="" data-line="">.env</code> file to inject environment variables and some values into the <code class="" data-line="">docker-compose.yml</code> services file.</p>
<pre><code class="language-bash" data-line="">###
#
# Winter CMS Test Image
# Version 1.0
# @author: WebMago
#
###
#### ---- * WinterCMS Configuration * ---- ####
# Name
CONTAINER_CMS_NAME=wintercms
# Image
CONTAINER_CMS_IMAGE=webmago/winter:stable-v1.1.3-php7.4-apache
# Env values
APP_DEBUG=false
APP_KEY=base64:PUT-YOUR-KEY-HERE
TZ=America/Mexico_City
APP_LOCALE=en
DB_PATH_SQLITE=storage/database.sqlite
DB_TYPE=sqlite
SESSION_DRIVER=file
CMS_ACTIVE_THEME=jacoweb-freelance
#### ---- * WinterCMS Domains * ---- ####
# A fake domain to test locally
WINTER_DOMAINS=winter.webmago.io</code></pre>
<p>&nbsp;</p>
<p>On the <code class="" data-line="">docker-compose.yml</code> the <code class="" data-line="">.env</code> values are injected as you can view on the code below and the directories are bound locally on my SSD.</p>
<pre><code class="language-yaml" data-line="">version: &#039;3&#039;
services:
  web-wintercms:
    image: ${CONTAINER_CMS_IMAGE}
    container_name: ${CONTAINER_CMS_NAME}
    restart: unless-stopped
    ports:
      - &quot;80:80&quot;
    environment:
        VIRTUAL_HOST: ${WINTER_DOMAINS}
        APP_DEBUG: ${APP_DEBUG}
        APP_KEY: ${APP_KEY}
        TZ: ${TZ}
        APP_LOCALE: ${APP_LOCALE}
        DB_PATH_SQLITE: ${DB_PATH_SQLITE}
        DB_TYPE: ${DB_TYPE}
        SESSION_DRIVER: ${SESSION_DRIVER}
        CMS_ACTIVE_THEME: ${CMS_ACTIVE_THEME}
    volumes:
     - ./config/test:/var/www/html/config/docker
     - ./wintercms/storage/database.sqlite:/var/www/html/storage/database.sqlite
     - ./wintercms/storage/logs:/var/www/html/storage/logs
     - ./wintercms/storage/app:/var/www/html/storage/app
     - ./wintercms/storage/cms:/var/www/html/storage/cms
     - ./wintercms/themes:/var/www/html/themes
     - ./wintercms/plugins:/var/www/html/plugins
</code></pre>
<p>&nbsp;</p>
<p>To launch WinterCMS execute:</p>
<pre><code class="language-bash" data-line="">docker-compose up -d</code></pre>
<p>This runs the process in the background, to stop the execution run:</p>
<pre><code class="language-bash" data-line="">docker-compose down</code></pre>
<p>&nbsp;</p>
<p>The first run creates the <code class="" data-line="">database.sqlite</code> and assign a random password to the <code class="" data-line="">admin</code> user, this is not visible if you run the <code class="" data-line="">docker-compose</code> command using the flag <code class="" data-line="">-d</code>.</p>
<p>This can be solved using three scenarios.</p>
<p>&nbsp;</p>
<p><strong>First Scenario</strong></p>
<p>Execute the docker-compose without the flag -d</p>
<p><code class="language-bash" data-line="">docker-compose up</code></p>
<p>&nbsp;</p>
<p><strong>Second Scenario</strong></p>
<p>If you have been executed the docker-compose with the flag -d and used the YAML of this example, the database is not deleted and the change will keep on the next execution.</p>
<pre><code class="language-bash" data-line=""># Access the container
docker-compose exec -it wintercms bash
# change the admin password
php artisan winter:passwd
# Enter the username to reset, on this case is admin
 Username to reset:
 &gt; admin
 Enter new password (leave blank for generated password) []:
 &gt; 
Password successfully changed.
# exit the container.
exit</code></pre>
<p>If you require to use <code class="" data-line="">redis</code> my advice is to use my images as a base to generate a new image with this PHP extension.</p>
<p>&nbsp;</p>
<p><strong>Third Scenario</strong></p>
<p>Add the environment variable <code class="" data-line="">INIT_WINTER</code> with the <code class="" data-line="">false</code> value into the <code class="" data-line="">environment</code> section of the YAML file, only if you have not executed the <code class="" data-line="">docker-compose</code> command as the first run.</p>
<pre><code class="language-bash" data-line=""># Access the container
docker-compose exec -it wintercms bash
# Winter up
php artisan winter:up
.
. # this show the DB migration process
.
.
. # finally the process displays the random password assigned, this is an example only
- The following password has been automatically generated for the &quot;admin&quot; account: xZ4DF20k8txIrcBRqEhkjw
 </code></pre>
<p><strong>Accessing the Backend</strong> After all the previous process, now you can access the Backend  CMS, on my case I define the host <code class="" data-line="">wintercms.webmago.io</code> as a fake URL added to my hosts, on my web browser typed: <code class="" data-line="">http://wintercms.webmago.io/backend/</code> the user is <code class="" data-line="">admin</code> and my password the defined or adjusted based on the previous three scenarios described. <code class="" data-line="">/etc/hosts file</code></p>
<pre><code class="language-bash" data-line="">127.0.0.1 wintercms.webmago.io</code></pre>
<p>&nbsp;</p>
<div id="attachment_1216" style="width: 1034px" class="wp-caption aligncenter"><img decoding="async" aria-describedby="caption-attachment-1216" class="size-large wp-image-1216" src="https://webmago.dev/buvytsan/2021/05/WinterCMS-sqlite-one-them-1024x378.png" alt="WinterCMS SQLite, Freelance Theme" width="1024" height="378" srcset="https://webmago.dev/buvytsan/2021/05/WinterCMS-sqlite-one-them-1024x378.png 1024w, https://webmago.dev/buvytsan/2021/05/WinterCMS-sqlite-one-them-300x111.png 300w, https://webmago.dev/buvytsan/2021/05/WinterCMS-sqlite-one-them-768x283.png 768w, https://webmago.dev/buvytsan/2021/05/WinterCMS-sqlite-one-them-1536x566.png 1536w, https://webmago.dev/buvytsan/2021/05/WinterCMS-sqlite-one-them-2048x755.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /><p id="caption-attachment-1216" class="wp-caption-text">WinterCMS SQLite, Freelance Theme</p></div>
<p><strong>Glitches</strong></p>
<p>The <code class="" data-line="">demo</code> theme currently is not available, this can origin errors on the Frontend, you need to install and activate one of the suggested on the <code class="" data-line="">Front-end theme</code> section, find or add your old theme with the required adjustments for WinterCMS.</p>
<p>&nbsp;</p>
<p>On the Plugins section, the oldest OctoberCMS Plugins are available to be installed, this can be an additional article for the WinterCMS series.</p>
<div id="attachment_1217" style="width: 1034px" class="wp-caption aligncenter"><img decoding="async" aria-describedby="caption-attachment-1217" class="size-large wp-image-1217" src="https://webmago.dev/buvytsan/2021/05/WinterCMS-Plugins-1024x562.png" alt="WinterCMS Plugins" width="1024" height="562" srcset="https://webmago.dev/buvytsan/2021/05/WinterCMS-Plugins-1024x562.png 1024w, https://webmago.dev/buvytsan/2021/05/WinterCMS-Plugins-300x165.png 300w, https://webmago.dev/buvytsan/2021/05/WinterCMS-Plugins-768x421.png 768w, https://webmago.dev/buvytsan/2021/05/WinterCMS-Plugins-1536x842.png 1536w, https://webmago.dev/buvytsan/2021/05/WinterCMS-Plugins-2048x1123.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /><p id="caption-attachment-1217" class="wp-caption-text">WinterCMS Plugins</p></div>
<p>&nbsp;</p>
<p>If you require my help, please let me know, <a href="https://webmago.dev/#contact" target="_blank" rel="noopener">contact me</a>.</p>The post <a href="https://webmago.dev/wintercms-testing-docker-image/">WinterCMS, Testing Docker Image</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WinterCMS, descarga la imagen Docker.</title>
		<link>https://webmago.dev/wintercms-descarga-la-imagen-docker/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 15:15:58 +0000</pubDate>
				<category><![CDATA[codefresh]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[wintercms]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=1166</guid>
					<description><![CDATA[<p>Si has leído nuestros artículos previos, te habrás enterado que OctoberCMS ha generado un nuevo esquema de pagos y esto origino una ruptura interna entre los colaboradores del proyecto quienes quienes lanzaron WinterCMS una derivación del actual OctoberCMS. &#160; Varios desarrolladores que hemos usado este CMS también han optado por mirar y  migrar sus proyectos [&#8230;]</p>
The post <a href="https://webmago.dev/wintercms-descarga-la-imagen-docker/">WinterCMS, descarga la imagen Docker.</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p>Si has leído nuestros artículos previos, te habrás enterado que OctoberCMS ha generado un <a title="Adios OctoberCMS, Hola WinterCMS" href="https://webmago.dev/adios-octobercms-hola-wintercms/" target="_blank" rel="noopener">nuevo esquema de pagos</a> y esto origino una ruptura interna entre los colaboradores del proyecto quienes quienes lanzaron <a title="WinterCMS finalmente disponible" href="https://webmago.dev/wintercms-finalmente-disponible/" target="_blank" rel="noopener">WinterCMS</a> una derivación del actual OctoberCMS.</p>
<p>&nbsp;</p>
<p>Varios desarrolladores que hemos usado este CMS también han optado por mirar y  migrar sus proyectos a este nuevo Administrador de Contenido, y por ello me he unido para proveer de las primeras imágenes <a href="https://hub.docker.com/r/webmago/winter" target="_blank" rel="noopener">Docker de WinterCMS</a> de forma gratuita.</p>
<p>&nbsp;</p>
<p>Para generar dichas imágenes me base en el código  proporcionado por <a href="https://github.com/aspendigital/docker-octobercms" target="_blank" rel="noopener">@aspendigital</a>, haciendo una derivación para generar el CI  con <a href="https://codefresh.io/" target="_blank" rel="noopener">Codefresh</a> un SaaS al que le he confiado varios de mis pipelines desde hace mas de 2 años.</p>
<p>&nbsp;</p>
<p>Al momento de escribir este artículo he generado 3 versiones de WinterCMS, <em>v1.1.0, v1.1.2</em> y <em>v1.1.3</em> con <em>PHP 7.2 a 7.4</em> con dos variantes, para <em>apache</em> y <em>fpm</em>; el por que no esta la version 1.1.1 se debe a que generó un error de sqlite al momento de su construcción, por lo que opté por no generar sus respectivas imágenes, así también  las imágenes con <strong>PHP 5.6</strong> fueron descartadas , esto debido a que WinterCMS recomienda usar la version <strong>PHP 7.2</strong> en adelante.</p>
<p>&nbsp;</p>
<h2>¿Cómo usar la imagen?</h2>
<h3>La forma rápida</h3>
<p><code class="" data-line="">$ docker run -p 80:80 --name winter webmago/winter:latest</code></p>
<p>Detener la imagen con CTRL-C</p>
<p><code class="" data-line="">$ docker rm winter # Destruye el contenedor</code></p>
<p>&nbsp;</p>
<blockquote>
<div>Si hay un conflicto con el puerto, recibirás un mensaje de error del daemon Docker. Intenta mapear a un puerto local <strong>(-p 8080:80)</strong> o apaga el contenedor o servidor que esté usando el puerto deseado.</div>
</blockquote>
<div>
<ul>
<li>Visita http://localhost usando tu navegador.</li>
<li>Ingresa al backend http://localhost/backend con el usuario <code class="" data-line="">admin</code> y  password <code class="" data-line="">admin</code>.</li>
<li>Presiona<code class="" data-line="">CTRL-C</code> para detener el contenedor. Ejecutar el contenedor en primer plano enviara los mensajes de log a la terminal.</li>
</ul>
</div>
<div></div>
<div></div>
<div>
<h3>Ejecutar el contenedor en segundo plano con la opcion <code class="" data-line="">-d</code>:</h3>
<div>
<pre><code class="language-bash" data-line="">$ docker run -p 80:80 --name winter -d webmago/winter:latest
$ docker stop winter  # Detener el contenedor. Para reiniciar docker start winter
$ docker rm winter  # Destruir el contenedor</code></pre>
</div>
</div>
<div></div>
<h2>Trabajar con archivos locales</h2>
<p>&nbsp;</p>
<div>
<div>Usando <em>volumes Docker,</em> es posible montar archivos localmente dentro de un contenedor.</div>
</div>
<div>
<div></div>
<div>El contenedor usa el directorio de trabajo <code class="" data-line="">/var/www/html</code> para el <code class="" data-line="">document root</code> del servidor web. Es aquí donde el codigo base de Winter CMS reside dentro del contenedor. Puedes reemplazar archivos y carpetas, o itnroducir nuevos con volumenes montados vinculados:</div>
<div>
<pre><code class="language-bash" data-line=""># Developing a plugin
$ git clone git@github.com:aspendigital/oc-resizer-plugin.git
$ cd oc-resizer-plugin
$ docker run -p 80:80 --rm \
-v $(pwd):/var/www/html/plugins/aspendigital/resizer \
webmago/winter:latest</code></pre>
</div>
</div>
<div></div>
<div>
<div>
<div>Ahórrate algunos pulsaciones de teclado, utiliza <a href="https://docs.docker.com/compose/overview/" target="_blank" rel="noopener"><code class="" data-line="">docker-compose</code></a> introduciendo un archivo <code class="" data-line="">docker-compose.yml</code> a tu proyecto:</div>
</div>
</div>
<div></div>
<div>
<pre><code class="language-yaml" data-line=""># docker-compose.yml
version: &#039;2.2&#039;
services:
  web:
    image: webmago/winter
    ports:
      - 80:80
    volumes:
      - $PWD:/var/www/html/plugins/aspendigital/resizer</code></pre>
</div>
<p>&nbsp;</p>
<div>
<div>Con el código arriba mencionado, guardalo en tu directorio de trabajo y ejecutalo:</div>
</div>
<div></div>
<div>
<pre><code class="language-bash" data-line="">$ docker-compose up -d # inicia los servicios definidos en `docker-compose.yml` en el fondo
$ docker-compose down # detiene y destruye</code></pre>
</div>
<p>&nbsp;</p>
<p>Estas son algunas formas principales de como usar esta imagen, si requieres una personalización o implementarla en algun cluster Kubernetes <a href="https://webmago.dev/#contact" target="_blank" rel="noopener">contactame</a>.</p>The post <a href="https://webmago.dev/wintercms-descarga-la-imagen-docker/">WinterCMS, descarga la imagen Docker.</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WinterCMS finalmente disponible</title>
		<link>https://webmago.dev/wintercms-finalmente-disponible/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Sun, 25 Apr 2021 16:49:41 +0000</pubDate>
				<category><![CDATA[octobercms]]></category>
		<category><![CDATA[wintercms]]></category>
		<category><![CDATA[lanzamiento]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=1118</guid>
					<description><![CDATA[<p>Hace unos días hablábamos de la nueva modalidad de pago que OctoberCMS estaba por aplicar a partir de la version 2.0 de su software lo que genero una ruptura entre los fundadores y crearon WinterCMS. &#160; Hace apenas unas horas el sitio web ha cambiado y muestra ya varias opciones para poder instalar y probar [&#8230;]</p>
The post <a href="https://webmago.dev/wintercms-finalmente-disponible/">WinterCMS finalmente disponible</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p>Hace unos días <a title="Adios OctoberCMS, Hola WinterCMS" href="https://webmago.dev/adios-octobercms-hola-wintercms/" target="_blank" rel="noopener">hablábamos</a> de la nueva modalidad de pago que OctoberCMS estaba por aplicar a partir de la version 2.0 de su software lo que genero una ruptura entre los fundadores y crearon WinterCMS.</p>
<p>&nbsp;</p>
<p>Hace apenas unas horas el sitio web ha cambiado y muestra ya varias opciones para poder instalar y probar esta derivación de CMS, así también <a title="October CMS as you know it is Dead" href="https://wintercms.com/blog/post/october-cms-you-know-it-dead" target="_blank" rel="noopener">publican</a> las razones por las cuales dieron origen a esta derivación de OctoberCMS hacia WinterCMS, tal y como mencioné previamente, fue debido al nuevo plan de negocios impuesta por parte del grupo que formaban al legendario CMS.</p>
<div id="attachment_1129" style="width: 1034px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1129" class="size-large wp-image-1129" src="https://webmago.dev/buvytsan/2021/04/Captura-de-Pantalla-2021-04-25-a-las-11.30.11-1024x532.png" alt="Lanzamiento Website WinterCMS" width="1024" height="532" srcset="https://webmago.dev/buvytsan/2021/04/Captura-de-Pantalla-2021-04-25-a-las-11.30.11-1024x532.png 1024w, https://webmago.dev/buvytsan/2021/04/Captura-de-Pantalla-2021-04-25-a-las-11.30.11-300x156.png 300w, https://webmago.dev/buvytsan/2021/04/Captura-de-Pantalla-2021-04-25-a-las-11.30.11-768x399.png 768w, https://webmago.dev/buvytsan/2021/04/Captura-de-Pantalla-2021-04-25-a-las-11.30.11-1536x798.png 1536w, https://webmago.dev/buvytsan/2021/04/Captura-de-Pantalla-2021-04-25-a-las-11.30.11-2048x1064.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><p id="caption-attachment-1129" class="wp-caption-text">Lanzamiento Website WinterCMS</p></div>
<p>&nbsp;</p>
<p>Cabe mencionar que el Marketplace aun esta pendiente y tendremos que esperar un poco mas de tiempo para poder acceder al ecosistema de plugins que tenia OctoberCMS o hacer un pequeño ajuste a tu configuración del archivo <strong>config/cms.php</strong></p>
<p><code class="" data-line=""><br />
&#039;updateServer&#039; =&gt; &#039;https://api.wintercms.com/marketplace&#039;,<br />
</code></p>
<p>&nbsp;</p>
<p>Mientras tanto esteré ajustando mis sistemas y códigos para probar y proveerles apoyo en este nuevo CMS, no me resta mas que decir que WinterCMS llegue a tener éxito y no repitamos esta historia en el futuro cercano o lejano.</p>
<p>&nbsp;</p>The post <a href="https://webmago.dev/wintercms-finalmente-disponible/">WinterCMS finalmente disponible</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Adios OctoberCMS, Hola WinterCMS</title>
		<link>https://webmago.dev/adios-octobercms-hola-wintercms/</link>
		
		<dc:creator><![CDATA[webmago]]></dc:creator>
		<pubDate>Thu, 15 Apr 2021 17:24:05 +0000</pubDate>
				<category><![CDATA[octobercms]]></category>
		<category><![CDATA[wintercms]]></category>
		<category><![CDATA[negocios]]></category>
		<guid isPermaLink="false">https://webmago.dev/?p=914</guid>
					<description><![CDATA[<p>Hace 3 días, Abril 12 para ser exactos, OctoberCMS anuncio su nuevo modelo de negocios, los que formamos su comunidad nos ha sorprendido. En adelante para acceder a las actualizaciones tendrás que pagar $9.00 USD al año por cada proyecto, o $ 150.00 USD al año por proyectos ilimitados; esta cantidad no incluye los costos [&#8230;]</p>
The post <a href="https://webmago.dev/adios-octobercms-hola-wintercms/">Adios OctoberCMS, Hola WinterCMS</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></description>
										<content:encoded><![CDATA[<p>Hace 3 días, Abril 12 para ser exactos, OctoberCMS anuncio su nuevo <a title="October CMS Moves to Become a Paid Platform" href="https://octobercms.com/blog/post/october-cms-moves-become-paid-platform">modelo de negocios</a>, los que formamos su comunidad nos ha sorprendido. En adelante para acceder a las actualizaciones tendrás que pagar $9.00 USD al año por cada proyecto, o $ 150.00 USD al año por proyectos ilimitados; esta cantidad no incluye los costos de adquisición de plantillas o plugins del Marketplace, por lo que seguirás pagando por ellos.</p>
<p>&nbsp;</p>
<p>Por si fuera poco, si necesitas soporte, el costo es de $97.00 USD por ticket y solo incluye 1.5 hr., entre los que hemos usado <a title="Proyectos en 5 dias" href="https://webmago.dev/proyectos-en-5-dias/" target="_blank" rel="noopener">OctoberCMS</a> para los proyectos ya  existe una preocupación al respecto, y mientras no actualicemos no entraremos en esta modalidad, esto será a partir de que OctoberCMS defina la fecha de aplicación de esta nuevo modelo de negocios.</p>
<p>&nbsp;</p>
<p>Ante esta situación, parte del equipo de OctoberCMS ha abandonado el proyecto y han lanzado una derivación llamada <a title="WinterCMS" href="https://www.wintercms.com/" target="_blank" rel="noopener">WinterCMS</a>, al momento de escribir este artículo, el sitio solo muestra el logo, un campo para suscribirse a las notificaciones y un acceso a Discord; sin embargo, en su <a title="WinterCMS Repoositorio" href="https://github.com/wintercms" target="_blank" rel="noopener">repositorio</a> de  Github ya se ve algo de movimiento.</p>
<p>&nbsp;</p>
<p>Habrá quienes se queden en OctoberCMS y paguen $9 o $150 USD al año, y habrá otros quienes opten por user WinterCMS, solo esperemos que esta decisión no sea contra-producente para el equipo de OctoberCMS.</p>The post <a href="https://webmago.dev/adios-octobercms-hola-wintercms/">Adios OctoberCMS, Hola WinterCMS</a> first appeared on <a href="https://webmago.dev">Webmago Dev</a>.]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
