Subiendo imagenes en Heroku--Guardandolas usando AWS S3 y la Gema Fog

Por:, en:

ES:This tutorial assumes you have already completed:

  1. Users' avatars

Ahora, nuestras imágenes se pueden cargar en nuestra aplicación. Sin embargo, cuando las implantamos en Heroku:

bash


    $ git add . #add changes to git
    $ git commit -m "image upload with paperclip" #commit changes
    $ git push # push changes to bitbucket
    $ git push heroku master # push changes to heroku
    $ git heroku run rake db:migrate #update heroku database

Si ahora intentas cargar las imágenes en tu sitio web de Heroku – funcionarán. Sin embargo, en el momento en que reinicies tu aplicación (lo que ocurre también cuando la actualizas):


    $ heroku restart

Verás que todas las imágenes han desaparecido. Esto es porque Heroku no permite el almacenamiento de archivos en sus servidores. Para lidiar con este problema, vamos a utilizar servicios externos para almacenar imágenes. En nuestro ejemplo, utilizaremos el servicio Amazon S3. En este tutorial cubriremos como:

  •  Crear una cuenta de Amazon S3 (se requiere una tarjeta de crédito - pero el costo es muy bajo)
  •  Añadir AWS-SDK y la gema Fog
  • Hacer que las imágenes funcionen en Heroku

Amazon S3 no es gratis pero si muy barato. Es tan barato, que ni lo notarás en tu factura. Apenas acabo de recibir mi primera factura de Amazon después de 3 meses y eran 3 centavos. Actualmente, Amazon ofrece uso gratuito de S3 por el primer año hasta 5GB. Aun así, tienes que usar una tarjeta de crédito para poder inscribirte. Un Consejo rápido para aquellos en Shanghái - escríbeme vía contact form y quizás pueda ayudarte directamente. O trata de hacer una búsqueda en Google sobre cómo hacerlo sin una tarjeta de crédito. Si encuentras algo de información, compártela con nosotros en los comentarios.

 

Paso 1: Crea una cuenta de Amazon S3

Dirígete a la página web AWS wesbite y registrarse si todavía no tienes una cuenta en Amazon. Si ya tienes una cuenta, simplemente inicia la sesión. Después de terminar ve a   AWS Management Console  y selecciona “S3.”

Tendrás que hacer clic a través de algunas cosas adicionales para confirmar que entiendes los términos etc.

Una vez que tengas tu configurada tu cuenta de S3, abre AWS management console y crea dos nuevos "buckets".

Nómbralos "rails-demo-production" y "rails-demo-dev." Si los nombres no están disponibles, utiliza otros nombres pero asegúrate de que uses los mismos nombres en tu aplicación.

ahora necesitamos nuestras credenciales de seguridad para acceder a buckets. Haz clic en "Security Credentials"

 

y clic en "Access Keys (Access Key ID and Secret Access Key)"

Deben de verse más o menos así:

  • Access Key: AKIAIRPKLJNSDO23425
  • Secret Access Key: 9LXV/GWagu/CJ4DoMLKSmdasdaZeUyuax/Ei92hL7

Asegúrate de mantener esta información segura. 

Paso 2: Añade AWS-SDK y la Gema Fog

Ahora, regresemos a nuestra aplicación y hagamos todos los cambios necesarios para poder subir las imágenes a S3.

Gemfile


    gem 'aws-sdk', '~> 1.36.1'
    gem 'fog'

y ahora agrupa las nuevas gemas:

bash


    $ bundle install

Paso 2.2: Modifica el archivo user.rb

Necesitamos decirle a nuestro modelo de usuario que utilice Fog para subir los archivos a S3. Tomaremos nuestra declaración original:

app/models/user.rb


has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" },
    :default_url => "/images/:style/missing.png"

y la modificaremos un poco:

app/models/user.rb


has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" },
    :default_url => "/images/:style/missing.png",
    :url  => ":s3_domain_url",
    :path => "public/avatars/:id/:style_:basename.:extension",
    :storage => :fog,
    :fog_credentials => {
        provider: 'AWS',
        aws_access_key_id: "AKIAIRPKLJNSDO23425",
        aws_secret_access_key: "9LXV/GWagu/CJ4DoMLKSmdasdaZeUyuax/Ei92hL7"
    },
    fog_directory: "rails-demo-env"

