Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • 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
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Model Context Protocol
    • Vector Database
    • Working with AI
    • Heroku Inference
      • Quick Start Guides
      • Inference API
      • Inference Essentials
      • AI Models
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • 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
  • Integrating with Salesforce
  • Add-ons
  • All Add-ons
  • Stackhero Object Storage (compatible with the Amazon S3 protocol)
Stackhero Object Storage (compatible with the Amazon S3 protocol)

This add-on is operated by Stackhero

Object storage on dedicated instances with unlimited transfers

Stackhero Object Storage (compatible with the Amazon S3 protocol)

Last updated December 11, 2024

Table of Contents

  • Provisioning the add-on
  • Create a user
  • Local setup
  • Using with Java
  • Using with Ruby
  • Using with Python
  • Using with PHP
  • Using with Go
  • Using with Node.js
  • Dashboard and MinIO console web UI
  • Upgrading your plan
  • Removing the add-on
  • Support
  • Additional resources

Stackhero Object Storage provides an object storage, based on MinIO, compatible with the Amazon S3 protocol and running on a fully dedicated instance.

It is easy to setup, fast and has a simple and predictive pricing. Especially, the network traffic is included and unlimited.

With your Stackhero Object Storage add-on you will get:

  • Unlimited transfers
  • A private instance (dedicated VM) for high performances and security
  • TLS encryption (aka SSL)
  • An automatic backup every 24 hours
  • A graphical web UI (MinIO console)
  • One click to update to new MinIO versions
  • Super fast servers with SSD disks

All clients compatible with the Amazon S3 protocol can connect to Stackhero Object Storage and there is an Amazon S3 client library for almost every language out there, including Ruby, Node.js, Java, Python, Clojure and Erlang.

You can also use the MinIO SDKs. This is the recommended way to connect to your object storage. You will find all the available SDKs on MinIO official documentation.

Another way to connect is to use the MinIO CLI interface. This is very helpful when you want to send big files directly from your terminal. You will find all the informations about it on the MinIO CLI official documentation.

Provisioning the add-on

Stackhero Object Storage can be attached to a Heroku application via the CLI:

A list of all plans available can be found here.

$ heroku addons:create ah-s3-object-storage-stackhero --app <your app name>
-----> Adding ah-s3-object-storage-stackhero to sharp-mountain-4005... done

After you provision Stackhero Object Storage, the STACKHERO_MINIO_ROOT_ACCESS_KEY and STACKHERO_MINIO_ROOT_SECRET_KEY config variables are available in your app’s configuration. They contain the “root” credentials.

You can see the content of those variables via the heroku config:get command:

$ heroku config:get STACKHERO_MINIO_ROOT_ACCESS_KEY
2765UKKnWOjjFtcXYSzW

We discourage users to directly use the “root” credentials in their applications. The good practice is to create a dedicated user and use it in your apps.

Create a user

A user is identified by an access key and a secret key that you will create.

There is two possibilities to create a user: use the MinIO web console or use the MinIO CLI client.

Create a user using the MinIO web console

To create a user on MinIO, you first have to connect to your Stackhero dashboard:

$ heroku addons:open ah-s3-object-storage-stackhero
Opening ah-s3-object-storage-stackhero for sharp-mountain-4005

Select your MinIO service and click on the Console link. Identify yourself with the STACKHERO_MINIO_ROOT_ACCESS_KEY and STACKHERO_MINIO_ROOT_SECRET_KEY credentials. You can retrieve them with the heroku config command or directly in Stackhero dashboard, by clicking on the Configure button.

Once connected to the MinIO console, click on “Users”, then “Create a user”. Define an access key, a secret key and select the policies you want (probably “readwrite”).

Creating a MinIO user

Once the user is created, you will be able to use these access key and secret key in your app.

Local setup

After you provision the add-on, it’s necessary to locally replicate its config variables so your development environment can operate against the service.

Use the Heroku Local command-line tool to configure, run and manage process types specified in your app’s Procfile. Heroku Local reads configuration variables from a .env file.

$ echo "STACKHERO_MINIO_ACCESS_KEY=XXXXXXX" >> .env
$ echo "STACKHERO_MINIO_SECRET_KEY=YYYYYYY" >> .env

Simply replace XXXXXXX per the access key value you have created before and YYYYYYY per the secret key.

Credentials and other sensitive configuration values should not be committed to source-control. In Git, exclude the .env file with: echo .env >> .gitignore.

For more information, see the Heroku Local article.

