<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Jesús Magallón]]></title><description><![CDATA[Cuento con experiencia en diseño y desarrollo de aplicaciones web, así como también experiencia desplegando en servidores basados en la nube como AWS y Digital ]]></description><link>https://yosoydev.net</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 20:22:07 GMT</lastBuildDate><atom:link href="https://yosoydev.net/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Desplegando una aplicación de Astro con Vue.js y Tailwind en AWS App Runner]]></title><description><![CDATA[Recientemente trabajé en un proyecto en el que tuve que desplegar un sitio web hecho con Astro, Tailwind y Vue.js. Este proyecto era para uso interno y se podría decir que era un prototipo más que algo que saldría a producción, por lo que no vi caso ...]]></description><link>https://yosoydev.net/desplegando-una-aplicacion-de-astro-con-vuejs-y-tailwind-en-aws-app-runner</link><guid isPermaLink="true">https://yosoydev.net/desplegando-una-aplicacion-de-astro-con-vuejs-y-tailwind-en-aws-app-runner</guid><category><![CDATA[Astro]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[AWS App Runner]]></category><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Jesús Magallón]]></dc:creator><pubDate>Mon, 24 Feb 2025 17:12:16 GMT</pubDate><content:encoded><![CDATA[<p>Recientemente trabajé en un proyecto en el que tuve que desplegar un sitio web hecho con <a target="_blank" href="https://astro.build/">Astro</a>, <a target="_blank" href="https://tailwindcss.com/">Tailwind</a> y <a target="_blank" href="https://vuejs.org/">Vue.js</a>. Este proyecto era para uso interno y se podría decir que era un prototipo más que algo que saldría a producción, por lo que no vi caso en montar algo complejo con <a target="_blank" href="https://docs.astro.build/en/guides/deploy/aws/">Amplify</a>, <a target="_blank" href="https://www.launchfa.st/blog/deploy-astro-aws-fargate">ECS</a>, <a target="_blank" href="https://www.astro-aws.org/guides/01-getting-started/">Lambdas</a> o <a target="_blank" href="https://www.npmjs.com/package/@common-web/astro-lambda-edge">Lambda@Edge</a>, como se puede encontrar en otras guías de internet.</p>
<p>Por si no conoces <a target="_blank" href="https://aws.amazon.com/es/apprunner/">AWS App Runner</a>, es un servicio completamente administrado que simplifica el despliegue y la ejecución de aplicaciones basadas en contenedores. Con App Runner, puedes tomar tu código o imagen de contenedor, construir, desplegar y escalar tu aplicación sin tener que preocuparte por la infraestructura subyacente.</p>
<p>Entre sus ventajas destacan:</p>
<ul>
<li><p><strong>Facilidad para aplicaciones containerizadas:</strong> App Runner está diseñado para desplegar aplicaciones server-side y basadas en contenedores de forma directa, sin requerir configuraciones complejas.</p>
</li>
<li><p><strong>Despliegue y escalado automático:</strong> Permite configurar despliegues automáticos y escalar la aplicación en función de la carga de tráfico, lo cual resulta ideal para proyectos que puedan experimentar picos de usuarios.</p>
</li>
<li><p><strong>Facilidad en la configuración:</strong> Si bien se puede utilizar para aplicaciones productivas con gran volumen de tráfico, si solo quieres prototipar o mostrar avances de tu aplicación, App Runner te permite tener tu aplicación corriendo en minutos, con CI/CD y toda la cosa.</p>
</li>
</ul>
<p>Bueno, vamos directo al grano. Estos son los pasos que necesitarás seguir para desplegar tu aplicación con AWS App Runner.</p>
<h2 id="heading-inicializacion-del-proyecto">Inicialización del Proyecto</h2>
<p>El primer paso es inicializar tu proyecto de Astro. Puedes configurarlo según las necesidades de tu aplicación. En mi caso, lo inicialicé con Tailwind y Vue.js mediante el siguiente comando:</p>
<pre><code class="lang-bash">npm create astro@latest -- --add vue --add tailwind
</code></pre>
<p>Una vez que el proyecto esté inicializado, al ejecutar <code>npm run dev</code> deberías poder ver la página de bienvenida de Astro.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740412067547/3599941c-8f63-4c22-92bf-0ec7b475fc63.png" alt class="image--center mx-auto" /></p>
<p>A partir de este punto, omito la parte en la que modificas o agregas los componentes necesarios, ya que esta guía se centra en el despliegue del proyecto en App Runner.</p>
<h2 id="heading-instalacion-y-configuracion-del-adaptador">Instalación y Configuración del Adaptador</h2>
<p>Hasta el momento de escribir esta guía, no hay un adaptador que se pueda utilizar para desplegar en App Runner como sí lo hay para AWS Amplify, ECS, Lambdas o Lambda@Edge. La mayoría de estos adaptadores funcionan con el SDK de AWS y, si bien funcionan de maravilla, por lo general son algo lentos.</p>
<p>En este caso, utilizaremos el adaptador nativo <a target="_blank" href="https://docs.astro.build/en/guides/integrations-guide/node/">@astrojs/node</a> en modo standalone y, para el despliegue, utilizaremos el proceso CI/CD que nos proporciona App Runner para detectar los cambios de nuestra rama <code>main</code> y realizar los despliegues.</p>
<p>Si aún no has instalado el adaptador @astrojs/node, ejecútalo en la raíz del proyecto:</p>
<pre><code class="lang-bash">npx astro add node
</code></pre>
<p>Este comando instalará las dependencias necesarias y modificará el archivo <code>astro.config.mjs</code>. Al finalizar, deberías ver algo similar a lo siguiente:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// @ts-check</span>
<span class="hljs-keyword">import</span> { defineConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">'astro/config'</span>;
<span class="hljs-keyword">import</span> tailwindcss <span class="hljs-keyword">from</span> <span class="hljs-string">'@tailwindcss/vite'</span>;
<span class="hljs-keyword">import</span> node <span class="hljs-keyword">from</span> <span class="hljs-string">"@astrojs/node"</span>; <span class="hljs-comment">// &lt;-- new</span>
<span class="hljs-keyword">import</span> vue <span class="hljs-keyword">from</span> <span class="hljs-string">'@astrojs/vue'</span>;

<span class="hljs-comment">// https://astro.build/config</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> defineConfig({
    <span class="hljs-attr">vite</span>: {
        <span class="hljs-attr">plugins</span>: [tailwindcss()]
    },
    <span class="hljs-attr">adapter</span>: node(), <span class="hljs-comment">// &lt;-- new</span>
    <span class="hljs-attr">integrations</span>: [
        vue()
    ]
});
</code></pre>
<p>Si no aparecen estas líneas, agrégalas manualmente. Luego, para especificar el modo del adaptador, modifica la configuración de la siguiente manera:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> defineConfig({
    <span class="hljs-attr">vite</span>: {
        <span class="hljs-attr">plugins</span>: [tailwindcss()]
    },
    <span class="hljs-attr">adapter</span>: node({
        <span class="hljs-attr">mode</span>: <span class="hljs-string">'standalone'</span>, <span class="hljs-comment">// &lt;-- new</span>
    }),
    <span class="hljs-attr">integrations</span>: [
        vue()
    ]
});
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Para producción con alto tráfico, quizá te convenga utilizar el adaptador en modo middleware combinado con un servidor más robusto (por ejemplo, Nginx). Quizás en otra ocasión exploremos esa alternativa para aplicaciones más robustas.</div>
</div>

