Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mount S3 folder under Heroku app

Is there such a concept as "mounting" an asset folder under your Heroku application, then linking it to S3 bucket?

I have a node app with a "public" asset folder. I'd like to .slugignore the "public" folder on my local project, have grunt upload to s3 bucket, and git push the code to Heroku when it starts up. The "public" folder will be visible, but sourced from the S3 bucket instead of Heroku's local file system.

I looked at Heroku's docs but (besides setting the env variables) there's no "automagic" that appears to mount your S3 bucket to your local Heroku /app folder.

like image 926
Biba Avatar asked Dec 08 '14 17:12

Biba


People also ask

Can S3 object be a folder?

Amazon S3 is a highly-scalable object storage system. Amazon S3 can contain any number of objects (files), and those objects can be organized into “folders”.

Can you mount S3 as a file system?

A S3 bucket can be mounted in a AWS instance as a file system known as S3fs. S3fs is a FUSE file-system that allows you to mount an Amazon S3 bucket as a local file-system. It behaves like a network attached drive, as it does not store anything on the Amazon EC2, but user can access the data on S3 from EC2 instance.

Can I store files on Heroku?

Heroku has an “ephemeral” hard drive, this means that you can write files to disk, but those files will not persist after the application is restarted. By default Active Storage uses a :local storage option, which uses the local file system to store any uploaded files.

Can Heroku store static files?

To answer your question, Heroku's "ephemeral filesystem" will not serve as a storage for static uploads. Heroku is an app server, period. You have to plug into data storage elsewhere.


1 Answers

I'm not aware of any out of the box solution. But a basic setup seems within reach. Here's a first pass using a dynamic segment in the route and a redirect in the controller:

in routes.rb:

get 's3/:file_key', to: 's3_redirects#show'

s3_redirects_controller.rb:

class S3RedirectsController < ApplicationController
  def show
    bucket = get_bucket
    file_key = params[:file_key]
    file_key += "." + params[:format] if params[:format].present?
    s3_file_link = RightAws::S3Interface.new(your_config_options_here).get_link(bucket, file_key, link_expiration_time)
    redirect_to s3_file_link
  end
end

Obviously you can substitute your favorite method of interfacing with your S3 files, and you have to define get_bucket and so on.

This of course only hits valid keys, you'll get a "no such key exists" otherwise. If you're looking for indexing / ls type actions, of course more needs to be done, but the basic structure here should allow you to do that as long as you have a reasonable way to get the data you're looking for from S3.

like image 89
Andrew Schwartz Avatar answered Sep 24 '22 01:09

Andrew Schwartz