Using with Java

Here is an example of a connection using the MinIO SDK:

MinioClient minioClient =
  MinioClient.builder()
    .endpoint("https://" + System.getenv("STACKHERO_MINIO_HOST"))
    .credentials(System.getenv("STACKHERO_MINIO_ACCESS_KEY"), System.getenv("STACKHERO_MINIO_SECRET_KEY"))
    .build();

You will find more information on the official MinIO Java SDK documentation.

Using with Ruby

Install the AWS SDK gem:

$ gem 'aws-sdk'
$ bundle install

Here is a simple example of how to use MinIO via AWS SDK on Ruby:

require 'aws-sdk'

Aws.config.update(
  endpoint: 'https://' + ENV["STACKHERO_MINIO_HOST"],
  access_key_id: ENV["STACKHERO_MINIO_ACCESS_KEY"],
  secret_access_key: ENV["STACKHERO_MINIO_SECRET_KEY"],
  force_path_style: true,
  region: 'us-east-1'
)

rubys3_client = Aws::S3::Client.new

# put_object operation

rubys3_client.put_object(
  key: 'testobject',
  body: 'Hello from MinIO!!',
  bucket: 'testbucket',
  content_type: 'text/plain'
)

# get_object operation

rubys3_client.get_object(
  bucket: 'testbucket',
  key: 'testobject',
  response_target: 'download_testobject'
)

print "Downloaded 'testobject' as  'download_testobject'. "

You will find more information on the official MinIO Ruby documentation.

Using with Python

Using AWS SDK (boto)

Install the AWS SDK (boto) package:

$ pip install boto3
$ pip freeze > requirements.txt

Here is an example on how to connect to MinIO with Python and AWS SDK (boto) package:

#!/usr/bin/env/python
import os
import boto3
from botocore.client import Config

s3 = boto3.resource('s3',
                    endpoint_url='https://' + os.environ.get('STACKHERO_MINIO_HOST'),
                    aws_access_key_id=os.environ.get('STACKHERO_MINIO_ACCESS_KEY'),
                    aws_secret_access_key=os.environ.get('STACKHERO_MINIO_SECRET_KEY'),
                    config=Config(signature_version='s3v4'),
                    region_name='us-east-1')

# upload a file from local file system '/home/john/piano.mp3' to bucket 'songs' with 'piano.mp3' as the object name.
s3.Bucket('songs').upload_file('/home/john/piano.mp3','piano.mp3')

# download the object 'piano.mp3' from the bucket 'songs' and save it to local FS as /tmp/classical.mp3
s3.Bucket('songs').download_file('piano.mp3', '/tmp/classical.mp3')

print "Downloaded 'piano.mp3' as  'classical.mp3'. "

You will find more information on the official MinIO Python documentation.

Using MinIO SDK

Install the MinIO package:

$ pip install minio
$ pip freeze > requirements.txt

Here is an example on how to connect to MinIO with Python:

#!/usr/bin/env/python
from minio import Minio
from minio.error import S3Error

def main():
  # Create a client with the MinIO server playground, its access key
  # and secret key.
  client = Minio(
    endpoint=os.environ.get('STACKHERO_MINIO_HOST') + ':443,
    secure=True,
    access_key=os.environ.get('STACKHERO_MINIO_ACCESS_KEY'),
    secret_key=os.environ.get('STACKHERO_MINIO_SECRET_KEY'),
  )

  # Make 'asiatrip' bucket if not exist.
  found = client.bucket_exists("asiatrip")
  if not found:
    client.make_bucket("asiatrip")
  else:
    print("Bucket 'asiatrip' already exists")

  # Upload '/home/user/Photos/asiaphotos.zip' as object name
  # 'asiaphotos-2015.zip' to bucket 'asiatrip'.
  client.fput_object(
    "asiatrip", "asiaphotos-2015.zip", "/home/user/Photos/asiaphotos.zip",
  )
  print(
    "'/home/user/Photos/asiaphotos.zip' is successfully uploaded as "
    "object 'asiaphotos-2015.zip' to bucket 'asiatrip'."
  )


if __name__ == "__main__":
  try:
    main()
  except S3Error as exc:
    print("error occurred.", exc)

You will find more information on the official MinIO Python SDK documentation.

Using with PHP

Install the AWS SDK for PHP package:

$ composer require aws/aws-sdk-php

Here is an example on how to connect to MinIO with PHP and AWS SDK:

<?php

