Si en algún momento las prestaciones del VPS 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 upgrade es que aunque contemos con más RAM y procesador, el tamaño del disco sigue siendo el mismo a pesar de que correspondería un aumento.
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.
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.
El primer paso que tenemos que hacer es reiniciar el VPS en modo de rescate. Esto lo podemos hacer desde el panel de OVH activando previamente el modo experto.
Tras unos minutos nos llegará un correo con la clave de root del modo rescate. Al arrancar en éste modo la huella SSH del servidor cambiará, nos conectamos con los siguientes parámetros para evitar que el cliente lo interprete como un ataque man-in-the-middle.
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@vps123456.ovh.net
Una vez en el servidor, listamos las particiones con fdisk -l
.
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
El disco en /dev/vda
es el que alberga el sistema del modo rescate, el que nos interesa es el que está montado sobre /dev/vdb
. Apuntamos el sector de inicio de la partición /dev/vdb1
para usarlo más adelante (en este caso es 2048
).
Usando el comando fdisk
vamos a editar la tabla de particiones.
fdisk /dev/vdb
Eliminamos la partición actual con el comando d
.
Command (m for help): dSelected partition 1
Ahora debemos crear una nueva partición con el comando n
. Indicamos que es una partición primaria p
y que el número de la partición será 1
. 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.
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{K,M,G} (2048-41940991, default 41940991): Using default value 41940991
Marcarmos la partición como ejecutable con el comando a
.
Command (m for help): aPartition number (1-4): 1
Para persistir los cambios que hemos hecho en la tabla de particiones, usamos el comando w
.
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.
Reiniciamos el VPS.
reboot
Nos conectamos de nuevo al servidor tras el reinicio y comprobamos las particiones de nuevo con fdisk -l
.
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
Perfecto, podemos ver como ahora la partición /dev/vdb1
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 resize2fs
.
resize2fs /dev/vdb1
Para terminar, reiniciamos de nuevo el VPS desde el panel, asegurándonos de que esta vez no entre en modo rescate.
Y esto es todo, ahora podemos disfrutar en nuestro VPS del espacio que le corresponde tras el upgrade.
]]>Aunque Capistrano se creó originariamente para desplegar aplicaciones Ruby on Rails, es muy configurable y actualmente soporta frameworks de otros lenguajes de programación. Incluso dispone de un módulo de Symfony que nos va a facilitar la tarea de integrarlo en nuestro proyecto.
Antes de empezar a usar Capistrano es importante entender como funciona. Cada vez que hacemos un deploy, Capistrano se conecta por SSH al servidor y ejecuta en orden una serie de tareas. Estas tareas pueden ir desde hacer un pull del repositorio hasta vaciar la caché de Symfony.
En el servidor, Capistrano 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 :deploy_to
.
releases
: En cada deploy se crea un nuevo directorio dentro de esta ruta con el código fuente actual de la aplicación.shared
: El contenido de este directorio es enlazado simbólicamente en cada nueva release. Se utiliza para datos que tengan que persistir de un despliegue a otro, como ficheros de configuración o logs.current
: Es un enlace simbólico que apunta a la última release. En caso de que el deploy falle en algún paso, seguirá apuntando a la anterior release.repo
: Contiene una copia del repositorio de control de versiones.revisions.log
: Fichero donde se escribe el histórico de los despliegues.Debemos cumplir una serie de requisitos para poder utilizar Capistrano:
2.0
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 Ruby como RVM o rbenv).Si el tema de la autenticación basada en claves de SSH es algo nuevo para ti en GitHub tienes un par de tutoriales sobre como crear claves SSH y configurar el reenvío de agente SSH.
En el directorio raíz de nuestro proyecto Symfony creamos un fichero Gemfile
. Este fichero sirve para indicar las gemas (paquetes de Ruby) que queremos que se instalen.
source "https://rubygems.org" |
Para instalar en el sistema lo que hay especificado en el Gemfile
usamos Bundler, un programa para gestionar las dependencias de las gemas.
$ gem install bundler$ bundle install
Gemfile
es el equivalente en Ruby al fichero composer.json
de PHP. Además Bundler crea automáticamente el fichero Gemfile.lock
, análogo a composer.lock
, donde se registran las versiones exactas de las gemas que se han instalado.
Inicializamos la configuración de Capistrano.
$ bundle exec cap install
Esto crea la siguiente estructura en el directorio raíz de nuestro proyecto.
├── Capfile├── config│ ├── deploy│ │ ├── production.rb│ │ └── staging.rb│ └── deploy.rb└── lib └── capistrano └── tasks
Capfile
define la lista de módulos de Capistrano que se usarán en el proyecto.config/deploy.rb
contiene la configuración global de despliegue para este proyecto.config/deploy/production.rb
y config/deploy/staging.rb
contienen configuración específica para esos entornos. Podemos definir todos los entornos que deseemos.lib/capistrano/tasks
se puede crear ficheros .rake
con tareas personalizadas.En el fichero Capfile
, añadimos la siguiente línea al final de los require
para cargar el módulo de Symfony.
require 'capistrano/symfony' |
Ya tenemos listo Capistrano para funcionar con Symfony, a falta de configurarlo para nuestro proyecto.
El fichero deploy.rb
tendrá un contenido similar a lo siguiente:
set :application, 'capistrano-symfony-example' |
:application
: Nombre de la aplicación.:deploy_to
: Directorio al que se desplegará la aplicación en el servidor. Por defecto es /var/www/<nombre-de-aplicación>
.:repo_url
: URL del repositorio de código de nuestro proyecto.:scm
: Tipo de sistema de control de versiones usado. Por defecto es :git
.:branch
: Rama del repositorio a desplegar en el servidor. Por defecto es master
.:linked_files
: Los ficheros serán enlazados simbólicamente en el directorio de la release durante el despliegue. Útil para crear ficheros de configuración persistentes.:linked_dirs
: Exactamente igual a :linked_files
pero para directorios.:keep_releases
: Número de releases que se mantendrán en el servidor para poder efectuar un rollback a cualquiera de ellas.Estas son solo algunas de las variables que podemos utilizar, consulta el resto en la documentación de Capistrano.
:symfony_directory_structure
: Hay que establecer un 2
o un 3
dependiendo de la versión de Symfony que use nuestro proyecto.:sensio_distribution_version
: Solo es necesario establecerlo en proyectos de Symfony 2 que usen una versión de SensioDistributionBundle menor a la 5.Aunque con establecer estas variables en principio es suficiente, para proyectos de Symfony con estructuras poco convencionales disponemos de variables para un mayor control.
Un escenario común suele ser que el usuario que corre el servidor web y el usuario con el que se reliza el deploy sean distintos, y ambos necesitan tener acceso de lectura/escritura a ciertos directorios de Symfony. En este caso hay que establecer las siguientes variables.
:permission_method
: Método para cambiar los permisos. Puede ser :chmod
, :acl
o :chgrp
.:file_permissions_users
: Usuario que ejecuta el servidor web. Suele ser www-data
en distribuciones basadas en Debian.:file_permissions_paths
: Directorios del proyecto que requieren cambiar los permisos.En los ficheros que hay en config/deploy
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.
server 'miserver.com', user: 'miuser', roles: %w{web} |
Para proyectos complejos que necesitan distintos tipos de servidores (servidor de base de datos, servidor web…), Capistrano introduce el concepto de roles para etiquetar cada servidor y controlar las tareas que se ejecutan en él. En este post no vamos a adentrarnos en su uso.
Dado que el directorio current
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 /var/www/my_app_name/current/web
.
Si nuestro servidor web es Apache hay que editar la directiva DocumentRoot del Virtual Host. En caso de usar Nginx, la directiva se llama root.
Hay una cosa que Capistrano no puede hacer automáticamente, y es crear el fichero parameters.yml que necesita Symfony con la configuración del entorno producción. Por ello, antes de hacer deploy por primera vez necesitamos crearlo en la ruta /var/www/my_app_name/shared/app/config
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).
Una vez todo configurado, podemos realizar el despliegue a producción con el comando:
$ bundle exec cap production deploy
Para desplegar en un entorno distinto solo tenemos que cambiar production
por otro que tengamos definido.
A parte de deploy
Capistrano dispone de otros comandos que pueden resultarnos útiles. Podemos ver el listado completo ejecutando:
$ bundle exec cap -T
A través de Capistrano se pueden enviar comandos a la consola de Symfony del servidor con el formato bundle exec entorno cap symfony:console[comando,parámetros,rol]
. Por ejemplo para crear el esquema de la Base de Datos en producción lanzamos:
$ bundle exec cap production symfony:console[doctrine:schema:create]
]]>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).
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 Ionic ready en Debian o distribuciones basadas en Debian (Ubuntu, Linux Mint, ElementaryOS…).
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.
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - |
Bajo el capó, Ionic utiliza Apache Cordova 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.
sudo npm install -g cordova ionic |
Para comprobar que todo está correcto podemos ejecutar el comando ionic info
y mostrará algo parecido a esto.
Your system information: |
Instalamos la última versión de OpenJDK disponible para nuestro sistema. En mi caso es OpenJDK 7.
sudo apt-get install openjdk-7-jdk |
En la web de Android Studio se pueden descargar las herramientas SDK sin necesidad de instalar toda la suite. Descargamos el paquete android-sdk_r24.4.1-linux.tgz
y lo descomprimimos en nuestra home.
tar -xzvf android-sdk_r24.4.1-linux.tgz -C "$HOME" |
Si nuestro sistema es de 64 bits (lo podemos comprobar escribiendo en el terminal uname -m
), además vamos a necesitar instalar algunas bibliotecas de 32 bits.
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 lib32stdc++6 |
Para que Cordova sepa donde se encuentra instalado el SDK de Android es necesario establecer la variable de entorno ANDROID_HOME
con la ruta donde lo hemos descomprimido.
echo 'export ANDROID_HOME=$HOME/android-sdk-linux' >> ~/.bash_profile |
También conviene añadir las herramientas del SDK de Android al PATH
.
echo 'export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools' >> ~/.bash_profile |
Al añadir todo esto al fichero .bash_profile
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.
source ~/.bash_profile |
Lanzamos la aplicación Android SDK Manager con el comando android
e instalamos los siguientes paquetes:
Para ver que hemos instalado todo como es debido, vamos a crear una App de prueba y generar un fichero apk
de Android a partir de ella.
ionic start test |
Veremos el log de la compilación y al final el mensaje BUILD SUCCESSFUL y la ruta donde se ha generado el apk
.
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.
A partir de ahora, desplegar la aplicación en nuestro dispositivo móvil es tan sencillo como ejecutar el siguiente comando.
ionic run android --device |
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.
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.
Estamos desarrollando varios proyectos en paralelo que tienen dependencias que entran en conflicto entre sí.
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.
La solución a estos problemas es utilizar máquinas virtuales. Así, podemos aislar el entorno de pruebas del entorno de trabajo y, además, compartirlo entre los miembros del equipo de desarrollo.
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.
Vagrant es una aplicación escrita en Ruby que facilita considerablemente la creación de entornos virtuales de desarrollo. 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 Chef, Puppet o incluso los clásicos scripts de shell.
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.
Descargamos la última versión de Vagrant disponible para nuestra plataforma y la instalamos en nuestro sistema.
Descargamos y ejecutamos el instalador adecuado para nuestra plataforma de la página de descargas de VirtualBox. En algunas distribuciones de GNU/Linux podemos añadir a nuestras fuentes su repositorio de paquetes.
Inicializamos la configuración partiendo de una imagen de base.
$ vagrant init precise32 http://files.vagrantup.com/precise32.box
Lanzamos la VM.
$ vagrant up
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 vagrant ssh
y, una vez hemos terminado de usarla, eliminarla con vagrant destroy
.
El comando vagrant init
crea un fichero Vagrantfile
en el directorio donde lo hemos ejecutado que contiene la configuración de la máquina virtual. Estando en ese directorio, con vagrant up
podemos volver a levantar la máquina sin necesidad de hacer de nuevo el init
.
En Vagrant una box
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.
Antes hemos mostrado cómo crear una máquina virtual con Ubuntu, pero no estamos limitados a este sistema. En la página vagrantbox.es 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 boxes
utilizando Veewee.
vagrant init [box-name] [box-url]
Inicializa el fichero de configuración Vagrantfile
en el directorio actual. Si se pasan el segundo y el tercer parámetro, se establecen el nombre y la box
a utilizar en la configuración.
vagrant up
Levanta la máquina virtual de acuerdo a la configuración del Vagrantfile
del directorio actual.
vagrant halt
Detiene la máquina virtual, pero mantiene los cambios que hayamos hecho en ella para la siguiente vez que ejecutemos vagrant up
.
vagrant reload
Equivale a hacer un vagrant halt
seguido de un vagrant up
. Tras hacer cambios en un Vagrantfile
es necesario hacer reload
.
vagrant suspend
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.
vagrant resume
Resume una máquina que ha sido anteriormente suspendida con vagrant suspend
.
vagrant destroy
Detiene la máquina virtual y destruye todos los cambios que podamos haber hecho. La siguiente vez que hagamos un vagrant up
partirá de una imagen totalmente limpia.
vagrant ssh
Nos conecta por SSH a la máquina virtual en ejecución.
vagrant status
Muestra el estado de las máquinas levantadas con Vagrant.
vagrant box
Comando para gestionar las boxes
que tenemos en nuestro sistema.
vagrant package
Exporta la máquina virtual en ejecución en un fichero box
que puede ser reutilizado.
El fichero Vagrantfile
contiene el tipo de máquina virtual y su configuración. Por defecto, tras hacer vagrant init
, la configuración solo incluye el nombre de la box
que va a usar y su URL. Pero con unas pocas opciones podemos configurar la máquina según nuestras necesidades:
Vagrant.configure("2") do |config| |
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 documentación de Vagrant.
VirtualBox: Es el proveedor de virtualización por defecto de Vagrant.
VMWare: Se recomienda en caso de usar Vagrant para crear arquitecturas en producción, ya que tiene mejor rendimiento que VirtualBox. Es necesario adquirir la licencia para usarlo.
AWS: Existe un plugin no oficial de Vagrant, vagrant-aws, que permite desplegar nuestro entorno en la nube de Amazon.
Otros proveedores: Vagrant se puede extender mediante plugins escritos en Ruby, por lo que podríamos crear nuestro propio proveedor personalizado.
La mayoría de las veces la box
que utilicemos vendrá con poco más que el SO instalado. Podremos acceder a la máquina con vagrant ssh
e instalar a mano el software que necesitemos. Pero mejor que eso es utilizar los provisioners de Vagrant que automatizan el proceso de instalar y configurar el software. Disponemos de varias alternativas:
Shell: La forma más simple de aprovisionar la máquina virtual es definir un script de shell que se lanzará al realizar vagrant up
.
Ansible: Ansible es un framework de automatización que se sirve de configuraciones escritas en documentos YAML para orquestar los despliegues.
Chef Client: Chef 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 recetas, se escriben en un DSL sobre Ruby.
Chef Solo: Chef Solo es una variante de Chef que no necesita el nodo servidor para funcionar. Todas las recetas que utilicemos deben residir en el disco.
Puppet Agent: Puppet 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 DSL propio de Puppet.
Puppet Apply: Es el equivalente a Chef Solo para Puppet. No requiere del Puppet Master para funcionar.