I'm using Carrierwave to upload images, and my app is on Heroku right now.
Images are uploaded successfully unless I push a new commit to heroku. Images that I uploaded before a push seem to be erased when a new commit comes in. Does anyone know the reason behind and how to fix this issue?
Update:
The problem becomes, using carrierwave on Heroku without a storage server like Amazon EC3. Heroku does not save files in public folder, where carrierwave uploads by default.
app/uploaders/image_uploader.rb:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
And you need to change this to somewhere in the tmp folder in order to preserve your image files after each commit. I tried to change it to
"#{Rails.root}/tmp/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
But it does not work. I checked on my local environment, and the image is stored in the right location successfully. So I guess if I just set the routes to the right location, this could work. Could someone help me with this?
Since Heroku does not allow storing static files (unless it's associated the application itself), you should make Carrierwave upload to a remote repository (e.g. Amazon S3) using fog. Everytime a user uploads a file, the file will be automatically uploaded to your S3 storage instead of Heroku.
Related
Any idea how to use Carrierwave to upload images with Heroku.
I added this to the uploader file:
def cache_dir
"#{Rails.root}/tmp/uploads"
end
but images still don't save! After uploading an image, it saves and once you refresh the page, the image breaks.
Any help would be appreciated! Thanks
I do not think you can use Heroku and upload images without 3rd party storage service like Amazon S3.
https://devcenter.heroku.com/articles/s3
Heroku allows you store files inside tmp but just in order to send to a 3rd party service. Inside carrierwave uploader class you can set for example
storage :fog
instead of default :file and setup uploads to AWS S3. There are other options as well.
One thing is that if you are using a free tier instance on Heroku your upload needs to finish in abut a minute - I would recommend setup where you upload files directly to s3 account.
https://github.com/dwilkie/carrierwave_direct
Hope it helps
The filesystem on Heroku is not persisted. Only files uploaded through deployment mechanisms (git push) are "persisted". Others like the ones in your "#{Rails.root}/tmp/uploads" folder will be erased. That's why they are disappearing.
I have answered a similar question here. Here is a quote:
Your dyno on Heroku has a "read-only" filesystem. In a sense, your files will not be persisted between your dyno restarts and there is no guarantee that they will persist between any two requests. Here is an excerpt from the docs:
Each dyno has its own ephemeral file system, not shared with any other dyno, that is discarded as soon as you disconnect. This file system is populated with the slug archive so one-off dynos can make full use of anything deployed in the application.
You can use the #{Rails.root}/tmp folder as temporary folder, but you need to upload your files to some external storage (S3, some CDN, etc.). Heroku has some addons that makes it easy to handle.
I have an existing Rails RefineryCMS application, which have been running for quite some time. It has alot of image and document uploads, which always have been uploaded to the local filesystem.
But we are moving to Heroku, then this will be a problem, since Heroku doesn't persist these files.
So, we need to get all the existing images and document exported to a Amazon S3.
How could we achieve this?
Would it be plain simple as just copying over the existing files from the current production environment to the S3 bucket?
Kind regards
The plain solution was just to copy the existing folders that are generated by fileupload from Dragonfly in "app/public" to Amazon S3.
I was following this guide for uploading images with PaperClip over ActiveAdmin:
File upload with Activeadmin Rails using paperclip
Everything is working fine, but I was wondering, after I upload image, how to redirect it to be uploaded into /assets/images/ instead only in database?
You don't.
It won't work anyway. assets/images is a source directory for rails asset pipeline. On your production server, the images are not used from there but from another folder where they have been updated by the pipeline (typically getting a name with a linked timestamp, so that the browsers can cache them properly).
To make this work you would need to upload them to the assets/images, then run again the asset pipeline, which would be... weird.
If you don't want to store them in the public folder, look at an external storage like S3 (sample using Heroku: https://devcenter.heroku.com/articles/paperclip-s3).
I'm using carrierwave and I want to change the directory where images are stored.
Right now the image URL is /uploads/modelname/image/51/nameoffile.jpg
the store_dir in ImageUploader is
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
I definitely do not want the modelname to show
Is there an accepted ideal path where images should be stored on heroku?
Heroku doesn't allow uploads to their servers. You need to use another storage medium, like Amazon's S3.
I'm actually using Parse's (www.parse.com) API to store images on their solution. But it depends how you need access to your images.
You can upload files to the Heroku dyno filesystems but the filesystem are perishable and not shared among your dynos. Here's a Gist showing how to make Carrierwave store uploaded file in AWS S3 which is a better option: https://gist.github.com/cblunt/1303386
Here's a Heroku guide for accomplishing this with PaperClip: https://devcenter.heroku.com/articles/paperclip-s3
I have a RoR website, where users can upload photos. I use paperclip gem to upload the photos and store them on the server as files. I am planning to move to Amazon S3 for storing the photos. I need to move all my existing photos from server to Amazon S3. Can someone tell me the best way for moving the photos. Thanks !
You'll want to log into your AWS Console and create a bucket structure to facilitate your images. Neither S3 nor Paperclip have any tools in the way of bulk migrations from file system -> s3, you'll need to use the tool s3cmd for that. In particular, you're interested in the s3cmd sync command, something along the lines of:
s3cmd sync ./public/system/images/ s3://imagesbucket
If you have any image urls hard-coded into your database (a la markdown/template code) this might be a little tricky. One option would be to manually update your urls to point to the new bucket. Alternatively, you can rack-rewrite.
You can easily do this by creating a bucket on Amazon S3 that has the same folder structure as your public directory on your Rails app.
So say for instance, you create a new bucket on Amazon S3 called MyBucket and it has a folder in it called images. You'd just move all of your images within your Rails app's images folder over to that new bucket's images folder.
Then you can set up your app to use an asset host like this answer describes: is it good to use S3 for Rails "public/images" and there an easy way to do it?
If you are using image_tag or other tag helpers (javascripts, stylesheets, etc), then it will use that asset_host for production environments and properly generate the URL to your S3 bucket.
I found this script which takes care of moving the images to Amazon S3 bucket using rake task.
https://gist.github.com/924617