Can Heroku be made to use a persistent filesystem? - ruby-on-rails

I've built an app where users can upload their avatars. I used the paperclip gem and everything works fine on my local machine. On Heroku everything works fine until server restart. Then every uploaded images disappear. Is it possible to keep them on the server?
Notice: I probably should use services such as Amazon S3 or Google Cloud. However each of those services require credit card or banking account information, even if you want to use a free mode. This is a small app just for my portfolio and I would rather avoid sending that information.

No, this isn't possible. Heroku's filesystem is ephemeral and there is no way to make it persistent. You will lose your uploads every time your dyno restarts.
You must use an off-site file storage service like Amazon S3 if you want to store files long-term.
(Technically you could store your images directly in your database, e.g. as a bytea in Postgres, but I strongly advise against that. It's not very efficient and then you have to worry about how to provide the saved files to the browser. Go with S3 or something similar.)

Related

Use external file storage for heroku app?

I have rails application running on heroku, as heroku file system is read-only so we cannot store any files or images on heroku.
A lot of people has suggested to use amazon s3, but can i use external storage to save user files and images and to retrieve them from there with paperclip or carrier-wave or anything similar.
Currently i am using Dropbox for images and files storage. But its too slow. I have a shared hosting account, there i have a lot of disk space and i want to use that to store files.
Any idea on how to do that?

Rails hosting for small photo app

I'm making a small photo-gallery app. The photos will be hosted locally. Right now I use dreamhost but their rails implementation looks horrible. So I'm looking for other options. I know Heroku gives you one 'web dyno' for free, but they don't say anything about how much space you get. As I said, I want my photos stored locally with the app, I don't want to deal with s3 or other cloud storage.
there is no local storage with heroku - only temporary space. you'll need to use S3 or some off-site storage with heroku.
(and I agree, rails on DH is awful, even if you enable passenger)
Use Openshift to deploy your app
checkout this deploying rails app in openshift
openshift provides one permanent data directory to store data and its free
If you are interested in VPS, Digital Ocean - https://www.digitalocean.com/, provides excellent hosting starting from $5. And you can store your photos on the local disc.
There are very good tutorials on their site to get you started with.
Check out Shelly Cloud: https://shellycloud.com/ You get persistent storage (so you don't lose data in case of disk failure) and the deployment is optimized for Rails applications.
With Heroku you can host images that you store in the repository of your project. Just try this:
rails new mytest
create a simple page and link to a test image in your /app/assets/images
heroku create mytest123 # <-- mytest1234 must be your unique app name
and now push the repo to Heroku:
git push origin master # origin points automatically to Heroku after you created this
This is the easiest way to host small projects for free. Sometimes the Dyno takes some time to startup, and you need to point the domain to the right proxy, but these issues can be dealt with later.
S3 comes into play when you deal with uploaded content / images. For this use case, you need S3 which is out of the scope of your question too.

Rails Heroku Paperclip Files disapperad

I'm developing a webapp with Rails, Paperclip and Heroku but since my last commit were I just added Google Analytics the most of the uploaded images disappeared! That's my link: http://wo42.herokuapp.com/ I don't know why that happened oO
Heroku never used to let you write to their file-system although they have recently introduced something calld the ephemeral file-system - this article explains it. Best option is to use S3.
The actual issue here is that when you push to Heroku your application is re-deployed, and that won't be to the same machine that you were on before (it could be anywhere at any time).
Therefore, if you were uploading images to your local dynos filesystem, only that dyno had access to those files. When you deployed, that dyno would have been destroyed and a new one created.
This is why Heroku recommend that you use a persistent backing service such as S3 to store your uploaded and persisted files. This sort of service is available to all dynos and persists across deploys.
https://devcenter.heroku.com/articles/s3

Where to save scraped images?

I'm building a Ruby on Rails app that scrapes the images off a website. What is the best location to save this images to?
Edit:
To be clear, I know the file system is the best type of storage, but where on the file system? I suppose I have to stay in the RoR app directory, but which folder is best suitable for this? public?
On your file server (static Apache server), on your app server (save some where locally in the disk and serve via the app server) or on Amazon S3
But I would suggest not to store in Database. (Some people think it's alright. So, I would be limited to suggestion)
in ROR, under <app_name>/public/images see here -- but the data will be public. If you are worried about privacy, probably this is not right.
If you are concerned about privacy, see the options discussed here How to store private pictures and videos in Ruby on Rails But as a sughestion: serving files from app-server may be painful in high traffic conditions and my experience is it better off-loaded to a file server or a cloud like S3.
It's not hard to write and/or create a server that is only serving images from a file store outside your website's directory structure. A simple rewrite of the URL can provide your code with the info it needs to the actual file location, which it then outputs to the browser.
An alternate is to have the image's URL mapped to the image's directory path in a database, then do a lookup. Make the URL field an indexed lookup and it will be very fast.
I wrote an image server in Ruby a couple years ago along those lines and it was a pretty simple task.

Securing S3 via your own application

Imagine the following use case:
You have a basecamp style application hosting files with S3. Accounts all have their own files, but stored on S3.
How, therefore, would a developer go about securing files so users of account 1, couldn't somehow get to files of account 2?
We're talking Rails if that's a help.
S3 supports signed time expiring URLs that mean you can furnish a user with a URL that effectively lets only people with that link view the file, and only within a certain time period from issue.
http://www.miracletutorials.com/s3-amazon-expiring-urls/
If you want to restrict control of those remote resources you could proxy the files through your app. For something like S3 this may defeat the purpose of what you are trying to do, but it would still allow you to keep the data with amazon and restrict access.
You should be careful with an approach like this as it could cause your ruby thread to block while it is proxying the file, which could become a real problem with the application.
Serve the files using an EC2 Instance
If you set your S3 bucket to private, then start up an EC2 instance, you could serve your files on S3 via EC2, using the EC2 instance to verify permissions based on your application's rules. Because there is no charge for EC2 to transfer to/from S3 (within the same region), you don't have to double up your bandwidth consumption costs at Amazon.
I haven't tackled this exact issue. But that doesn't stop me from having an opinion :)
Check out cancan:
http://github.com/ryanb/cancan
http://railscasts.com/episodes/192-authorization-with-cancan
It allows custom authorization schemes, without too much hassle.

Resources