Paso 2.3: Añade la gema Figaro

No es la mejor idea mantener las variables de nuestro código sensibles dentro de nuestro código de fuente. Tenemos que mantenerlos en algún lugar seguro. Desde que existe Rails 4.1, podemos utilizar el archivo secrets.yml pero la verdad me parece un poco confuso y no es muy útil comparado con la gema Figaro. Figaro nos ayudará a administrar todos los secretos y actualizar las variables de heroku. Comencemos agregándolo a nuestro archivo gem:

Gemfile


    # existing code

    gem "figaro"

y agrupala:

bash


$ bundle install

Paso 2.4: Ejecuta la instalación 

Ahora tenemos que ejecutar la instalación que generara el archivo application.yml para nuestras variables:

bash


$ rails generate figaro:install

    create  config/application.yml
    append  .gitignore

Paso 2.5: Reemplaza las variables AWS

Este archivo no es rastreado por git ya que figaro automáticamente agrega a nuestro archivo .gitingore. Abramos el archivo y agreguemos nuestras variables:

config/aplication.yml


    # Add application configuration variables here, as shown below.
    #
    # PUSHER_APP_ID: "2954"
    # PUSHER_KEY: 7381a978f7dd7f9a1117
    # PUSHER_SECRET: abdc3b896a0ffb85d373
    # STRIPE_API_KEY: EdAvEPVEC3LuaTg5Q3z6WbDVqZlcBQ8Z
    # STRIPE_PUBLIC_KEY: pk_BRgD57O8fHja9HxduJUszhef6jCyS

Ahora podemos reemplazar esto con nuestras variables AWS:

config/aplication.yml


SECRET_KEY_BASE: 60949ad338a3c9a578350ae917bb74372a40a45e5d93c80addaa13d4bf57a62352c644e861c24ce8a5c61fc193f7dbbbf39aadff80e17285f5ac5bf6f0db8200
AWS_ACCES_KEY_ID: AKIAIRPKLJNSDO23425
AWS_SECRET_ACCESS_KEY: 9LXV/GWagu/CJ4DoMLKSmdasdaZeUyuax/Ei92hL7

development:
  FOG_DIRECTORY: rails-demo-dev
production:
  FOG_DIRECTORY: rails-demo-production

Paso 2.6: Reemplaza los valores Hardcoded

Ahora podemos reemplazar nuestros valores hardcoded con referencias a "environment variables handled by figaro

app/models/user.rb


has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" },
    :default_url => "/images/:style/missing.png",
    :url  => ":s3_domain_url",
    :path => "public/avatars/:id/:style_:basename.:extension",
    :storage => :fog,
    :fog_credentials => {
        provider: 'AWS',
        aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
        aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
    },
    fog_directory: ENV["FOG_DIRECTORY"]

Paso 2.7: Añade la contraseña y el inicio de Sesión en tu Aplicación 

También podemos mover aquí nuestro “login” y “password” que hemos usado antes para enviar e-mails a nuestros archivos de environments configuration:

config/environments/development.rb


config.action_mailer.smtp_settings = {
    address: "smtp.gmail.com",
    port: 587,
    authentication: "plain",
    enable_starttls_auto: true,
    user_name: ENV["EMAIL_LOGIN"],
    password: ENV["EMAIL_PASSWORD"]
}

config/environments/production.rb


config.action_mailer.smtp_settings = {
    address: "smtp.gmail.com",
    port: 587,
    authentication: "plain",
    enable_starttls_auto: true,
    user_name: ENV["EMAIL_LOGIN"],
    password: ENV["EMAIL_PASSWORD"]
}

y añade la contraseña y accede a nuestro archivo application.yml:

config/application.yml


SECRET_KEY_BASE: 60949ad338a3c9a578350ae917bb74372a40a45e5d93c80addaa13d4bf57a62352c644e861c24ce8a5c61fc193f7dbbbf39aadff80e17285f5ac5bf6f0db8200
AWS_ACCES_KEY_ID: AKIAIRPKLJNSDO23425
AWS_SECRET_ACCESS_KEY: 9LXV/GWagu/CJ4DoMLKSmdasdaZeUyuax/Ei92hL7
EMAIL_LOGIN: email@gmail.com
EMAIL_PASSWORD: passwordhere

development:
  FOG_DIRECTORY: rails-demo-dev