<h2 id="heading-configuracion-de-variables-de-entorno-opcional">Configuración de Variables de Entorno (Opcional)</h2>
<p>Si tu aplicación utiliza variables de entorno, puedes definir un esquema en la configuración de Astro. Para ello, agrega el parámetro <code>env</code> a la función <code>defineConfig</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { defineConfig, envField } <span class="hljs-keyword">from</span> <span class="hljs-string">'astro/config'</span>; <span class="hljs-comment">// &lt;-- new</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> defineConfig({
    <span class="hljs-comment">// ... otras configuraciones</span>
    <span class="hljs-attr">env</span>: { <span class="hljs-comment">// &lt;-- new</span>
        <span class="hljs-attr">schema</span>: {
            <span class="hljs-attr">API_HOST</span>: envField.string({ <span class="hljs-attr">context</span>: <span class="hljs-string">"server"</span>, <span class="hljs-attr">access</span>: <span class="hljs-string">"public"</span>, <span class="hljs-attr">optional</span>: <span class="hljs-literal">false</span> }),
            <span class="hljs-attr">API_KEY_VALUE</span>: envField.string({ <span class="hljs-attr">context</span>: <span class="hljs-string">"server"</span>, <span class="hljs-attr">access</span>: <span class="hljs-string">"secret"</span>, <span class="hljs-attr">optional</span>: <span class="hljs-literal">false</span> }),
            <span class="hljs-comment">// ... otras variables</span>
        }
    }
});
</code></pre>
<p>Consulta la <a target="_blank" href="https://docs.astro.build/en/guides/environment-variables/#type-safe-environment-variables">documentación oficial</a> para más detalles.</p>
<h2 id="heading-creacion-del-archivo-de-configuracion-apprunneryaml">Creación del Archivo de Configuración <code>apprunner.yaml</code></h2>
<p>Este archivo nos permitirá configurar App Runner, indicándole qué debe hacer en cada una de las etapas de despliegue.</p>
<p>App Runner cuenta con dos etapas de despliegue: <code>build</code> y <code>run</code>. En la etapa <code>build</code>, normalmente nos va a interesar construir nuestra aplicación; en el caso de Astro, instalar las dependencias y ejecutar el comando <code>npm run build</code>. Opcionalmente, también puedes ejecutar tus pruebas en caso de tenerlas o cualquier otro proceso que quieras realizar antes de que tu aplicación esté disponible para tus usuarios.</p>
<p>En la etapa <code>run</code>, normalmente nos va a interesar correr nuestra aplicación; en el caso de Astro, levantar el servidor integrado para que nuestra aplicación esté disponible.</p>
<p>Este es mi archivo de configuración básico para correr Astro en App Runner:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-number">1.0</span>
<span class="hljs-attr">runtime:</span> <span class="hljs-string">nodejs18</span>
<span class="hljs-attr">build:</span>
  <span class="hljs-attr">commands:</span>
    <span class="hljs-attr">pre-build:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span>
    <span class="hljs-attr">build:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">build</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">NODE_ENV</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"development"</span>
