If you’re using WordPress or another web application that utilizes uploads in a load balanced and autoscaled environment, you know what a pain it can be to manage the uploads so they don’t disappear when an instance shuts down. Likewise, you need to make sure that every instance would have to have a copy of the resources because a request could go to any of them.
We use WordPress, and use media uploads quite a bit. We’ve been looking for a nice solution to the problem but until recently we didn’t have one. As we recently changed our autoscaling configuration and we recycle instances daily now, we found ourselves needing a better solution to this problem, and quickly.
The obvious choice for centralized resource storage is AWS S3. The unobvious choice is how to go about it. We tried using a few different WordPress extensions to do the task, however all of them had faults in one way or another that make them not well suited for a load balanced and autoscaled environment. Then we stumbled upon s3fs-fuse. In short, it’s a FUSE filesystem extension to mount an S3 bucket as a local folder on the file system. This seemed like the perfect solution. I checked into some other S3 File System FUSE extensions and this one seemed to be the most mature and actively maintained, despite it’s high open issue count, some of which are more questions about the product than actual issues.
Fortunately, getting s3fs-fuse setup to work with AWS Beanstalk is as easy as adding a .config file to your .ebextensions folder and adding your Access Keys to your Elastic Beanstalk configuration and that’s it! No changes to WordPress! Now, if you have the need to use CloudFront for your WordPress resources, then you’ll probably need an additional custom plugin (ie: you’ll have to write it, I haven’t found anything that will do this) that will inspect content of your posts and rewrite the URLs to a CloudFront url. But you can still use this s3fs-fuse extension as a backend to ensure files are uploaded to S3.
So without further delay, here is the config file. Simply add an Access Key to your Elastic Beanstalk configuration (one that has access to the bucket you’re referencing), replace the bracketed options with your specific details and drop this file into your .ebextensions folder and deploy it to your Beanstalk environment.