production:
  FOG_DIRECTORY: rails-demo-production

y actualiza el archivo secrets.yml:

config/secrets.yml


development:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

test:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>


Si estás ejecutando tu aplicación - este es el momento de reiniciarla. Si no está corriendo, empiezala.

Ahora puedes intentarlo. La aplicación comenzará a subir las imágenes a Amazon S3. Dependiendo de dónde vives, esto puede ser un proceso muy lento. No te preocupes aunque, una vez que desplegamos nuestra aplicación en heroku, esta será mucho más rápida.

Paso 3: Hacer que funcione en Heroku

Necesitamos una forma de ofrecer nuestros códigos secretos a heroku sin compartirlas dentro de un código. Esto puede ser bastante complejo, pero con Figaro configurar en Heroku es muy facil. Simplemente ejecuta rake task en tu aplicación:

bash


$ rake figaro:heroku

En caso de que esto no funcione, (y si vives en China todo es posible), siempre puedes enviar las variables manualmente:

bash


    $ heroku config:set SECRET_KEY_BASE='1fe51548304cc75187d202dff0bd17a16999b815b1c326382afd2bf8a4323493f04a2a7c63485c022b724f05911170a65ad72ab30be87f40de8be937eaa8f6e2'
    $ heroku config:set AWS_ACCESS_KEY='AKIAIRPKLJNSDO23425'
    $ heroku config:set AWS_SECRET_ACCESS_KEY='9LXV/GWagu/CJ4DoMLKSmdasdaZeUyuax/Ei92hL7'
    $ heroku config:set FOG_DIRECTORY='rails-demo-production'
    $ heroku config:set EMAIL_LOGIN='you@gmail.com'
    $ heroku config:set EMAIL_PASSWORD='yourpassword'

Asegúrate de utilizar los valores correctos.

Paso 3.2: Ajuste Final en el archivo de production.rb 

Estamos casi listos para empujar al repositorio remoto y el servidor. Pero primero, vamos a hacer algunos ajustes finales. De forma predeterminada nuestra producción no permitirá acceder al directorio público desde el navegador. Para cambiar el comportamiento, necesitamos cambiar una línea en  config/environments/production.rb

config/environments/production.rb


config.serve_static_assets = true

Ya estamos listos.

bash


    $ git add .
    $ git commit -m "AWS and Fog added for user avatars"
    $ git push
    $ git push heroku master
 

Si tu Inicio de sesión serás capaz de marcar esto tutorial Como vas avanzando tu progreso



Comentarios

  • en: Brunitob escribió:

    I have a questios, where do you get:

    SECRET_KEY_BASE: 60949ad338a3c9a578350ae917bb74372a40a45e5d93c80addaa13d4bf57a62352c644e861c24ce8a5c61fc193f7dbbbf39aadff80e17285f5ac5bf6f0db8200
    
  • en: Andrew Hamilton escribió:

    run ' $: rake secret ' in your terminal to generate a key. ( http://edgeguides.rubyonrails.org/41release_notes.html#config-secrets-yml)

  • en: Anchieta Junior escribió:

    Just in case someone has a problem with that, the new comand to run Figaro Gem installation is just "figaro install" and it's no longer "rails generate figaro:install".

  • en: Andrew Hamilton escribió:

    Also worth noting that the rake task for Figaro setting up on Heroku is now ' $: figaro heroku:set -e production ' instead of ' $: rake figaro:heroku '. ( https://github.com/laserlemon/figaro#heroku-configuration )

  • en: Adam escribió:

    i'm having a problem uploading my avatar to S3. i get this error : ArgumentError in Devise::RegistrationsController#update Missing required arguments: awsaccesskey_id

    Extracted source (around line #244): unless missing.empty?

          raise ArgumentError, "Missing required arguments: #{missing.join(", ")}"
        end
        unless recognizes.empty?
    

    i followed every step in the tutorial and i updated my AWSACCESKEYID and AWSSECRETACCESSKEY.

    i think it's a fog gem problem. can someone help me please, i'm stuck ! thank you.

  • en: clement escribió:

    I had the same problem, and I dont really understand why, but wrapping the ENV["AWSACCESSKEYID"] in strings (replacing by : "#{ENV["AWSACCESSKEYID"]}") did it.

Comentar

Tú puedes Inicio de sesión Comentar