// Include the SDK using the Composer autoloader
date_default_timezone_set('America/Los_Angeles');
require 'vendor/autoload.php';

$s3 = new Aws\S3\S3Client([
  'version' => 'latest',
  'region'  => 'us-east-1',
  'endpoint' => 'https://' . getenv('STACKHERO_MINIO_HOST'),
  'use_path_style_endpoint' => true,
  'credentials' => [
    'key'    => getenv('STACKHERO_MINIO_ACCESS_KEY'),
    'secret' => getenv('STACKHERO_MINIO_SECRET_KEY')
  ],
]);


// Send a PutObject request and get the result object.
$insert = $s3->putObject([
  'Bucket' => 'testbucket',
  'Key'    => 'testkey',
  'Body'   => 'Hello from MinIO!!'
]);

// Download the contents of the object.
$retrive = $s3->getObject([
  'Bucket' => 'testbucket',
  'Key'    => 'testkey',
  'SaveAs' => 'testkey_local'
]);

// Print the body of the result by indexing into the result object.
echo $retrive['Body'];

You will find more information on the official MinIO PHP documentation.

Using with Go

Using AWS SDK

Install the AWS SDK package for GO:

$ go get github.com/aws/aws-sdk-go-v2
$ go get github.com/aws/aws-sdk-go-v2/config

Here is an example on how to connect to MinIO with GO and AWS SDK:

package main

import (
  "fmt"
  "os"
  "strings"

  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/aws/credentials"
  "github.com/aws/aws-sdk-go/service/s3/s3manager"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
  bucket := aws.String("newbucket")
  key := aws.String("testobject")

  // Configure to use MinIO Server
  s3Config := &aws.Config{
    Credentials:      credentials.NewStaticCredentials(os.Getenv("STACKHERO_MINIO_ACCESS_KEY"), os.Getenv("STACKHERO_MINIO_SECRET_KEY"), ""),
    Endpoint:         aws.String("https://" + os.Getenv("STACKHERO_MINIO_HOST")),
    Region:           aws.String("us-east-1"),
    DisableSSL:       aws.Bool(false),
    S3ForcePathStyle: aws.Bool(true),
  }
  newSession := session.New(s3Config)

  s3Client := s3.New(newSession)

  cparams := &s3.CreateBucketInput{
    Bucket: bucket, // Required
  }

  // Create a new bucket using the CreateBucket call.
  _, err := s3Client.CreateBucket(cparams)
  if err != nil {
    // Message from an error.
    fmt.Println(err.Error())
    return
  }

  // Upload a new object "testobject" with the string "Hello World!" to our "newbucket".
  _, err = s3Client.PutObject(&s3.PutObjectInput{
    Body:   strings.NewReader("Hello from MinIO!!"),
    Bucket: bucket,
    Key:    key,
  })
  if err != nil {
    fmt.Printf("Failed to upload data to %s/%s, %s\n", *bucket, *key, err.Error())
    return
  }
  fmt.Printf("Successfully created bucket %s and uploaded data with key %s\n", *bucket, *key)

  // Retrieve our "testobject" from our "newbucket" and store it locally in "testobject_local".
  file, err := os.Create("testobject_local")
  if err != nil {
    fmt.Println("Failed to create file", err)
    return
  }
  defer file.Close()

  downloader := s3manager.NewDownloader(newSession)
  numBytes, err := downloader.Download(file,
  &s3.GetObjectInput{
    Bucket: bucket,
    Key:    key,
  })
  if err != nil {
    fmt.Println("Failed to download file", err)
    return
  }
  fmt.Println("Downloaded file", file.Name(), numBytes, "bytes")
}

You will find more information on the official MinIO GO documentation.

Using MinIO SDK

Install the MinIO SDK package for GO:

$ GO111MODULE=on go get github.com/minio/minio-go/v7

Here is an example on how to connect to MinIO with GO and MinIO SDK:

package main

import (
  "log"

  "github.com/minio/minio-go/v7"
  "github.com/minio/minio-go/v7/pkg/credentials"
)

func main() {
  endpoint := os.Getenv("STACKHERO_MINIO_HOST")
  accessKeyID := os.Getenv("STACKHERO_MINIO_ACCESS_KEY")
  secretAccessKey := os.Getenv("STACKHERO_MINIO_SECRET_KEY")
  useSSL := true


  // Initialize minio client object.
  minioClient, err := minio.New(endpoint, &minio.Options{
    Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
    Secure: useSSL,
  })
  if err != nil {
    log.Fatalln(err)
  }

  log.Printf("%#v\n", minioClient) // minioClient is now set up
}