<span class="hljs-attr">run:</span>
  <span class="hljs-attr">runtime-version:</span> <span class="hljs-number">18.20</span><span class="hljs-number">.5</span>
  <span class="hljs-attr">pre-run:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span> <span class="hljs-string">--omit=dev</span>
  <span class="hljs-attr">command:</span> <span class="hljs-string">node</span> <span class="hljs-string">dist/server/entry.mjs</span>
  <span class="hljs-attr">network:</span>
    <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
    <span class="hljs-attr">env:</span> <span class="hljs-string">PORT</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">NODE_ENV</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"production"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">HOST</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"0.0.0.0"</span>
</code></pre>
<h3 id="heading-expicacion-de-la-configuracion">Expicación de la configuración</h3>
<ul>
<li><p><strong>version:</strong> Versión del archivo de configuración.</p>
</li>
<li><p><strong>runtime:</strong> Entorno de ejecución; en este caso usamos Node.js 18 debido a que hasta ahora App Runner soporta hasta esa versión.</p>
</li>
<li><p><strong>build:</strong> Define la etapa de construcción, donde normalmente se instalan las dependencias y se construye el proyecto.</p>
</li>
<li><p><strong>run:</strong> Especifica la etapa de ejecución, indicando el comando para levantar el servidor, el puerto y las variables necesarias. En el caso de Astro, debemos agregar la variable <code>HOST</code> con el valor "0.0.0.0" para que el Health Check de App Runner funcione.</p>
</li>
</ul>
<p>Consulta la <a target="_blank" href="https://docs.aws.amazon.com/apprunner/latest/dg/config-file-ref.html">documentación oficial</a> para más detalles.</p>
<h3 id="heading-variables-de-entorno">Variables de entorno</h3>
<p>Si tu aplicación utiliza variables de entorno, debes incluirlas tanto en la sección <code>build</code> como en <code>run</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">build:</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">NODE_ENV</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"development"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">API_HOST</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"https://api.myawsomewebsite.com"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">API_KEY_NAME</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"API-Key"</span>
<span class="hljs-attr">run:</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">NODE_ENV</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"production"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">HOST</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"0.0.0.0"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">API_HOST</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"https://api.myawsomewebsite.com"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">API_KEY_NAME</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"API-Key"</span>
</code></pre>
<p>El archivo apprunner.yaml debe subirse al repositorio Git. Si manejas variables sensibles, utiliza <a target="_blank" href="https://aws.amazon.com/es/secrets-manager/">AWS Secrets Manager</a> o <a target="_blank" href="https://docs.aws.amazon.com/es_es/systems-manager/latest/userguide/systems-manager-parameter-store.html">AWS Systems Manager Parameter Store</a>. Por ejemplo:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">run:</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">MY_VAR_EXAMPLE</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">"example"</span>
  <span class="hljs-attr">secrets:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">my-secret</span>
      <span class="hljs-attr">value-from:</span> <span class="hljs-string">"arn:aws:secretsmanager:us-east-1:123456789012:secret:testingstackAppRunnerConstr-kJFXde2ULKbT-S7t8xR:username::"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">my-parameter</span>
      <span class="hljs-attr">value-from:</span> <span class="hljs-string">"arn:aws:ssm:us-east-1:123456789012:parameter/parameter-name"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">my-parameter-only-name</span>
      <span class="hljs-attr">value-from:</span> <span class="hljs-string">"parameter-name"</span>
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">No uses directamente el ARN generado por AWS ya que puede incluir caracteres extra que harán que App Runner no encuentre el secreto. Recuerda que los secretos <strong>no</strong> se pueden utilizar en la etapa de construcción, solo en la de ejecución.</div>
</div>

