How should I deal with lots of images?
I have a Rails app that lets users select an invoice from a list of invoices. When selected a view of the image of the invoice is displayed with an image of the customer signature overlayed on top. This is all working well with the test invoice and signature images I am using (9 of each). They are all kept in the app/assets/images folder. However the production data contains hundreds of thousands of invoice and signature images. What is best practise for storing these images so they are accessible by the Rails app?
I would use a cloud service like AWS S3 to store lots of images and save the URLs to the image model in the database, like:
image.source = "http://yourapp.s3.amazonaws.com/969ba2d01cc3.jpg"
To display the images on the page you can do
AWS S3 is fairly standard but there are other options like Digital Ocean Spaces, Backblaze B2, Wasabi, etc. (I'm looking at Wasabi right now because they're touting themselves as 80% cheaper than S3! 🎉)
If you want to display thumbnails for the image you can run then live through a transformation service like Imgix. You simply add your cloud storage as an Imgix 'source' then call your images through that, appending something like
?w=250&h=250 to give you a faster-loading thumbnail.
Thanks Daniel. There is a bit of paranoia amongst management here about storing company data outside the network. We have plenty of storage on the company servers, I am just not sure how to access the images if they are not stored in the Rails app. Do you know of any way to do that?
I understand the paranoia, but it's more a case of protecting access than the actual location of the files themselves. Most cloud systems offer 'encryption at rest' and you would be using HTTPS to load the images. That being said, if you have SLAs and privacy policies already in place you might be better using your own storage.
The method would be the same as I mentioned earlier - you store an
Image record in your database with something like
image.source that contains the URL of the file. You would have some kind of server set up in front of your file storage to server the files via URLs.
It would be up to you to limit access to those files to your own application. On AWS S3 files/folders/buckets are set to private by default and you could request a short-lived (say, 10 minutes) access URL every time you load a file. You can also use CORS to limit who can access your files.
There's likely a easy way to do this, and probably avoid any web access, between your application and your file storage if it's all ont he same internal network but I have no idea how to do that.