jueves, 26 de febrero de 2015

Laravel 5 con vagrant en ubuntu

Las siguientes instrucciones fueron probadas y funcionan para Ubuntu 14.10.

Recientemente inicié a trabajar en un sitio web que usará Laravel 5 y decidimos usar vagrant para hacer el proceso de creación y configuración de nuestros ambientes de trabajo locales algo más simples.

A continuación les dejo las herramientas que estaremos utilizando:

Laravel: su eslogan lo dice todo "The PHP Framework For Web Artisans" que se puede traducir mas o menos así: El marco de trabajo en PHP para los artesanos de la web. Laravel busca ser simple y robusto, pero orientado a objetos, utiliza composer para manejo de las dependencias lo que le permite reutilizar código de otros proyectos (en especial symfony).

Vagrant: es una herramienta que permite crear ambientes de trabajo simples de configurar, reproducibles y portátiles, que emplean tecnología estándar y que son controlados en un flujo de trabajo único y constante, para ayudar a maximizar la productividad y flexibilidad de su equipo de trabajo. Por ejemplo: al iniciar un proyecto, en lugar de hacer circular un documento con los pasos que todos los desarrolladores tienen que seguir para hacer que la aplicación funcione en su máquinas (ambiente local), les pasamos una máquina virtual ya configurada y lista para usar, la principal ventaja de esto, aparte de facilitar el trabajo, es que todo el mundo tiene la misma configuración y no importa cuantos nuevos miembros se unan al equipo, todos usaran las mismas herramientas. Cabe mencionar que incluso podemos jugar con las configuraciones del servidor creando máquinas virtuales adicionales

VirtualBox: es un programa (software) de virtualización, es decir que nos permite crear máquinas virtuales a las cuales les asignamos recursos del sistema físico (nuestro computador). Vagrant usará virtualbox como proveedor para ejecutar las máquinas virtuales.

Composer: es un manejador de dependencias para PHP.

Requerimientos

Debemos tener instalado todo lo que sigue, los pormenores de cada programa pueden ser encontrados en el sitio web respectivo, por lo que no entraremos en detalles:

  1. composer, de preferencia globalmente, ver detalles
  2. virtualbox 4.3.22, que se puede descargar desde aquí
  3. vagrant 1.7.2, que se puede descargar desde aquí

Crear un proyecto de pruebas:

Como mencioné antes, vamos a usar Laravel, por lo que ahora crearemos un proyecto nuevo, usaré composer para esto pero existe una alternativa:

cd ~/Projects
composer create-project laravel/laravel my-project --prefer-dist


La salida del comando anterior debería ser algo como lo siguiente (texto acortado por brevedad):
Installing laravel/laravel (v5.0.1)
  - Installing laravel/laravel (v5.0.1)
    Downloading: 100%         

Created project in my-project
Loading composer repositories with package information
Installing dependencies (including require-dev)
...
Writing lock file
Generating autoload files
Generating optimized class loader
Compiling common classes
Compiling views
Application key [********MySuperSecretKey*********] set successfully.

Instalar y configurar laravel/homestead

Laravel Homestead es una "caja" oficial de Vagrant (Vagrant box), pre-empacada y lista para usar en tu ambiente local. No hay que preocuparse con dañar algo, pues si algo sale mal podemos ¡destruir y recrear el ambiente de desarrollo en minutos!

El siguiente comando descargará la caja laravel/homestead, esto puede tardar algún tiempo:

vagrant box add laravel/homestead

Instalamos homestead en nuestro sistema globalmente:
composer global require "laravel/homestead=~2.0"

Inicializamos los archivos de configuración de homestead:
homestead init

Editamos el contenido del archivo ~/.homestead/Homestead.yml
homestead edit

Para más detalles sobre las configuraciones pueden consultar aquí
Aquí dejo un ejemplo de mi configuración para my-project en el archivo ~/.homestead/Homestead.yml:
---
ip: "192.168.10.10"
memory: 4096
cpus: 1

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Projects/
      to: /home/vagrant/Projects

sites:
    - map: myproject.app
      to: /home/vagrant/Projects/myproject/public

databases:
    - homestead