<p>Por alguna razón, Astro no detecta correctamente las variables de entorno inyectadas por App Runner. La solución más sencilla que encontré es crear un script que extraiga las variables del sistema y las escriba en un archivo <code>.env</code>. Este es el script que utilizo:</p>
<pre><code class="lang-javascript">#!<span class="hljs-regexp">/usr/</span>bin/env bash

# Declarar un array asociativo con las variables y sus valores por defecto
declare -A default_variables=(
    [API_HOST]=<span class="hljs-string">"https://api.myawsomewebsite.com"</span>
    [API_KEY_VALUE]=<span class="hljs-string">"something"</span>
    # ... otras variables
)

# Obtener el directorio donde se encuentra el script
script_dir=<span class="hljs-string">"$(dirname "</span>$(realpath <span class="hljs-string">"$0"</span>)<span class="hljs-string">")"</span>
env_file=<span class="hljs-string">"$script_dir/.env"</span>

# Crear o vaciar el archivo .env
&gt; <span class="hljs-string">"$env_file"</span>

# Recorrer el array y escribir cada variable en el archivo .env
<span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> <span class="hljs-string">"${!default_variables[@]}"</span>; <span class="hljs-keyword">do</span>
    # Si la variable de entorno existe, se utiliza; de lo contrario, se toma el valor por defecto
    value=<span class="hljs-string">"${!key}"</span>
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"$value"</span> ]; then
        value=<span class="hljs-string">"${default_variables[$key]}"</span>
    fi

    # Si el valor contiene espacios y no está entre comillas, se envuelve en comillas dobles
    <span class="hljs-keyword">if</span> [[ <span class="hljs-string">"$value"</span> =~ \  &amp;&amp; ! <span class="hljs-string">"$value"</span> =~ ^\<span class="hljs-string">".*\"$ ]]; then
        value="</span>\<span class="hljs-string">"$value\""</span>
    fi

    echo <span class="hljs-string">"$key=$value"</span> &gt;&gt; <span class="hljs-string">"$env_file"</span>
done

echo <span class="hljs-string">"Archivo .env generado en $env_file"</span>
cat $env_file
</code></pre>
<p>Guarda este archivo en la raíz del proyecto como <code>generate_env.sh</code> y asígnale permisos de ejecución:</p>
<pre><code class="lang-bash">chmod +x generate_env.sh
</code></pre>
<p>Luego, asegúrate de llamar a este script en las etapas de <code>build</code> y <code>run</code> de tu archivo <code>apprunner.yaml</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">build:</span>
  <span class="hljs-attr">commands:</span>
    <span class="hljs-attr">pre-build:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">./generate_env.sh</span>  <span class="hljs-comment"># &lt;-- nuevo: genera el archivo .env</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-string">...</span>
<span class="hljs-attr">run:</span>
  <span class="hljs-string">...</span>
  <span class="hljs-attr">pre-run:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./generate_env.sh</span>  <span class="hljs-comment"># &lt;-- nuevo: genera el archivo .env</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span> <span class="hljs-string">--omit=dev</span>
  <span class="hljs-attr">command:</span> <span class="hljs-string">node</span> <span class="hljs-string">dist/server/entry.mjs</span>
  <span class="hljs-attr">network:</span>
    <span class="hljs-string">...</span>
  <span class="hljs-attr">env:</span>
    <span class="hljs-string">...</span>
</code></pre>
<h2 id="heading-configuracion-en-aws-app-runner">Configuración en AWS App Runner</h2>
<p>Con el proyecto configurado y el archivo <code>apprunner.yaml</code> listo, solo queda subir tu proyecto a GitHub o Bitbucket y configurar App Runner en la consola de AWS.</p>
<p>Estos son los pasos que necesitas seguir:</p>
<ol>
<li><p>Ingresa a App Runner y haz clic en “Crear servicio”.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416711257/86325cee-5b15-4080-9a80-7d64b30fcff7.png" alt class="image--center mx-auto" /></p>
<p> Selecciona “Repositorio de código fuente” y elige el proveedor (GitHub o Bitbucket).</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416732927/f035ea48-52e9-4d06-ae14-35e3464d0b53.png" alt class="image--center mx-auto" /></p>
<p> Selecciona la conexión, el repositorio y la rama. En caso de trabajar en un monorepo o que tu código fuente no se encuentre en la raíz del repositorio, especifica el directorio donde se encuentra tu proyecto de Astro (por ejemplo, “/” para la raíz).</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416785205/d84f3735-7b5c-47a0-873e-1de925c35184.png" alt class="image--center mx-auto" /></p>
<p> Configura el despliegue automático para que, cada vez que se haga push a la rama <strong>main</strong> (o la que hayas elegido), se inicie un nuevo despliegue.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416804260/e44ff241-5b9e-4bf4-943e-68cdd11be71e.png" alt class="image--center mx-auto" /></p>
<p> En la sección de compilación, selecciona “Usar un archivo de configuración” para que App Runner utilice el archivo <code>apprunner.yaml</code> que acabamos de crear.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416816213/ae1a14c2-87d9-4f61-b9a0-1cc6b7229b4b.png" alt class="image--center mx-auto" /></p>
<p> Define la cantidad de vCPU y memoria asignada. Para proyectos ligeros como prototipos o landings estaticas, 0.25 vCPU y 0.5GB pueden ser suficientes; puedes ajustar esta configuración según el uso que tu aplicación va a tener.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416826335/86fc90f8-20e1-49f8-b2c1-92c003b4415f.png" alt class="image--center mx-auto" /></p>
<p> App Runner viene con una configuración para el Auto Scaling por default, básicamente permite 100 peticiones en simultaneo por instancia y conforme este uso aumenta va incrementando de 1 instancia (el minímo) hasta 25 instancias (el máximo). Haciendo un calculo básico tenemos que esta configuración es capaz de responder a 2,500 peticiones al mismo tiempo. Puedes crear o modificar esta configuración para adaptarla a las necesidades de tu aplicación.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416843920/4adb528f-cdee-47d9-9c7d-37f60cafe6f2.png" alt class="image--center mx-auto" /></p>
<p> App Runner hace una comprobación health check TCP con un timeout de 5 segundos. Si prefieres, puedes cambiar a HTTP y especificar una ruta (por ejemplo, <code>/health</code>).</p>
</li>
<li><p>Ahora toca seleccionar un rol de instancia previamente creado que tenga permisos para acceder a los secretos (obligatorio si usas Secrets Manager o SSM).</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740416991378/366096bc-c3fa-4d53-bcb7-f74ab2668c98.png" alt class="image--center mx-auto" /></p>
<p> Asegúrate de que el rol tenga la siguiente relación de confianza:</p>
<pre><code class="lang-json"> {
   <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
   <span class="hljs-attr">"Statement"</span>: [
     {
       <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
       <span class="hljs-attr">"Principal"</span>: {
         <span class="hljs-attr">"Service"</span>: <span class="hljs-string">"tasks.apprunner.amazonaws.com"</span>
       },
       <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"sts:AssumeRole"</span>
     }
   ]
 }
</code></pre>
</li>
<li><p>Si deseas que tu aplicación sea pública, puedes dejar la configuración de red por defecto. En caso de que quieras que tu aplicación sea privada, deberás configurar un punto de conexión privado y personalizar la VPC. En esta guía no abarcaremos este tema.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740417007896/3d48e4d0-6ebf-41d5-83c6-569af5a99e63.png" alt class="image--center mx-auto" /></p>
<p>Opcionalmente, habilita AWS WAF (ten en cuenta que puede generar costos adicionales) o configura AWS X-Ray para monitoreo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740417036399/74ef3275-a689-4ab7-b2d9-dd0d32b5cd83.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Revisa la configuración y haz clic en “Crear e implementar”. Si todo está correcto, verás cómo se despliega tu aplicación.</p>
</li>
</ol>
<p>¡Y eso es todo! Hasta el momento, esta ha sido la forma más sencilla que he encontrado de desplegar aplicaciones con una experiencia similar a la que ofrece Vercel o Netlify. Si tienes alguna duda o presentas algún error siguiendo esta guía, no dudes en ponerte en contacto conmigo a través de Twitter en <a target="_blank" href="https://twitter.com/yosoydev">@yosoydev</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Como configurar el inicio de sesión de Laravel 5.8 con nombre de usuario]]></title><description><![CDATA[Laravel incluye un sistema de logueo o inicio de sesión y registro de usuarios bastante avanzado dándonos la posibilidad incluso de activar la verificación de usuarios por correo electrónico y un sistema de recuperación de contraseñas sin práctica me...]]></description><link>https://yosoydev.net/como-configurar-el-inicio-de-sesion-de-laravel-58-con-nombre-de-usuario</link><guid isPermaLink="true">https://yosoydev.net/como-configurar-el-inicio-de-sesion-de-laravel-58-con-nombre-de-usuario</guid><category><![CDATA[Laravel 5]]></category><category><![CDATA[login]]></category><dc:creator><![CDATA[Jesús Magallón]]></dc:creator><pubDate>Mon, 17 Jan 2022 17:59:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1642442178967/P8SNuY21o.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Laravel incluye un sistema de logueo o inicio de sesión y registro de usuarios bastante avanzado dándonos la posibilidad incluso de activar la verificación de usuarios por correo electrónico y un sistema de recuperación de contraseñas sin práctica mente hacer nada.</p>
<p>Por default este sistema funciona con las columnas email y password que incluso Laravel nos coloca en la migración CreateUsersTable que ya viene al crear nuestro proyecto. Sin embargo, hay ocasiones en las que por x o y necesitamos personalizar un poquito estas columnas, ya sea porque estamos trabajando con una base de datos existente o porque por alguna extraña razón así nos lo requiera el proyecto.</p>
<p>En cualquier caso hoy veremos como podemos personalizar el inicio de sesión de laravel para acceder por medio de un campo personalizado (en este caso el nombre de usuario).</p>
<h2 id="heading-primer-paso">Primer paso</h2>
<p>Lo primero es tener un proyecto nuevo (o bien uno existente) de Laravel y haber generado el Authentication scaffolding de Laravel a través del comando <code>php artisan make:auth</code>. Ya que tenemos esto como paso opcional podemos modificar la migración CreateUsersTable para generar la columna username que será la que utilizaremos para iniciar sesión. Si ya tienes esto resuelto te puedes saltar este paso o si por alguna extraña razón no estás usando las migraciones de Laravel (extraño) entonces deberás realizar las modificaciones necesarias a tu base de datos.</p>
<p>Más o menos estamos buscando algo como esto:</p>
<pre><code class="lang-php">Schema::create(<span class="hljs-string">'users'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
    $table-&gt;bigIncrements(<span class="hljs-string">'id'</span>);
    $table-&gt;string(<span class="hljs-string">'name'</span>);
    $table-&gt;string(<span class="hljs-string">'username'</span>)-&gt;unique();
    $table-&gt;string(<span class="hljs-string">'email'</span>)-&gt;unique();
    $table-&gt;timestamp(<span class="hljs-string">'email_verified_at'</span>)-&gt;nullable();
    $table-&gt;string(<span class="hljs-string">'password'</span>);
    $table-&gt;rememberToken();
    $table-&gt;timestamps();
});
</code></pre>
<p>Como podemos ver hemos creado la columna username la cual hemos marcado como única para evitar que haya registros con el mismo nombre de usuario. Lo mismo hemos hecho con la columna email.</p>
<h2 id="heading-segundo-paso">Segundo paso</h2>
<p>Ahora hay que ubicar el archivo <code>app/Http/Controllers/Auth/LoginController.php</code> y crear la siguiente función debajo de todo:</p>
<pre><code class="lang-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">username</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">return</span> <span class="hljs-string">'username'</span>;
}
</code></pre>
<p>En caso de que también estés usando el sistema de registro de usuarios que Laravel proporciona también habría que modificar la función validator del controlador RegisterController de tal manera que quede así:</p>
<pre><code class="lang-php"><span class="hljs-comment">/**
 * Get a validator for an incoming registration request.
 *
 * <span class="hljs-doctag">@param</span>  array  $data
 * <span class="hljs-doctag">@return</span> \Illuminate\Contracts\Validation\Validator
 */</span>
