lunes, 28 de octubre de 2013

Nginx: 413 Request Entity Too Large

Estaba yo todo "juicioso" trabajando como siempre cuando de repente me dicen: "La aplicación está dando un problema!!!" y bueno, quienes me conocen, saben que nunca me equivoco por lo que debía existir un error en el servidor.

Haciendo el respectivo "debug" me encontré conque Nginx estaba botando el siguiente error: 413 Request Entity Too Large.

La aplicación permite subir fotos y estaban intentando subir una foto de más de 2MB de tamaño.

Resulta que Nginx está configurado por defecto para permitir un tamaño de mensaje de máximo 2MB por lo que procedí a hacer el siguiente cambio:

En el archivo /etc/nginx/nginx.conf (el path puede cambiar de acuerdo al S.O y forma de instalación) agregué la siguiente linea:

client_max_body_size 5M;

luego recargué Nginx y listo.

/etc/init.d/nginx reload

lunes, 14 de octubre de 2013

¿Cómo eliminar múltiples archivos de un repositorio git?

Estaba en la tarea de actualizar la version de Sencha Touch en un proyecto en el que estoy trabajando corriendo el muy conocido comando

sencha app upgrade /path/a/la/nueva/version

y pues al hacer las respectivas pruebas y arreglos, me puse en la tarea de actualizar el repositorio, por lo que, corrí el otro muy conocido commando

git status

Y oh sorpresa, existían muchos pero muchos archivos en diferentes carpetas que debían ser eliminados del repositorio, junto con muchos que debían ser agregados (al haber sido modificados y/o creados).

Para agregar los nuevos el siguiente commando hace el milagro

git add /path/

Pero para borrar no puedo usar simplemente

git rm .

dado que borraría TODOS los archivos.

¿Y el recontra conocido git -a o git -u?

Pues serviría siempre y cuando quieras subir TODOS tus cambios (y a veces no quieres hacer eso)

Entonces, ¿cuál es la solución?

Facilísimo:

git ls-files --deleted -z | xargs -0 git rm

Y bueno expliquemos un poco:

git ls-files: lista archivos del indice de git
--deleted: solo muestra los archivos eliminados
-z: pone \0 (el conocido NUL) como terminador del string (util si el path tiene espacios)
|: concatena la salida del primer commando con el siguiente
xargs: permite concatenar argumentos y pasarlos a un comando (en este caso git rm)
-0: utiliza \0 como character de separación (por esto usamos -z en git ls-files)

martes, 8 de octubre de 2013

¿Cómo configurar Nginx para que utilice autenticación HTTP?

Estaba haciendo una migración de servidores y decidí cambiar Apache por Nginx, todo resultó bastante "sencillo", pero ¡oh sorpresa! uno de los sitios web necesita autenticación HTTP para funcionar como se espera.

Y bueno, caí en cuenta de que no tenía idea de como hacerlo por lo que luego de una pequeña búsqueda en google investigación pues encontré estos pasos:

1. Para poder generar el password cifrado utilicé Apache Utils por lo que ejecuté:
sudo apt-get install apache2-utils

2. Crear el usuario y el password
sudo htpasswd -c /path/donde/mantener/el/archivo/.htpasswd el_nombre_de_usuario

Pedirá el password:
New password:
Re-type new password:
Adding password for user el_nombre_de_usuario

3. Actualizar el archivo de configuración de Nginx
sudo vi /etc/nginx/sites/available/el_archivo_de_configuracion_del_sitio_web

En este archivo, en la sección location se debe agregar lo siguiente:

auth_basic "Restricted";
auth_basic_user_file /path/donde/mantener/el/archivo/.htpasswd;

Ejemplo:

