<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>raulr.net</title>
  
  <subtitle>Web Development, Linux &amp; Stuff</subtitle>
  <link href="https://www.raulr.net/atom.xml" rel="self"/>
  
  <link href="https://www.raulr.net/"/>
  <updated>2022-03-04T23:10:06.863Z</updated>
  <id>https://www.raulr.net/</id>
  
  <author>
    <name>Raúl Rodríguez</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Cómo redimensionar el disco tras mejorar el VPS de OVH</title>
    <link href="https://www.raulr.net/Como-redimensionar-el-disco-tras-mejorar-el-VPS-de-OVH/"/>
    <id>https://www.raulr.net/Como-redimensionar-el-disco-tras-mejorar-el-VPS-de-OVH/</id>
    <published>2017-01-08T20:33:10.000Z</published>
    <updated>2022-03-04T23:10:06.863Z</updated>
    
    <content type="html"><![CDATA[<p>Desde hace unos años <a href="https://www.ovh.es/">OVH</a> ofrece entre sus productos servidores <strong><abbr title="Virtual Private Server">VPS</abbr></strong> a precios asequibles que los hacen interesantes para pequeños proyectos o servidores personales.</p><p>Si en algún momento las prestaciones del <abbr title="Virtual Private Server">VPS</abbr> se quedan cortas para nuestras necesidades, éste se puede mejorar fácilmente dentro de la misma gama a través de la interfaz web de OVH. Algo que puede sorprendernos despues del <em>upgrade</em> es que aunque contemos con más RAM y procesador, <strong>el tamaño del disco sigue siendo el mismo a pesar de que correspondería un aumento</strong>.</p><span id="more"></span><p>En realidad, el espacio de disco sí ha aumentado, pero la partición no se extiende automáticamente para hacer uso de él. Veamos como hacerlo manualmente.</p><div class="alert warning"><p>Un error en la ejecución de los siguientes comandos podría llevar a la pérdida de los datos, por lo que es muy recomendable hacer una copia de seguridad antes de iniciar el proceso.</p></div><p>El primer paso que tenemos que hacer es reiniciar el <abbr title="Virtual Private Server">VPS</abbr> en <strong>modo de rescate</strong>. Esto lo podemos hacer desde el panel de OVH activando previamente el <em>modo experto</em>.</p><div class="figure center nocaption" style="width:;"><img class="fig-img" src="ovh-vps-reiniciar-modo-rescate.png" alt="Reiniciar VPS en modo rescate"></div><p>Tras unos minutos nos llegará un correo con la clave de root del <strong>modo rescate</strong>. Al arrancar en éste modo la <em>huella</em> SSH del servidor cambiará, nos conectamos con los siguientes parámetros para evitar que el cliente lo interprete como un ataque <a href="https://es.wikipedia.org/wiki/Ataque_de_intermediario">man-in-the-middle</a>.</p><pre><code>ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@vps123456.ovh.net</code></pre><p>Una vez en el servidor, listamos las particiones con <code>fdisk -l</code>.</p><pre><code>root@rescue-pro:/# fdisk -lDisk /dev/vda: 10.7 GB, 10737418240 bytes4 heads, 32 sectors/track, 163840 cylinders, total 20971520 sectorsUnits = sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x00000000   Device Boot      Start         End      Blocks   Id  System/dev/vda1   *        2048    20971519    10484736   83  LinuxDisk /dev/vdb: 21.5 GB, 21474836480 bytes4 heads, 32 sectors/track, 327680 cylinders, total 41943040 sectorsUnits = sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x0005bac1   Device Boot      Start         End      Blocks   Id  System/dev/vdb1   *        2048    20971519    10484736   83  Linux</code></pre><p>El disco en <code>/dev/vda</code> es el que alberga el sistema del modo rescate, el que nos interesa es el que está montado sobre <code>/dev/vdb</code>. Apuntamos el sector de inicio de la partición <code>/dev/vdb1</code> para usarlo más adelante (en este caso es <code>2048</code>).</p><p>Usando el comando <code>fdisk</code> vamos a editar la tabla de particiones.</p><pre><code>fdisk /dev/vdb</code></pre><p>Eliminamos la partición actual con el comando <code>d</code>.</p><pre><code>Command (m for help): dSelected partition 1</code></pre><p>Ahora debemos crear una nueva partición con el comando <code>n</code>. Indicamos que es una partición primaria <code>p</code> y que el número de la partición será <code>1</code>. Como sector de inicio introducimos el que hemos apuntado anteriormente y el sector final lo dejamos en blanco para que utilice todo el espacio disponible.</p><pre><code>Command (m for help): nPartition type:   p   primary (0 primary, 0 extended, 4 free)   e   extendedSelect (default p): pPartition number (1-4, default 1): 1First sector (2048-41940991, default 2048): 2048Last sector, +sectors or +size&#123;K,M,G&#125; (2048-41940991, default 41940991): Using default value 41940991</code></pre><p>Marcarmos la partición como ejecutable con el comando <code>a</code>.</p><pre><code>Command (m for help): aPartition number (1-4): 1</code></pre><p>Para persistir los cambios que hemos hecho en la tabla de particiones, usamos el comando <code>w</code>.</p><pre><code>Command (m for help): wThe partition table has been altered!Calling ioctl() to re-read partition table.WARNING: Re-reading the partition table failed with error 16: Device or resource busy.The kernel still uses the old table. The new table will be used atthe next reboot or after you run partprobe(8) or kpartx(8)Syncing disks.</code></pre><p>Reiniciamos el <abbr title="Virtual Private Server">VPS</abbr>.</p><pre><code>reboot</code></pre><p>Nos conectamos de nuevo al servidor tras el reinicio y comprobamos las particiones de nuevo con <code>fdisk -l</code>.</p><pre><code>Disk /dev/vda: 10.7 GB, 10737418240 bytes4 heads, 32 sectors/track, 163840 cylinders, total 20971520 sectorsUnits = sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x00000000   Device Boot      Start         End      Blocks   Id  System/dev/vda1   *        2048    20971519    10484736   83  LinuxDisk /dev/vdb: 21.5 GB, 21474836480 bytes4 heads, 32 sectors/track, 327680 cylinders, total 41943040 sectorsUnits = sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x0005bac1   Device Boot      Start         End      Blocks   Id  System/dev/vdb1   *        2048    41943039    20970496   83  Linux</code></pre><p>Perfecto, podemos ver como ahora la partición <code>/dev/vdb1</code> toma todo el espacio disponible en disco. Sin embargo, todavía nos queda un paso, redimensionar el sistema de ficheros para que emplee el nuevo espacio adjudicado. Para ello usamos el comando <code>resize2fs</code>.</p><pre><code>resize2fs /dev/vdb1</code></pre><p>Para terminar, reiniciamos de nuevo el <abbr title="Virtual Private Server">VPS</abbr> desde el panel, asegurándonos de que esta vez no entre en modo rescate.</p><div class="figure center nocaption" style="width:;"><img class="fig-img" src="ovh-vps-reiniciar-modo-normal.png" alt="Reiniciar VPS en modo normal"></div><p>Y esto es todo, ahora podemos disfrutar en nuestro <abbr title="Virtual Private Server">VPS</abbr> del espacio que le corresponde tras el <em>upgrade</em>.</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Desde hace unos años &lt;a href=&quot;https://www.ovh.es/&quot;&gt;OVH&lt;/a&gt; ofrece entre sus productos servidores &lt;strong&gt;&lt;abbr title=&quot;Virtual Private Server&quot;&gt;VPS&lt;/abbr&gt;&lt;/strong&gt; a precios asequibles que los hacen interesantes para pequeños proyectos o servidores personales.&lt;/p&gt;
&lt;p&gt;Si en algún momento las prestaciones del &lt;abbr title=&quot;Virtual Private Server&quot;&gt;VPS&lt;/abbr&gt; se quedan cortas para nuestras necesidades, éste se puede mejorar fácilmente dentro de la misma gama a través de la interfaz web de OVH. Algo que puede sorprendernos despues del &lt;em&gt;upgrade&lt;/em&gt; es que aunque contemos con más RAM y procesador, &lt;strong&gt;el tamaño del disco sigue siendo el mismo a pesar de que correspondería un aumento&lt;/strong&gt;.&lt;/p&gt;</summary>
    
    
    
    
    <category term="ovh" scheme="https://www.raulr.net/tags/ovh/"/>
    
    <category term="vps" scheme="https://www.raulr.net/tags/vps/"/>
    
  </entry>
  
  <entry>
    <title>Desplegar una aplicación Symfony con Capistrano</title>
    <link href="https://www.raulr.net/Desplegar-una-aplicacion-Symfony-con-Capistrano/"/>
    <id>https://www.raulr.net/Desplegar-una-aplicacion-Symfony-con-Capistrano/</id>
    <published>2016-10-03T11:20:21.000Z</published>
    <updated>2022-03-04T23:10:06.867Z</updated>
    
    <content type="html"><![CDATA[<p>En cualquier proyecto web es deseable que el <strong>despliegue a producción se haga de forma automatizada</strong>: nos libera de realizar una tarea repetitiva, propensa a errores y que suele requerir bastante tiempo. Aún así, existe la percepción de que configurar y mantener un sistema de despliegue automático es demasiado costoso y muchos equipos de desarrollo no se aventuran a ello. Vamos a ver como en realidad no es algo tan complejo si usamos una herramienta como <a href="http://capistranorb.com/">Capistrano</a>.</p><span id="more"></span><p>Aunque <em>Capistrano</em> se creó originariamente para desplegar aplicaciones <em>Ruby on Rails</em>, <strong>es muy configurable y actualmente soporta frameworks de otros lenguajes de programación</strong>. Incluso dispone de un <a href="https://github.com/capistrano/symfony">módulo de Symfony</a> que nos va a facilitar la tarea de integrarlo en nuestro proyecto.</p><h2 id="Como-funciona-Capistrano"><a href="#Como-funciona-Capistrano" class="headerlink" title="Cómo funciona Capistrano"></a>Cómo funciona Capistrano</h2><p>Antes de empezar a usar <em>Capistrano</em> es importante entender como funciona. Cada vez que hacemos un <em>deploy</em>, <strong><em>Capistrano</em> se conecta por SSH al servidor y ejecuta en orden una serie de tareas</strong>. Estas tareas pueden ir desde hacer un <em>pull</em> del repositorio hasta vaciar la caché de <em>Symfony</em>.</p><p>En el servidor, <em>Capistrano</em> crea una jerarquía de directorios para gestionar el código fuente de la aplicación y los ficheros relacionados con el despliegue. La ruta raíz de esta estructura se define en variable de configuración <code>:deploy_to</code>.</p><ul><li><code>releases</code>: En cada <em>deploy</em> se crea un nuevo directorio dentro de esta ruta con el código fuente actual de la aplicación.</li><li><code>shared</code>: El contenido de este directorio es enlazado simbólicamente en cada nueva <em>release</em>. Se utiliza para datos que tengan que persistir de un despliegue a otro, como ficheros de configuración o logs.</li><li><code>current</code>: Es un enlace simbólico que apunta a la última <em>release</em>. En caso de que el <em>deploy</em> falle en algún paso, seguirá apuntando a la anterior <em>release</em>.</li><li><code>repo</code>: Contiene una copia del repositorio de control de versiones.</li><li><code>revisions.log</code>: Fichero donde se escribe el histórico de los despliegues.</li></ul><h2 id="Requisitos-previos"><a href="#Requisitos-previos" class="headerlink" title="Requisitos previos"></a>Requisitos previos</h2><p>Debemos cumplir una serie de requisitos para poder utilizar <em>Capistrano</em>:</p><ul><li>Disponer en nuestra máquina local <em>Ruby</em> versión <code>2.0</code> o superior (En caso de que la versión del repositorio de paquetes del sistema sea menor, podemos instalarlo usando un gestor de versiones de <em>Ruby</em> como <a href="https://rvm.io/">RVM</a> o <a href="https://github.com/rbenv/rbenv">rbenv</a>).</li><li>El proyecto debe usar un sistema de control de versiones (están soportados Git, Mercurial y Subversion).</li><li>El sistema de control de versiones que usemos debe estar instalado también en el servidor.</li><li>El servidor debe permitir la conexión por SSH usando autenticación con clave pública/privada.</li><li>Tener configurado el reenvío del agente SSH al servidor remoto (Es necesario para que el servidor pueda conectarse al repositorio privado de código).</li></ul><p>Si el tema de la autenticación basada en claves de SSH es algo nuevo para ti en <em>GitHub</em> tienes un par de tutoriales sobre como <a href="https://help.github.com/articles/generating-an-ssh-key/">crear claves SSH</a> y <a href="https://developer.github.com/guides/using-ssh-agent-forwarding/">configurar el reenvío de agente SSH</a>.</p><h2 id="Instalar-Capistrano"><a href="#Instalar-Capistrano" class="headerlink" title="Instalar Capistrano"></a>Instalar Capistrano</h2><p>En el directorio raíz de nuestro proyecto <em>Symfony</em> creamos un fichero <code>Gemfile</code>. Este fichero sirve para indicar las <em>gemas</em> (paquetes de <em>Ruby</em>) que queremos que se instalen.</p><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line">source <span class="string">&quot;https://rubygems.org&quot;</span></span><br><span class="line"></span><br><span class="line">gem <span class="string">&#x27;capistrano&#x27;</span>,  <span class="string">&#x27;~&gt; 3.4&#x27;</span></span><br><span class="line">gem <span class="string">&#x27;capistrano-symfony&#x27;</span>, <span class="string">&#x27;~&gt; 1.0.0.rc1&#x27;</span></span><br></pre></td></tr></table></figure><p>Para instalar en el sistema lo que hay especificado en el <code>Gemfile</code> usamos <a href="http://bundler.io/">Bundler</a>, un programa para gestionar las dependencias de las <em>gemas</em>.</p><pre><code>$ gem install bundler$ bundle install</code></pre><div class="alert info"><p><code>Gemfile</code> es el equivalente en <em>Ruby</em> al fichero <code>composer.json</code> de <em>PHP</em>. Además <em>Bundler</em> crea automáticamente el fichero <code>Gemfile.lock</code>, análogo a <code>composer.lock</code>, donde se registran las versiones exactas de las <em>gemas</em> que se han instalado.</p></div><p>Inicializamos la configuración de <em>Capistrano</em>.</p><pre><code>$ bundle exec cap install</code></pre><p>Esto crea la siguiente estructura en el directorio raíz de nuestro proyecto.</p><pre><code>├── Capfile├── config│   ├── deploy│   │   ├── production.rb│   │   └── staging.rb│   └── deploy.rb└── lib    └── capistrano            └── tasks</code></pre><ul><li><code>Capfile</code> define la lista de módulos de <em>Capistrano</em> que se usarán en el proyecto.</li><li><code>config/deploy.rb</code> contiene la configuración global de despliegue para este proyecto.</li><li><code>config/deploy/production.rb</code> y <code>config/deploy/staging.rb</code> contienen configuración específica para esos entornos. Podemos definir todos los entornos que deseemos.</li><li>En el directorio <code>lib/capistrano/tasks</code> se puede crear ficheros <code>.rake</code> con tareas personalizadas.</li></ul><p>En el fichero <code>Capfile</code>, añadimos la siguiente línea al final de los <code>require</code> para cargar el módulo de <em>Symfony</em>.</p><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line"><span class="keyword">require</span> <span class="string">&#x27;capistrano/symfony&#x27;</span></span><br></pre></td></tr></table></figure><p>Ya tenemos listo <em>Capistrano</em> para funcionar con <em>Symfony</em>, a falta de configurarlo para nuestro proyecto.</p><h2 id="Configurar-Capistrano"><a href="#Configurar-Capistrano" class="headerlink" title="Configurar Capistrano"></a>Configurar Capistrano</h2><p>El fichero <code>deploy.rb</code> tendrá un contenido similar a lo siguiente:</p><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line">set <span class="symbol">:application</span>, <span class="string">&#x27;capistrano-symfony-example&#x27;</span></span><br><span class="line">set <span class="symbol">:deploy_to</span>, <span class="string">&#x27;/var/www/my_app_name&#x27;</span></span><br><span class="line"></span><br><span class="line">set <span class="symbol">:repo_url</span>, <span class="string">&#x27;https://github.com/symfony/symfony-demo.git&#x27;</span></span><br><span class="line">set <span class="symbol">:scm</span>, <span class="symbol">:git</span></span><br><span class="line">set <span class="symbol">:branch</span>, <span class="string">&#x27;master&#x27;</span></span><br><span class="line"></span><br><span class="line">set <span class="symbol">:linked_files</span>, [<span class="string">&quot;app/config/parameters.yml&quot;</span>]</span><br><span class="line">set <span class="symbol">:linked_dirs</span>, [<span class="string">&quot;var/logs&quot;</span>, <span class="string">&quot;web/uploads&quot;</span>]</span><br><span class="line"></span><br><span class="line">set <span class="symbol">:keep_releases</span>, <span class="number">5</span></span><br><span class="line"></span><br><span class="line">set <span class="symbol">:symfony_directory_structure</span>, <span class="number">3</span></span><br><span class="line">set <span class="symbol">:sensio_distribution_version</span>, <span class="number">5</span></span><br><span class="line"></span><br><span class="line">set <span class="symbol">:permission_method</span>, <span class="symbol">:acl</span></span><br><span class="line">set <span class="symbol">:file_permissions_users</span>, [<span class="string">&quot;www-data&quot;</span>]</span><br><span class="line">set <span class="symbol">:file_permissions_paths</span>, [<span class="string">&quot;var&quot;</span>, <span class="string">&quot;web/uploads&quot;</span>]</span><br></pre></td></tr></table></figure><h3 id="Variables-de-despliegue"><a href="#Variables-de-despliegue" class="headerlink" title="Variables de despliegue"></a>Variables de despliegue</h3><ul><li><code>:application</code>: Nombre de la aplicación.</li><li><code>:deploy_to</code>: Directorio al que se desplegará la aplicación en el servidor. Por defecto es <code>/var/www/&lt;nombre-de-aplicación&gt;</code>.</li><li><code>:repo_url</code>: URL del repositorio de código de nuestro proyecto.</li><li><code>:scm</code>: Tipo de sistema de control de versiones usado. Por defecto es <code>:git</code>.</li><li><code>:branch</code>: Rama del repositorio a desplegar en el servidor. Por defecto es <code>master</code>.</li><li><code>:linked_files</code>: Los ficheros serán enlazados simbólicamente en el directorio de la <em>release</em> durante el despliegue. Útil para crear ficheros de configuración persistentes.</li><li><code>:linked_dirs</code>: Exactamente igual a <code>:linked_files</code> pero para directorios.</li><li><code>:keep_releases</code>: Número de <em>releases</em> que se mantendrán en el servidor para poder efectuar un <em>rollback</em> a cualquiera de ellas.</li></ul><p>Estas son solo algunas de las variables que podemos utilizar, consulta el resto en la <a href="http://capistranorb.com/documentation/getting-started/configuration/">documentación de Capistrano</a>.</p><h3 id="Variables-de-Symfony"><a href="#Variables-de-Symfony" class="headerlink" title="Variables de Symfony"></a>Variables de Symfony</h3><ul><li><code>:symfony_directory_structure</code>: Hay que establecer un <code>2</code> o un <code>3</code> dependiendo de la versión de <em>Symfony</em> que use nuestro proyecto.</li><li><code>:sensio_distribution_version</code>: Solo es necesario establecerlo en proyectos de <em>Symfony 2</em> que usen una versión de <a href="https://github.com/sensiolabs/SensioDistributionBundle">SensioDistributionBundle</a> menor a la 5.</li></ul><p>Aunque con establecer estas variables en principio es suficiente, para proyectos de <em>Symfony</em> con estructuras poco convencionales <a href="https://github.com/capistrano/symfony#settings">disponemos de variables para un mayor control</a>.</p><h3 id="Variables-de-Permisos"><a href="#Variables-de-Permisos" class="headerlink" title="Variables de Permisos"></a>Variables de Permisos</h3><p>Un escenario común suele ser que el usuario que corre el servidor web y el usuario con el que se reliza el <em>deploy</em> sean distintos, y ambos necesitan tener acceso de lectura/escritura a ciertos directorios de <em>Symfony</em>. En este caso hay que establecer las siguientes variables.</p><ul><li><code>:permission_method</code>: Método para cambiar los permisos. Puede ser <code>:chmod</code>, <code>:acl</code> o <code>:chgrp</code>.</li><li><code>:file_permissions_users</code>: Usuario que ejecuta el servidor web. Suele ser <code>www-data</code> en distribuciones basadas en <em>Debian</em>.</li><li><code>:file_permissions_paths</code>: Directorios del proyecto que requieren cambiar los permisos.</li></ul><h3 id="Configuracion-del-servidor"><a href="#Configuracion-del-servidor" class="headerlink" title="Configuración del servidor"></a>Configuración del servidor</h3><p>En los ficheros que hay en <code>config/deploy</code> se establece la configuración específica para cada entorno. La mínima configuración que hay que meter es el servidor al que desplegar y con qué usuario.</p><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line">server <span class="string">&#x27;miserver.com&#x27;</span>, <span class="symbol">user:</span> <span class="string">&#x27;miuser&#x27;</span>, <span class="symbol">roles:</span> <span class="string">%w&#123;web&#125;</span></span><br></pre></td></tr></table></figure><div class="alert info"><p>Para proyectos complejos que necesitan distintos tipos de servidores (servidor de base de datos, servidor web…), <em>Capistrano</em> introduce el concepto de <em>roles</em> para etiquetar cada servidor y controlar las tareas que se ejecutan en él. En este post no vamos a adentrarnos en su uso.</p></div><h3 id="Preparar-el-servidor"><a href="#Preparar-el-servidor" class="headerlink" title="Preparar el servidor"></a>Preparar el servidor</h3><p>Dado que el directorio <code>current</code> apunta a la release activa, debemos establecer en la configuración de nuestro servidor web que la raíz pública del site estará en <code>/var/www/my_app_name/current/web</code>.</p><div class="alert info"><p>Si nuestro servidor web es <strong>Apache</strong> hay que editar la directiva <a href="https://httpd.apache.org/docs/2.0/es/mod/core.html#documentroot">DocumentRoot</a> del <em>Virtual Host</em>. En caso de usar <strong>Nginx</strong>, la directiva se llama <a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#root">root</a>.</p></div><p>Hay una cosa que <em>Capistrano</em> no puede hacer automáticamente, y es crear el fichero <a href="http://symfony.com/doc/current/best_practices/configuration.html">parameters.yml</a> que necesita <em>Symfony</em> con la <strong>configuración del entorno producción</strong>. Por ello, antes de hacer <em>deploy</em> por primera vez necesitamos crearlo en la ruta <code>/var/www/my_app_name/shared/app/config</code> del servidor y rellenarlo con los parámetros que necesite nuestra aplicación (comúnmente los parámetros de conexión a Base de Datos).</p><h3 id="Despliegue"><a href="#Despliegue" class="headerlink" title="Despliegue"></a>Despliegue</h3><p>Una vez todo configurado, podemos realizar el despliegue a producción con el comando:</p><pre><code>$ bundle exec cap production deploy</code></pre><p>Para desplegar en un entorno distinto solo tenemos que cambiar <code>production</code> por otro que tengamos definido.</p><p>A parte de <code>deploy</code> <em>Capistrano</em> dispone de otros comandos que pueden resultarnos útiles. Podemos ver el listado completo ejecutando:</p><pre><code>$ bundle exec cap -T</code></pre><h3 id="Usar-la-consola-de-Symfony"><a href="#Usar-la-consola-de-Symfony" class="headerlink" title="Usar la consola de Symfony"></a>Usar la consola de Symfony</h3><p>A través de <em>Capistrano</em> se pueden enviar comandos a la consola de <em>Symfony</em> del servidor con el formato <code>bundle exec <strong><em>entorno</em></strong> cap symfony:console[<strong><em>comando</em></strong>,<strong><em>parámetros</em></strong>,<strong><em>rol</em></strong>]</code>. Por ejemplo para crear el esquema de la Base de Datos en producción lanzamos:</p><pre><code>$ bundle exec cap production symfony:console[doctrine:schema:create]</code></pre>]]></content>
    
    
    <summary type="html">&lt;p&gt;En cualquier proyecto web es deseable que el &lt;strong&gt;despliegue a producción se haga de forma automatizada&lt;/strong&gt;: nos libera de realizar una tarea repetitiva, propensa a errores y que suele requerir bastante tiempo. Aún así, existe la percepción de que configurar y mantener un sistema de despliegue automático es demasiado costoso y muchos equipos de desarrollo no se aventuran a ello. Vamos a ver como en realidad no es algo tan complejo si usamos una herramienta como &lt;a href=&quot;http://capistranorb.com/&quot;&gt;Capistrano&lt;/a&gt;.&lt;/p&gt;</summary>
    
    
    
    
    <category term="php" scheme="https://www.raulr.net/tags/php/"/>
    
    <category term="symfony" scheme="https://www.raulr.net/tags/symfony/"/>
    
    <category term="capistrano" scheme="https://www.raulr.net/tags/capistrano/"/>
    
  </entry>
  
  <entry>
    <title>Instalar Ionic Framework</title>
    <link href="https://www.raulr.net/Instalar-Ionic-Framework/"/>
    <id>https://www.raulr.net/Instalar-Ionic-Framework/</id>
    <published>2016-04-16T13:23:31.000Z</published>
    <updated>2022-03-04T23:10:06.867Z</updated>
    
    <content type="html"><![CDATA[<p><a href="http://ionicframework.com/">Ionic</a> es un framework que permite <strong>crear aplicaciones móviles multiplataforma utilizando tecnologías web actuales</strong>, es decir, <em>HTML5</em>, <em>CSS3</em> y <em>JavaScript</em>.</p><span id="more"></span><p>Uno de sus puntos fuertes es que permite probar la aplicación que estamos desarrollando sobre nuestro móvil de foma muy ágil (con un único comando se compila, empaqueta y transfiere la app al teléfono).</p><p>Sin embargo, Ionic requiere una serie de dependencias en el sistema que pueden hacer un poco frustrante su instalación. A continuación voy a detallar los pasos necesarios para configurar un entorno <em>Ionic ready</em> en Debian o distribuciones basadas en Debian (Ubuntu, Linux Mint, ElementaryOS…).</p><h2 id="Node-js"><a href="#Node-js" class="headerlink" title="Node.js"></a>Node.js</h2><p>Por lo general el repositorio por defecto del sistema trae una versión bastante desfasada de Node, por lo que es recomendable instalarlo del repositorio que provee la comunidad de Node.js.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -</span><br><span class="line">sudo apt-get install -y nodejs</span><br></pre></td></tr></table></figure><h2 id="Cordova-e-Ionic-Framework"><a href="#Cordova-e-Ionic-Framework" class="headerlink" title="Cordova e Ionic Framework"></a>Cordova e Ionic Framework</h2><p>Bajo el capó, Ionic utiliza <a href="https://cordova.apache.org/">Apache Cordova</a> para empaquetar nuestra aplicación web en una aplicación móvil nativa. Una vez tenemos Node.js en el sistema, Cordova e Ionic se pueden instalar fácilmente con un simple comando.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">sudo npm install -g cordova ionic</span><br></pre></td></tr></table></figure><p>Para comprobar que todo está correcto podemos ejecutar el comando <code>ionic info</code> y mostrará algo parecido a esto.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Your system information:</span><br><span class="line"></span><br><span class="line">Cordova CLI: 6.1.1</span><br><span class="line">Ionic Version: 1.2.4</span><br><span class="line">Ionic CLI Version: 1.7.14</span><br><span class="line">Ionic App Lib Version: 0.7.0</span><br><span class="line">OS: Distributor ID:Ubuntu Description:Ubuntu 14.04.4 LTS </span><br><span class="line">Node Version: v4.4.3</span><br></pre></td></tr></table></figure><h2 id="Java-Development-Kit"><a href="#Java-Development-Kit" class="headerlink" title="Java Development Kit"></a>Java Development Kit</h2><p>Instalamos la última versión de OpenJDK disponible para nuestro sistema. En mi caso es OpenJDK 7.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">sudo apt-get install openjdk-7-jdk</span><br></pre></td></tr></table></figure><h2 id="SDK-de-Android"><a href="#SDK-de-Android" class="headerlink" title="SDK de Android"></a>SDK de Android</h2><h3 id="Descargar-SDK"><a href="#Descargar-SDK" class="headerlink" title="Descargar SDK"></a>Descargar SDK</h3><p>En la web de <a href="https://developer.android.com/sdk/index.html#downloads">Android Studio</a> se pueden descargar las herramientas SDK sin necesidad de instalar toda la suite. Descargamos el paquete <code>android-sdk_r24.4.1-linux.tgz</code> y lo descomprimimos en nuestra <em>home</em>.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">tar -xzvf android-sdk_r24.4.1-linux.tgz -C &quot;$HOME&quot;</span><br></pre></td></tr></table></figure><p>Si nuestro sistema es de <strong>64 bits</strong> (lo podemos comprobar escribiendo en el terminal <code>uname -m</code>), además vamos a necesitar instalar algunas bibliotecas de <strong>32 bits</strong>.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 lib32stdc++6</span><br></pre></td></tr></table></figure><h3 id="Establecer-las-variables-de-entorno"><a href="#Establecer-las-variables-de-entorno" class="headerlink" title="Establecer las variables de entorno"></a>Establecer las variables de entorno</h3><p>Para que Cordova sepa donde se encuentra instalado el SDK de Android es necesario establecer la variable de entorno <code>ANDROID_HOME</code> con la ruta donde lo hemos descomprimido.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">echo &#x27;export ANDROID_HOME=$HOME/android-sdk-linux&#x27; &gt;&gt; ~/.bash_profile</span><br></pre></td></tr></table></figure><p>También conviene añadir las herramientas del SDK de Android al <code>PATH</code>.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">echo &#x27;export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools&#x27; &gt;&gt; ~/.bash_profile</span><br></pre></td></tr></table></figure><p>Al añadir todo esto al fichero <code>.bash_profile</code> las variables de entorno estarán configuradas en la próxima sesión de terminal que iniciemos. Para disponer de ellas en las sesión actual solo necesitamos recargar el fichero.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">source ~/.bash_profile</span><br></pre></td></tr></table></figure><h3 id="Anadir-los-paquetes-del-SDK"><a href="#Anadir-los-paquetes-del-SDK" class="headerlink" title="Añadir los paquetes del SDK"></a>Añadir los paquetes del SDK</h3><p>Lanzamos la aplicación <em>Android SDK Manager</em> con el comando <code>android</code> e instalamos los siguientes paquetes:</p><ul><li><em>Android SDK Platform-tools</em> (la última versión)</li><li><em>Android SDK Build-tools</em> (la última versión)</li><li><em>SDK Platform</em> (de la última versión disponible de la API)</li></ul><div class="figure center nocaption" style="width:;"><img class="fig-img" src="Android_SDK_Manager.png" alt="Android SDK Manager"></div><h2 id="Compilar-una-App"><a href="#Compilar-una-App" class="headerlink" title="Compilar una App"></a>Compilar una App</h2><p>Para ver que hemos instalado todo como es debido, vamos a crear una App de prueba y generar un fichero <code>apk</code> de Android a partir de ella.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ionic start test</span><br><span class="line">cd test</span><br><span class="line">ionic platform add android</span><br><span class="line">ionic build android</span><br></pre></td></tr></table></figure><p>Veremos el log de la compilación y al final el mensaje <em>BUILD SUCCESSFUL</em> y la ruta donde se ha generado el <code>apk</code>.</p><h3 id="Habilitar-depuracion-USB"><a href="#Habilitar-depuracion-USB" class="headerlink" title="Habilitar depuración USB"></a>Habilitar depuración USB</h3><p>Antes de poder lanzar la aplicación sobre un hardware real será necesario activar el modo de depuración USB en nuestro teléfono Android.</p><ol><li>Ir a <em>Ajustes</em> &gt; <em>Información del teléfono</em> y pulsar siete veces sobre <strong>Número de compilación</strong>.</li><li>En <em>Ajustes</em> &gt; <em>Opciones de desarrollo</em> habilitar la <strong>Depuración USB</strong>.</li><li>Conectar el teléfono al PC con un cable USB y permitir la depuración en el popup que aparecerá.</li></ol><div class="figure center nocaption" style="width:;"><img class="fig-img" src="Android_habilitar_depuracion_usb.png" alt="Habilitar depuración USB en Android"></div><h3 id="Lanzar-la-App"><a href="#Lanzar-la-App" class="headerlink" title="Lanzar la App"></a>Lanzar la App</h3><p>A partir de ahora, desplegar la aplicación en nuestro dispositivo móvil es tan sencillo como ejecutar el siguiente comando.</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ionic run android --device</span><br></pre></td></tr></table></figure><div class="alert info"><p>El proceso de compilar y lanzar la aplicación en un dispositivo IOS (iPhone, iPad) es el mismo, solo que en este caso se precisa de un sistema Mac OS X con XCode 6.0 instalado.</p></div>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;a href=&quot;http://ionicframework.com/&quot;&gt;Ionic&lt;/a&gt; es un framework que permite &lt;strong&gt;crear aplicaciones móviles multiplataforma utilizando tecnologías web actuales&lt;/strong&gt;, es decir, &lt;em&gt;HTML5&lt;/em&gt;, &lt;em&gt;CSS3&lt;/em&gt; y &lt;em&gt;JavaScript&lt;/em&gt;.&lt;/p&gt;</summary>
    
    
    
    
    <category term="ionic" scheme="https://www.raulr.net/tags/ionic/"/>
    
    <category term="desarrollo" scheme="https://www.raulr.net/tags/desarrollo/"/>
    
    <category term="android" scheme="https://www.raulr.net/tags/android/"/>
    
    <category term="ios" scheme="https://www.raulr.net/tags/ios/"/>
    
  </entry>
  
  <entry>
    <title>Entornos virtuales de desarrollo con Vagrant</title>
    <link href="https://www.raulr.net/Entornos-virtuales-desarrollo-Vagrant/"/>
    <id>https://www.raulr.net/Entornos-virtuales-desarrollo-Vagrant/</id>
    <published>2016-02-19T20:51:00.000Z</published>
    <updated>2022-03-04T23:10:06.867Z</updated>
    
    <content type="html"><![CDATA[<p>Comúnmente, en un proyecto web, los desarrolladores prueban la aplicación que están construyendo en su propio equipo de trabajo. Pero, muchas veces, <strong>configurar y mantener el entorno de desarrollo no es tarea sencilla</strong>.<span id="more"></span> Veamos tres posibles escenarios:</p><ol><li><p>Los miembros del equipo de desarrollo usan indistintamente GNU/Linux, Mac OS X o Windows, cada uno con versiones diferentes de bases de datos, intérpretes, dependencias… Esto lleva a inconsistencias y, en muchos casos, el código que funciona en el equipo de un desarrollador no funciona en el de otro.</p></li><li><p>Estamos desarrollando varios proyectos en paralelo que tienen dependencias que entran en conflicto entre sí.</p></li><li><p>Entra una persona nueva en el departamento y tiene que instalar y configurar un equipo con todas las dependencias del proyecto antes de poder ponerse a trabajar.</p></li></ol><p>La solución a estos problemas es utilizar <a href="http://es.wikipedia.org/wiki/M%C3%A1quina_virtual">máquinas virtuales</a>. Así, podemos aislar el entorno de pruebas del entorno de trabajo y, además, compartirlo entre los miembros del equipo de desarrollo.</p><p>Hoy en día disponemos de multiples soluciones de virtualización: VMWare, Xen, VirtualBox, KVM, LXC… Pero requieren instalar el Sistema Operativo desde cero y suelen ser complejas de configurar. Entra Vagrant al rescate.</p><h2 id="¿Que-es-Vagrant"><a href="#¿Que-es-Vagrant" class="headerlink" title="¿Qué es Vagrant?"></a>¿Qué es Vagrant?</h2><p>Vagrant es una aplicación escrita en Ruby que <strong>facilita considerablemente la creación de entornos virtuales de desarrollo</strong>. Para ello Vagrant nos abstrae del sistema de virtualización subyacente y nos permite instalar y configurar el software de la máquina virtual con herramientas de automatización como <em>Chef</em>, <em>Puppet</em> o incluso los clásicos <em>scripts de shell</em>.</p><h2 id="Manos-a-la-obra"><a href="#Manos-a-la-obra" class="headerlink" title="Manos a la obra"></a>Manos a la obra</h2><h3 id="Instalacion"><a href="#Instalacion" class="headerlink" title="Instalación"></a>Instalación</h3><p>Aunque Vagrant puede ser utilizado con varios sistemas de virtualización, vamos a utilizar VirtualBox porque es gratuito, está disponible en las plataformas mayoritarias y funciona con Vagrant sin configuraciones adicionales.</p><ol><li><p>Descargamos la <a href="http://downloads.vagrantup.com/">última versión de Vagrant</a> disponible para nuestra plataforma y la instalamos en nuestro sistema.</p></li><li><p>Descargamos y ejecutamos el instalador adecuado para nuestra plataforma de la <a href="https://www.virtualbox.org/wiki/Downloads">página de descargas de VirtualBox</a>. En algunas distribuciones de GNU/Linux podemos añadir a nuestras fuentes su <a href="https://www.virtualbox.org/wiki/Linux_Downloads">repositorio de paquetes</a>.</p></li></ol><h3 id="Inicio-rapido"><a href="#Inicio-rapido" class="headerlink" title="Inicio rápido"></a>Inicio rápido</h3><p>Inicializamos la configuración partiendo de una imagen de base.</p><pre><code>$ vagrant init precise32 http://files.vagrantup.com/precise32.box</code></pre><p>Lanzamos la <abbr title="Virtual Machine">VM</abbr>.</p><pre><code>$ vagrant up</code></pre><p>Con estos dos simples comandos ya tenemos funcionando una máquina virtual de Ubuntu 12.04 LTS de 32 bits. Podemos conectarnos a ella por SSH con <code>vagrant ssh</code> y, una vez hemos terminado de usarla, eliminarla con <code>vagrant destroy</code>.</p><p>El comando <code>vagrant init</code> crea un fichero <code>Vagrantfile</code> en el directorio donde lo hemos ejecutado que contiene la configuración de la máquina virtual. Estando en ese directorio, con <code>vagrant up</code> podemos volver a levantar la máquina sin necesidad de hacer de nuevo el <code>init</code>.</p><h2 id="Boxes"><a href="#Boxes" class="headerlink" title="Boxes"></a>Boxes</h2><p>En Vagrant una <code>box</code> es un fichero que contiene la base a partir de la cual se crean las máquinas virtuales. Este fichero puede ser compartido fácilmente para que otros repliquen nuestro mismo entorno de desarrollo.</p><p>Antes hemos mostrado cómo crear una máquina virtual con Ubuntu, pero no estamos limitados a este sistema. En la página <a href="http://www.vagrantbox.es/">vagrantbox.es</a> disponemos de un listado enorme de Sistemas Operativos, tanto de 32 como de 64 bits, que podemos utilizar como base para nuestras máquinas de Vagrant. Podríamos incluso crear nuestras propias <code>boxes</code> utilizando <a href="https://github.com/jedi4ever/veewee">Veewee</a>.</p><h2 id="Comandos"><a href="#Comandos" class="headerlink" title="Comandos"></a>Comandos</h2><h3 id="vagrant-init-box-name-box-url"><a href="#vagrant-init-box-name-box-url" class="headerlink" title="vagrant init [box-name] [box-url]"></a><code>vagrant init [box-name] [box-url]</code></h3><p>Inicializa el fichero de configuración <code>Vagrantfile</code> en el directorio actual. Si se pasan el segundo y el tercer parámetro, se establecen el nombre y la <code>box</code> a utilizar en la configuración.</p><h3 id="vagrant-up"><a href="#vagrant-up" class="headerlink" title="vagrant up"></a><code>vagrant up</code></h3><p>Levanta la máquina virtual de acuerdo a la configuración del <code>Vagrantfile</code> del directorio actual.</p><h3 id="vagrant-halt"><a href="#vagrant-halt" class="headerlink" title="vagrant halt"></a><code>vagrant halt</code></h3><p>Detiene la máquina virtual, pero mantiene los cambios que hayamos hecho en ella para la siguiente vez que ejecutemos <code>vagrant up</code>.</p><h3 id="vagrant-reload"><a href="#vagrant-reload" class="headerlink" title="vagrant reload"></a><code>vagrant reload</code></h3><p>Equivale a hacer un <code>vagrant halt</code> seguido de un <code>vagrant up</code>. Tras hacer cambios en un <code>Vagrantfile</code> es necesario hacer <code>reload</code>.</p><h3 id="vagrant-suspend"><a href="#vagrant-suspend" class="headerlink" title="vagrant suspend"></a><code>vagrant suspend</code></h3><p>Suspende la máquina virtual, salvando el estado de ejecución actual de forma que pueda ser resumido más tarde y continuar desde ese punto exacto.</p><h3 id="vagrant-resume"><a href="#vagrant-resume" class="headerlink" title="vagrant resume"></a><code>vagrant resume</code></h3><p>Resume una máquina que ha sido anteriormente suspendida con <code>vagrant suspend</code>.</p><h3 id="vagrant-destroy"><a href="#vagrant-destroy" class="headerlink" title="vagrant destroy"></a><code>vagrant destroy</code></h3><p>Detiene la máquina virtual y destruye todos los cambios que podamos haber hecho. La siguiente vez que hagamos un <code>vagrant up</code> partirá de una imagen totalmente limpia.</p><h3 id="vagrant-ssh"><a href="#vagrant-ssh" class="headerlink" title="vagrant ssh"></a><code>vagrant ssh</code></h3><p>Nos conecta por SSH a la máquina virtual en ejecución.</p><h3 id="vagrant-status"><a href="#vagrant-status" class="headerlink" title="vagrant status"></a><code>vagrant status</code></h3><p>Muestra el estado de las máquinas levantadas con Vagrant.</p><h3 id="vagrant-box"><a href="#vagrant-box" class="headerlink" title="vagrant box"></a><code>vagrant box</code></h3><p>Comando para gestionar las <code>boxes</code> que tenemos en nuestro sistema.</p><h3 id="vagrant-package"><a href="#vagrant-package" class="headerlink" title="vagrant package"></a><code>vagrant package</code></h3><p>Exporta la máquina virtual en ejecución en un fichero <code>box</code> que puede ser reutilizado.</p><h2 id="Vagrantfile"><a href="#Vagrantfile" class="headerlink" title="Vagrantfile"></a>Vagrantfile</h2><p>El fichero <code>Vagrantfile</code> contiene el tipo de máquina virtual y su configuración. Por defecto, tras hacer <code>vagrant init</code>, la configuración solo incluye el nombre de la <code>box</code> que va a usar y su URL. Pero con unas pocas opciones podemos configurar la máquina según nuestras necesidades:</p><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line">Vagrant.configure(<span class="string">&quot;2&quot;</span>) <span class="keyword">do</span> <span class="params">|config|</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Nombre de la box a utilizar</span></span><br><span class="line">  config.vm.box = <span class="string">&quot;precise32&quot;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Url de donde Vagrant se descargará la box si no existe ya en el sistema</span></span><br><span class="line">  config.vm.box_url = <span class="string">&quot;http://files.vagrantup.com/precise32.box&quot;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Redirigir el puerto 80 de la VM al 8080 local</span></span><br><span class="line">  config.vm.network <span class="symbol">:forwarded_port</span>, <span class="symbol">guest:</span> <span class="number">80</span>, <span class="symbol">host:</span> <span class="number">8080</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Asignar una IP a la VM que es solo accesible desde nuestro equipo</span></span><br><span class="line">  config.vm.network <span class="symbol">:private_network</span>, <span class="symbol">ip:</span> <span class="string">&quot;192.168.33.10&quot;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Compartir un directorio de nuestro host con la VM</span></span><br><span class="line">  config.vm.synced_folder <span class="string">&quot;~/shared&quot;</span>, <span class="string">&quot;/vagrant_shared&quot;</span></span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><p>Esto es solo un pequeño ejemplo de lo que se puede hacer. Hay muchas más opciones de configuración que pueden consultarse en la <a href="http://docs.vagrantup.com/v2/vagrantfile/index.html">documentación de Vagrant</a>.</p><h2 id="Providers"><a href="#Providers" class="headerlink" title="Providers"></a>Providers</h2><ul><li><p><strong><a href="https://www.virtualbox.org/">VirtualBox</a></strong>: Es el proveedor de virtualización por defecto de Vagrant.</p></li><li><p><strong><a href="http://www.vmware.com/">VMWare</a></strong>: Se recomienda en caso de usar Vagrant para crear arquitecturas en producción, ya que tiene mejor rendimiento que VirtualBox. Es necesario <a href="http://www.vagrantup.com/vmware">adquirir la licencia</a> para usarlo.</p></li><li><p><strong><a href="http://aws.amazon.com/">AWS</a></strong>: Existe un plugin no oficial de Vagrant, <a href="https://github.com/mitchellh/vagrant-aws">vagrant-aws</a>, que permite desplegar nuestro entorno en la nube de Amazon.</p></li><li><p><strong>Otros proveedores</strong>: Vagrant se puede extender mediante plugins escritos en Ruby, por lo que podríamos crear nuestro propio proveedor personalizado.  </p></li></ul><h2 id="Provisioning"><a href="#Provisioning" class="headerlink" title="Provisioning"></a>Provisioning</h2><p>La mayoría de las veces la <code>box</code> que utilicemos vendrá con poco más que el <abbr title="Sitema Operativo">SO</abbr> instalado. Podremos acceder a la máquina con <code>vagrant ssh</code> e instalar a mano el software que necesitemos. Pero mejor que eso es utilizar los <em>provisioners</em> de Vagrant que automatizan el proceso de instalar y configurar el software. Disponemos de varias alternativas:</p><ul><li><p><strong>Shell</strong>: La forma más simple de aprovisionar la máquina virtual es definir un script de shell que se lanzará al realizar <code>vagrant up</code>.</p></li><li><p><strong>Ansible</strong>: <a href="http://www.ansibleworks.com/">Ansible</a> es un framework de automatización que se sirve de configuraciones escritas en documentos <a href="http://en.wikipedia.org/wiki/YAML">YAML</a> para orquestar los despliegues. </p></li><li><p><strong>Chef Client</strong>: <a href="http://www.opscode.com/chef/">Chef</a> es una herramienta para la gestión de configuración y aprovisionamiento automático de sistemas. Utiliza una arquitectura Cliente-Servidor y las configuraciones, denominadas <em>recetas</em>, se escriben en un <abbr title="Domain Specific Language">DSL</abbr> sobre Ruby.</p></li><li><p><strong>Chef Solo</strong>: <a href="https://docs.chef.io/chef_solo.html">Chef Solo</a> es una variante de Chef que no necesita el nodo servidor para funcionar. Todas las <em>recetas</em> que utilicemos deben residir en el disco.</p></li><li><p><strong>Puppet Agent</strong>: <a href="https://puppetlabs.com/puppet/what-is-puppet/">Puppet</a> es un software de automatización similar a Chef. Al igual que éste tiene una arquitectura Cliente-Servidor y las configuraciones pueden ser escritas en Ruby, aunque el lenguaje principal es un <abbr title="Domain Specific Language">DSL</abbr> propio de Puppet.</p></li><li><p><strong>Puppet Apply</strong>: Es el equivalente a Chef Solo para Puppet. No requiere del <em>Puppet Master</em> para funcionar.</p></li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;Comúnmente, en un proyecto web, los desarrolladores prueban la aplicación que están construyendo en su propio equipo de trabajo. Pero, muchas veces, &lt;strong&gt;configurar y mantener el entorno de desarrollo no es tarea sencilla&lt;/strong&gt;.</summary>
    
    
    
    
    <category term="vagrant" scheme="https://www.raulr.net/tags/vagrant/"/>
    
    <category term="virtualización" scheme="https://www.raulr.net/tags/virtualizacion/"/>
    
  </entry>
  
</feed>