<span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validator</span>(<span class="hljs-params"><span class="hljs-keyword">array</span> $data</span>)
</span>{
    <span class="hljs-keyword">return</span> Validator::make($data, [
        <span class="hljs-string">'name'</span> =&gt; [<span class="hljs-string">'required'</span>, <span class="hljs-string">'string'</span>, <span class="hljs-string">'max:255'</span>],
        <span class="hljs-string">'username'</span> =&gt; [<span class="hljs-string">'required'</span>, <span class="hljs-string">'string'</span>, <span class="hljs-string">'max:255'</span>, <span class="hljs-string">'unique:users'</span>],
        <span class="hljs-string">'email'</span> =&gt; [<span class="hljs-string">'required'</span>, <span class="hljs-string">'string'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'max:255'</span>, <span class="hljs-string">'unique:users'</span>],
        <span class="hljs-string">'password'</span> =&gt; [<span class="hljs-string">'required'</span>, <span class="hljs-string">'string'</span>, <span class="hljs-string">'min:8'</span>, <span class="hljs-string">'confirmed'</span>],
    ]);
}
</code></pre>
<p>En este caso dejamos el límite del nombre de usuario a 255 caracteres, pero si se requiere puede reducirse. Generalmente, las redes sociales lo manejan a un máximo de 16 caracteres.</p>
<p>También no se olviden de agregarlo a los atributos “fillable” del Modelo Users, ya que de otra forma les dará error al registrar un nuevo usuario.</p>
<pre><code class="lang-php"><span class="hljs-comment">/**
 * The attributes that are mass assignable.
 *
 * <span class="hljs-doctag">@var</span> array
 */</span>
<span class="hljs-keyword">protected</span> $fillable = [
    <span class="hljs-string">'name'</span>, <span class="hljs-string">'username'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'password'</span>,
];
</code></pre>
<h2 id="heading-tercer-paso">Tercer paso</h2>
<p>Ya por último solo quedaría modificar las vistas de login para poder iniciar sesión por medio del nombre de usuario en lugar del correo electrónico. Para eso tenemos que ubicar el archivo <code>resources/views/auth/login.blade.php</code> y cambiar el input email a text así como su respectiva propiedad name.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group row"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4 col-form-label text-md-right"</span>&gt;</span>{{ __('Username') }}<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-6"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control @error('username') is-invalid @enderror"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"{{ old('username') }}"</span> <span class="hljs-attr">required</span> <span class="hljs-attr">autocomplete</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">autofocus</span>&gt;</span>

        @error('username')
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"invalid-feedback"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{{ $message }}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        @enderror
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Una vez realizados estos pasos pueden probar a iniciar sesión con su nombre de usuario y verán que podrán hacerlo sin ningún problema.</p>
<p>Espero les sirva esta pequeña guía para cambiar el tipo de acceso de email a nombre de usuario en Laravel.</p>
]]></content:encoded></item></channel></rss>