Skip Navigation
Show nav
Heroku Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku Architecture
    • Dynos (app containers)
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Command Line
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery
    • Continuous Integration
  • Language Support
    • Node.js
    • Ruby
      • Rails Support
      • Working with Bundler
    • Python
      • Working with Django
      • Background Jobs in Python
    • Java
      • Working with Maven
      • Java Database Operations
      • Working with the Play Framework
      • Working with Spring Boot
      • Java Advanced Topics
    • PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
    • Heroku Redis
    • Apache Kafka on Heroku
    • Other Data Stores
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
    • Compliance
  • Heroku Enterprise
    • Private Spaces
      • Infrastructure Networking
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
    • Single Sign-on (SSO)
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • App Performance
  • Using AWS S3 to Store Static Assets and File Uploads

Using AWS S3 to Store Static Assets and File Uploads

English — 日本語に切り替える

Last updated 27 May 2020

Table of Contents

  • Overview
  • S3 setup
  • Static assets
  • File uploads

Amazon Simple Storage Service (S3) is a “highly durable and available store” that is ideal for storing application content such as media files, static assets, and user uploads.

S3 allows you to offload the storage of static files from your app. This is crucial on Heroku, because your app’s dynos have an ephemeral filesystem. This means that all files that aren’t part of your application’s slug are lost whenever a dyno restarts or is replaced (this happens at least once daily).

Overview

All files in S3 are stored in buckets. Buckets act as a top-level container, much like a directory. All files sent to S3 belong to a bucket, and a bucket’s name must be unique across all of S3.

Access to the S3 API is governed by an Access Key ID and a Secret Access Key. The access key identifies your S3 user account, and the secret key is a password-like credential that should be stored securely.

S3 setup

Enabling an application to use S3 requires that the application have access to the AWS credentials as well as the name of the bucket to store files.

Credentials

Your S3 credentials can be found on the Security Credentials section of the AWS “My Account/Console” menu

Manage S3 credentials

Because of the sensitive nature of your S3 credentials, you should never commit them to version control. Instead, set them as the values of config vars for the Heroku apps that will use them.

Use the heroku config:set to set both keys:

$ heroku config:set AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy
Adding config vars and restarting app... done, v21
  AWS_ACCESS_KEY_ID     => xxx
  AWS_SECRET_ACCESS_KEY => yyy

Bucket

Make sure you create your S3 bucket in the same region as the app that will use it. This takes advantage of AWS’s free in-region data transfer rates.

A single bucket typically stores the files, assets, and uploads for an application. To create a bucket, access the S3 section of the AWS Management Console and create a new bucket in the US Standard region:

Create new S3 bucket

Although you have a lot of freedom in choosing a bucket name, take care in choosing a name to ensure maximum interoperability.

Store the bucket name in a config var to give your application access to its value:

$ heroku config:set S3_BUCKET_NAME=appname-assets
Adding config vars and restarting app... done, v22
  S3_BUCKET_NAME     => appname-assets

Naming buckets

Your S3 bucket’s name can have unintended effects on which features of AWS you can use, including basic features like encryption. To ensure maximum compatibility, the ideal bucket name has:

  • 32 total characters or fewer
  • No capital letters (A-Z)
  • No periods (.)
  • No underscores (_)
  • No hyphens (-) as the first or last character.

The reasons why these naming conventions matter are as follows:

  • Period (.) characters cause certificate failures when using SSL or TLS.
  • Capital letters, underscores (_), and beginning/terminating hyphens (-) disable the use of the preferred “Virtual Hosted” API format for S3, and they are incompatible with some S3 regions.
  • Bucket names that are greater than 32 characters in length cannot use AWS STS policies, which provide flexible, temporary credentials.

Static assets

Static assets such as videos, PDFs, Javascript, CSS, and image files can be manually uploaded to your S3 account using the command line or a graphical browser like the Amazon S3 console.

After assets are uploaded, you can refer to their public URLs (such as http://s3.amazonaws.com/bucketname/filename) in your application’s code. These files will now be served directly from S3, freeing up your application to serve only dynamic requests.

File uploads

There are two approaches to processing and storing file uploads from a Heroku app to S3: direct and pass-through.

Direct upload

In a direct upload, a file is uploaded to your S3 bucket from a user’s browser, without first passing through your app. This method is recommended for user uploads that might exceed 4MB in size.

Although this method reduces the amount of processing your application needs to perform, it can be more complex to implement. It also limits the ability to modify (transform, filter, resize, etc.) files before storing them in S3.

Most of the articles listed below demonstrate how to perform direct uploads.

Pass-through uploads

In a pass-through upload, a file is uploaded to your app, which in turn uploads it to S3. This method enables you to perform preprocessing on user uploads before you push them to S3. However, depending on your chosen language and framework, this method might cause latency issues for other requests that are initiated while the upload is taking place.

Large files uploads in single-threaded, non-evented environments (such as Rails) block your application’s web dynos and can cause request timeouts and H11, H12 errors. EventMachine, Node.js and JVM-based languages are less susceptible to such issues. Please be aware of this constraint and choose the right approach for your language or framework.

Language-specific guides

Here are language-specific guides to handling uploads to S3:

Language/framework Tutorials
Ruby/Rails
  • Direct to S3 Image Uploads in Rails
Node.js
  • Direct to S3 File Uploads in Node.js
Python
  • Direct to S3 File Uploads in Python
Java
  • Uploading Files to S3 in Java with Play 2
PHP
  • Uploading Files to S3 in PHP

Keep reading

  • App Performance

Feedback

Log in to submit feedback.

Worker Dynos, Background Jobs and Queueing Worker Dynos, Background Jobs and Queueing

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Podcasts
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing

Subscribe to our monthly newsletter

Your email address:

  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Heroku Podcasts
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Facebook
  • Instagram
  • Github
  • LinkedIn
  • YouTube
Heroku is acompany

 © Salesforce.com

  • heroku.com
  • Terms of Service
  • Privacy
  • Cookies