You will find more information on the official MinIO GO SDK documentation.

Using with Node.js

Using AWS SDK

Install the AWS SDK package for Node.js:

$ npm install --save aws-sdk

Here is an example on how to connect to MinIO with Node.js and MinIO SDK:

const process = require('process');
const AWS = require('aws-sdk');

const s3  = new AWS.S3({
  accessKeyId: process.env.STACKHERO_MINIO_ACCESS_KEY,
  secretAccessKey: process.env.STACKHERO_MINIO_SECRET_KEY,
  endpoint: 'https://' + process.env.STACKHERO_MINIO_HOST,
  s3ForcePathStyle: true, // needed with minio?
  signatureVersion: 'v4'
});

// putObject operation.
s3.putObject(
  { Bucket: 'testbucket', Key: 'testobject', Body: 'Hello from MinIO!!' },
  (err, data) => {
    if (err)
      console.log(err)
    else
      console.log('Successfully uploaded data to testbucket/testobject');
  }
);

// getObject operation.
const file = require('fs').createWriteStream('/tmp/mykey');
s3.getObject({ Bucket: 'testbucket', Key: 'testobject' })
  .on('httpData', chunk => file.write(chunk))
  .on('httpDone', () => file.end())
  .send();

You will find more information on the official MinIO Node.js documentation.

Using MinIO SDK

Install the MinIO SDK package for Node.js:

$ npm install --save minio

Here is an example on how to connect to MinIO with Node.js and MinIO SDK:

const process = require('process');
const Minio = require('minio');

// Instantiate the minio client with the endpoint
// and access keys as shown below.
const minioClient = new Minio.Client({
  endpoint: process.env.STACKHERO_MINIO_HOST,
  port: 443,
  useSSL: true,
  accessKeyId: process.env.STACKHERO_MINIO_ACCESS_KEY,
  secretAccessKey: process.env.STACKHERO_MINIO_SECRET_KEY,
});

// File that needs to be uploaded.
const file = '/tmp/photos-europe.tar'

// Make a bucket called europetrip.
minioClient.makeBucket(
  'europetrip',
  'us-east-1',
  err => {
    if (err) return console.log(err)

    console.log('Bucket created successfully in "us-east-1".')

    const metaData = {
      'Content-Type': 'application/octet-stream',
      'X-Amz-Meta-Testing': 1234,
      'example': 5678
    }
    // Using fPutObject API upload your file to the bucket europetrip.
    minioClient.fPutObject(
      'europetrip',
      'photos-europe.tar',
      file,
      metaData,
      (err, etag) => {
        if (err) return console.log(err)
        console.log('File uploaded successfully.')
      }
    );
  }
);

You will find more information on the official MinIO Node.js SDK documentation.

Dashboard and MinIO console web UI

Stackhero dashboard allows you to see your instance usage, restart it, and apply updates. It also gives you the ability to access the MinIO console web UI to consult your MinIO data directly in a graphical way.

You can access the dashboard via the CLI:

$ heroku addons:open ah-s3-object-storage-stackhero
Opening ah-s3-object-storage-stackhero for sharp-mountain-4005

or by visiting the Heroku Dashboard and selecting the application in question. Select “Stackhero Object Storage from the Add-ons menu.

Upgrading your plan

You cannot downgrade an existing add-on.

 

Application owners should carefully manage the migration timing to ensure proper application function during the migration process.

Use the heroku addons:upgrade command to migrate to a new plan.

$ heroku addons:upgrade ah-s3-object-storage-stackhero:newplan
-----> Upgrading ah-s3-object-storage-stackhero:newplan to sharp-mountain-4005... done
       Your plan has been updated to: ah-s3-object-storage-stackhero:newplan

Removing the add-on

You can remove Stackhero Object Storage via the CLI:

This will destroy all associated data and cannot be undone!

$ heroku addons:destroy ah-s3-object-storage-stackhero
-----> Removing ah-s3-object-storage-stackhero from sharp-mountain-4005... done

Support

Stackhero Object Storage support and runtime issues should be submitted via one of the Heroku Support channels. We recommend adding support@stackhero.io in copy for urgent issues.

Additional resources

  • Object Storage (MinIO) documentation by Stackhero
  • MinIO managed cloud

Keep reading

  • All Add-ons

Feedback

Log in to submit feedback.

Zara 4 Status List Uptime

Information & Support

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

Language Reference

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

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices