S3

S3 es el servicio que usamos en staging y producción para el almacenamiento de archivos. La gema Shrine se encarga de la comunicación entre S3 y nuestra app Rails.

Inicio de un proyecto

Típicamente al principio de un proyecto no necesitamos subir archivos. Si tratamos de deployar con la configuración tal cuál viene de Potassium probablemente se caiga debido a que no tenemos las variables de ambiente correspondientes. Una solución temporal a esto es comentar la sección de la configuración de shrine en shrine.rb para producción y hacer que production tenga la misma configuración que development. Con esto no funcionarían la subida de archivos en Heroku hasta que se configure un bucket S3 y se devuelva la configuración de shrine a su estado anterior.

Asociando un bucket de S3

Cuando llega el momento de usar manejo de archivos en nuestra aplicación, vamos a necesitar asociar un bucket a nuestro staging y producción. Heroku nos da una forma fácil de hacerlo con el addon Bucketeer. Al provisionarlo en nuestra app se nos generarán unas variables de ambiente con el prefijo BUCKETEER_, se deben usar los valores de estas variables, pero las keys deben ser las mismas que se usan en el shrine.rb y que están en el .env.development.

Hay que tener en cuenta que el addon de bucketeer no tiene un tier gratis, siendo 5 USD lo más barato. Hay que conversar esto con el SM y cliente, posiblemente se deba transferir la app a un team de ellos, como se menciona al final de la guía de Heroku.

Teniendo las variables correctamente definidas, ya se puede restaurar la configuración de Shrine para que use S3 en producción.

CORS

Con lo anterior ya tendríamos casi configurado S3 y Shrine, pero si deployamos y usamos la app veremos mensajes en la consola del navegador diciendo que hay requests que están fallando por CORS. El problema es que no le hemos dicho al bucket que debe aceptar requests desde el dominio de nuestra app. Para esto hay que definir su configuración de CORS. Hay un par de maneras de hacerlo:

  • Usando aws-cli. Se debe instalar y configurar con las credenciales del bucket. Luego se puede usar el comando s3api put-bucket-cors para setear el CORS a partir de un archivo que tengamos en local. Se vería más o menos así:

    aws s3api put-bucket-cors --bucket my-bucket-name --cors-configuration file://cors.jsons

    Dónde cors.json debe ser algo así:

    {
        "CORSRules": [
            {
                "AllowedHeaders": [
                    "*"
                ],
                "AllowedMethods": [
                    "PUT",
                    "POST",
                    "DELETE",
                    "GET"
                ],
                "AllowedOrigins": [
                    "https://pl-my-app.herokuapp.com"
                ]
            }
        ]
    }
  • Llamando directo a la api de AWS. Para esto puedes descargar una colección y un environment de Postman desde este link. Debes dar los valores que correspondan a las variables del ambiente, pero notar que la variable content-md5 se calcula sola al hacer la request, no es necesario darle un valor explícitamente

Si configuramos bien todo ya deberíamos poder subir y ver imágenes.

Última actualización