server {
  listen      numero_de_puerto;
  server_name el_dominio.com;
  location / {
    root                 /el/path/a/la/raiz/del/sitio;
    auth_basic           "Restricted";
    auth_basic_user_file /el/path/al/archivo/.htpasswd;
}

4. Luego simplemente recargamos Nginx y listo:

sudo /etc/init.d/nginx

martes, 30 de octubre de 2012

Sencha Touch con PhoneGap

Pues bueno, estaba yo todo juicioso haciendo mi trabajo como todos los días cuando me hicieron el siguiente requerimiento:

Necesitamos una aplicación para iPhone que haga tal y cual cosa, necesitamos que uses Sencha Touch y PhoneGap.

Ya PhoneGap lo he utilizado en un par de proyectos y ya me conozco las mañas para usarlo, pero Sensa Touch no lo había usado por lo que me puse a investigar un poco del asunto, en el mismo sitio web de Sensa existe un tutorial de cómo unir ambos productos pero... El tutorial fue realizado el 28 de enero de 2011 y actualizado el 7 de Octubre del mismo año y las versiones tanto de Sensa Touch como de PhoneGap han cambiado y mucho!!! así que me puse a leer un poco más de cómo carajos hacer la integración y en este post espero ayudar a los que esten en el mismo dilema que yo.

Paso 1
Descarga las últimas versiones de lo que se necesita e instalalo:

Paso 2
Abre un terminal y ve a donde hayas copiado el Sansa Touch y ejecuta
sencha app create nombre_de_app /path/de/la/app all

Paso 3
Copia el archivo js de PhoneGap en la carpeta de la applicación que acabas de crear
cp CordovaLib-2.1.0/bin/templates/project/www/cordova-2.1.0.js /path/de/la/app/

Paso 4
Indicale a Sencha Touch que debe usar el archivo js de PhoneGap, para lo cual abre el archivo app.json y agrega en el apartado de js el path al archivo.
"js": [
    {
       "path": "cordova-2.1.0.js"
    }
    ...
  ]

Paso 5
Abre un terminal y ve a donde hayas copiado PhoneGap y crea una aplicación, y ubicala dentro de la carpeta build de la aplicación Sencha Touch
./create /path/de/la/app/build/phonegap el.nombre.de.la.app NombreApp

Paso 6
Elimina el contenido de la carpeta www de la aplicación de PhoneGap que acabas de crear

Paso 7
Modifica la aplicación de Sencha Touch para que compile en la carpeta www de la aplicación de PhoneGap, para lo cual edita el archivo app.json en la sección "buildPaths", debe quedar algo parecido a lo siguiente:
"buildPaths": {
    "testing": "build/testing",
    "production": "build/production",
    "package": "build/phonegap/www",
    "native": "build/native"
}

Paso 8
Empaqueta la aplicación sencha
sencha app build package

Paso 9
Abre el proyecto Xcode de la aplicación PhoneGap y ejecutalo.

Y voilà!!!


Espero que esta guia te haya ayudado.

viernes, 5 de octubre de 2012

Rails y Postgresql

Estaba todo juicioso creando una nueva aplicación rails con postgres

rails new AppName -d postgresql

Cuando de repente fui a crear la BDD

rails db:create

Y me apareció el siguiente mensaje:

FATAL: Peer authentication failed for user "el usuario"

Una rápida búsqueda me indicó que tenía que hacer un pequeño cambio en cómo se hace la autenticación de postgres para lo cual hice lo siguiente:

sudo vi /etc/postgresql/9.1/main/pg_hba.conf

Y cambié la linea:

local   all             postgres                              peer

Por

local   all             postgres                               md5

luego reinicié el server

sudo /etc/init.d/postgresql restart

Y listo, todo funcionó.

martes, 1 de mayo de 2012

Sun JDK 6 en Ubuntu 12.04 (Precise Pangolin)

Se supone que la forma más facil es a través de PPA pero al parecer por disposiciones legales en cualquier momento dejará de estar disponible este package por lo que la recomendación es instalarlo manualmente.
Y como se hace?
  1. Descargamos el jdk desde el sitio de Oracle.
  2. Le damos permisos de ejecución al archivo
    chmod +x jdk-6u32-linux-x64.bin
  3. Ejecutamos el archivo
    ./jdk-6u32-linux-x64.bin
  4. Lo movemos a la carpeta de maquinas virtuales java
    sudo mv jdk1.6.0_32 /usr/lib/jvm/
  5. Le indicamos al sistema donde puede encontrar los ejecutables de java
    sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_32/bin/javac 1
    sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_32/bin/java 1 
  6. Escogemos estos ejecutables como los usados por defecto
    sudo update-alternatives --config javac
    sudo update-alternatives --config java
  7. Verificamos que funcione
    java -version

miércoles, 18 de abril de 2012

Como utilizar spree en heroku

Spree es una plataforma de comercio electrónico, para más información presiona aqui. Heroku es una plataforma para aplicaciones en la nube.

Hasta ahi todo facil, resulta que spree en su configuración por defecto (de hecho está quemado en el código) solo permite grabar las imagenes de productos de forma local, pero en cambio heroku no permite guardar archivos en disco (el sistema de archivos para las aplicaciones es de solo lectura).

Entonces. ¿Cómo hago para usar mezcladas estas 2 plataformas?

Pues bueno, es fácil (relativamente), toca configurar la aplicación para que use algun servicio de hospedaje en la nube (en mi ejemplo usaré Amazon S3) y modificar un poco la gema de spree (sobreescribir los modelos que tengan attachments) y pues estos son los pasos:
Creamos una aplicación de ejemplo (en el momento de escribir esto spree solo funciona con rails 3.1 (desde 3.1.1 hasta 3.1.4)

rails new ejemplo_spree
cd ejemplo_spree

Crea la base de datos (como por defecto rails usa SqLite pues no toca configurar nada)

rake db:create

Instala la gema de spree
 
gem install spree

Instala spree en tu aplicación

spree install --auto_accept

Hasta aquí, spree debería estar funcionando por lo que levanta el server para la app y verifica (http://localhost:3000)

rails s

Bueno, ahora como hacer que la aplicación funcione en heroku?

Crea un initializer y pon el siguiente código:

Spree::Image.class_eval do
    definition = self.attachment_definitions[:attachment]
    definition.delete :url
    definition[:path] = definition[:path].gsub(':rails_root/public/', '')
    definition[:storage] = 's3'
    definition[:bucket] = ENV['S3_BUCKET']
    definition[:s3_credentials] = {:access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET']}
  end

  Spree::Taxon.class_eval do
    definition = self.attachment_definitions[:icon]
    definition.delete :url
    definition[:path] = definition[:path].gsub(':rails_root/public/', '')
    definition[:storage] = 's3'
    definition[:bucket] = ENV['S3_BUCKET']
    definition[:s3_credentials] = {:access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET']}
  end

Lo hice separado para cada modelo para tratar de hacerlo más entendible pero no te olvides de usar DRY.

Aqui viene la primera inquietud (supongo): ¿y esas variables de ambiente ENV[xxx] como las seteo en heroku? pues bueno dentro de unas cuantas líneas responderé esa inquietud

Ahora toca agregar a la aplicación las gemas para Amazon S3 por lo que edita el Gemfile y agrega:

gem 'aws-s3'
gem 'aws-sdk'

instalamos las gemas

bundle install

Heroku utiliza git como repositorio para el código por lo que hacemos un repositorio para nuestra applicación y la creamos en heroku:

git init
git add .
git commit -m "Primer commit"
heroku create ejemplo_spree
git push heroku master

Al ser un proceso interactivo la creación de los datos iniciales de spree, la forma más facil de replicarlos en heroku es copiando los datos locales:

gem install tap
heroku db:push
heroku restart

Configuramos las variables de ambiente en heroku:

heroku config:add S3_KEY=el_key S3_SECRET=el_password S3_BUCKET=el_bucket

Habilitamos a heroku para que use sendgrid para enviar correos:

heroku addons:add sendgrid:starter

hasta ahi, la aplicacion deberia funcionar.

Ahora el problema es que las imágenes de las migraciones fueron creadas localmente, como las veo desde mi aplicación en heroku?

Sube las imagenes ubicadas en root_app/public/spree a tu cuenta de amazon en el bucket asignado para la aplicación y listo.

Y bueno eso es todo. Ahora deberias tener una aplicación usando spreed y que funcione en heroku.