variables:
    - key: APP_ENV
      value: local

# blackfire:
#     - id: foo
#       token: bar
Vale la pena mencionar que el archivo Homestead.yml es global así que al añadir nuevos proyectos, se debe modificar ya sea para agregar dichos proyectos o reemplazar los anteriores

Antes de poder acceder a nuestra máquina virtual tenemos que modificar el archivo hosts, para añadir una línea (192.168.10.10 myproject.app)y que nuestro sistema operativo sepa la forma de resolver el dominio myproject.app a una dirección ip, esto normalmente se haría en un servidor de nombres DNS, pero para nuestro ambiente local no hace falta.
sudo nano /etc/hosts

A continuación un ejemplo de mi archivo /etc/hosts:
127.0.0.1        localhost
127.0.0.1        myhost

192.168.10.10    myproject.app

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
Ahora lo que resta es ir al directorio donde está instalado Homestead y ejecutar vagrant up:
cd ~/.composer/vendor/laravel/homestead/
vagrant up


Asumiendo que todo a salido bien, la máquina virtual con su aplicación debería estar funcionando y debemos poder acceder en nuestro navegador preferido a la dirección http://myproject.app, sino pueden revisar la sección de problemas conocidos
.

Problemas conocidos:

  • He escuchado comentarios de las versiones de Vagrant (1.7.2) y VirtualBox (4.3.22) afectan en gran medida, por lo que es recomendable mantener ambos actualizados
  • En Ubuntu, tuve el problema de que algunos módulos del kernel no cargan correctamente, la solución, editar el archivo /etc/modules y añadir los módulos siguientes uno por línea: vboxdrv, vboxnetadp y vboxnetflt, por ejemplo:
    #virtual box module
    vboxdrv
    vboxnetadp
    vboxnetflt
    

    Además para no tener que reiniciar cargamos los módulos mencionados:
    sudo service vbxdrv start
    sudo modprove vboxnetadp
    sudo modprobe vboxnetflt
    

domingo, 7 de diciembre de 2014

Instalar y actualizar ack-grep en ubuntu (dpkg-divert)

Hace poco actualicé Ubuntu a la versión 14.10 en mi laptop y traté de actualizar ack-grep pero este proceso siempre fallaba con el siguiente error:

package ack-grep 2.12-1 failed to install/upgrade: trying to overwrite 
`/usr/bin/ack', which is the diverted version of `/usr/bin/ack-grep'


Después de investigar un poco recordé la guía oficial de instalación de ack-grep recomienda renombrar el paquete posterior a su instalación para que sea posible llamar dicho programa simplemente escribiendo ack en lugar de ack-grep, lo que la guía no dice es que esto causará problemas al tratar de actualizar el paquete, al menos es lo que me pasó después de actualizar Ubuntu.

Instalar ack (guía oficial)

Esta es la forma recomendada de instalar ack-grep en Ubuntu (http://beyondgrep.com/install/):

Primero necesitamos instalar el paquete:

sudo apt-get install ack-grep 


Y luego, por conveniencia, renombramos el paquete instalado:

sudo dpkg-divert --local --divert /usr/bin/ack --rename --add /usr/bin/ack-grep 


Este comando causa que el paquete sea renombrado localmente y si se ejecuta sin problemas están listos para usar ack

Acerca de dkpg-divert


dpkg-divert crea una "desviación", en este caso local, que cambia el nombre de ack-grep por ack, si ejecutan el siguiente comando:

dpkg-divert --list |grep ack


verán algo como lo siguiente:

desviación local de /usr/bin/ack-grep a /usr/bin/ack


si quieren eliminar dicha desviación puede usar:

sudo dpkg-divert --remove /usr/bin/ack-grep


y deberían ver el siguiente resultado si todo sale bien:

Eliminando `desviación local de /usr/bin/ack-grep a /usr/bin/ack'


Instalar ack (mi recomendación)

El principal problema con la guía oficial es que no dice nada sobre remover la desviación y los posibles problemas que puedes encontrar, y lo cierto es que prefiero usar "ack" antes que "ack-grep" así que usaré un alias.

La instalación ack-grep es igual:

sudo apt-get install ack-grep 


Ahora vamos a crear un alias y para esto editamos el archivo de configuración de nuestra consola de comandos, por defecto en Ubuntu sería ~/.bashrc

nano ~/.bashrc


y añadimos un línea como la siguiente al final:

alias ack='ack-grep'


Para que el cambio sea visible hay que recargar la terminal, lo cual vuelve a leer el archivo ~/.bashrc, por lo general lo más simple sería cerrar la ventana del emulador de terminal o podemos ejecutar:

exec $SHELL


Y luego debemos poder ejecutar ack de forma normal.


Conclusión

Aunque la guía oficial ofrece una forma simple de hacer que el comando ack esté disponible para todos, crear una desviación local puede causar problemas y a menos que sepamos la forma de usar dpkg-divert podríamos terminar con un paquete roto en nuestro sistema.
Mi solución tiene la ventaja de que no afecta futuras actualizaciones y aunque el ejemplo solo afecta la cuenta de un usuario, solo haría falta actualizar el archivo /etc/bash.bashrc (o el equivalente para el shell que esten usando) para hacer este alias accesible a todos los usuarios; cabe resaltar que para mi solución ack está disponible para todos los usuarios si invocan al comando ack-grep sin necesidad de crear un alias.

lunes, 15 de septiembre de 2014

evironment specific wordpress configuration

Everyone who has ever setup Wordpress knows the wp - config.php file and all settings that you can define there, this works fine to configure your wordpress instalation on any given environment but there are times when we have to work on different environments or stages as your applications is developed, tested and installed on production.

I have worked on companies that have one local environment per developer, then one for QA(quality assurance), another for staging and finally other one for production, in some cases there is a development environment where all development code is merged so developers can test their changes with what others have done, there is not a right answer here but one thing is for sure you don 't have the same settings on each of those environments and you don' t want to, here are some reason why that is the case :

  1. your local working copy: you want to be able to do just anything and you don 't care about database access rights so is usual to setup for example mysql root account without password.
  2. staging environment: you want to configure your database and the settings of your application to be as close as production as possible but this environment is accessible to a lot of people like: QA, software architects,  system administrators and perhaps even developers so you want to keep things simple and share easy to remember passwords with those who need them.
  3. production: this is the place that you want to keep protected, very specific user access rights, security policies, strong passwords, and so on. Maybe only certain sys admins whose are trust worthy can access here and see the application event log and change/install/update any required software.

With all of that being said here a simple example of a possible configuration of database users and privileges using MySQL 5.5.x, see here for a complete list of all supported Privileges and how to grant them.





environment user name permissions
local root ALL
staging root ALL
staging qa CREATE, DROP, SELECT, INSERT, UPDATE, DELETE
production root ALL
production app_user SELECT, INSERT, UPDATE, DELETE


Now let's say that you want to use root on your local without password, on staging you want to configure qa and use app_user for production.

Here is an example of your wp-config.php file for production, is very likely that you will just provide an example with place holders, then a sys admin will replace with actual values and deploy the final file to production environment.


Now the questions is: how do we allow different settings on staging and local environments? some people will just edit the config file to adjust it for every environment however this is very dangerous because you could end up overwriting one or more of those files and if you do override production your site will not work.

My suggestion/solution
inspired on this wordpress plugin I got the idea of defining an stage constant and then use that constant to load an environment specific configs file, another way could be just checking if an environment specific file existed but I think using a constant is better.

So we need to update our wp-config.php file making sure that it contains the WP_STAGE constant and that this is used to load the right configs file, here is how it looks like:


And this is how the wp-config-local.php looks like:

As you can see if you define some value for WP_STAGE constant and you create a file named like: wp-config-{WP_STAGE}.php the original (production settings in this case) will be ignored and your stage specific settings are loaded instead.

You may use local settings as default and create an specific version for production and staging. In my example I am loading and external file OR what is defined on wp-config.php so If something is required in many environments I will have to redefine it as many times as it is required, you could "move" this common setting to wp-config.php outside of the if block. In the worst case scenario if by accident you upload any of your environment/stage specific configs to production it will not be used unless your WP_STAGE constant is also changed and your production files are not going to get overwritten.