Skip to content

Laravel and Django

Both frameworks talk to Hive Buckets through their standard S3 storage backends. You need a bucket and an access key with Read & write permission. Put the values in your app’s environment variables.

Install the S3 driver:

Terminal window
composer require league/flysystem-aws-s3-v3 "^3.0"

Set the environment variables:

.env
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=DH...
AWS_SECRET_ACCESS_KEY=...
AWS_DEFAULT_REGION=auto
AWS_BUCKET=my-app-uploads
AWS_ENDPOINT=https://s3.dockhive.io
AWS_USE_PATH_STYLE_ENDPOINT=true
AWS_URL=https://s3.dockhive.io/my-app-uploads

Check the s3 disk in config/filesystems.php. Recent Laravel versions already read these variables:

config/filesystems.php
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'auto'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT', 'https://s3.dockhive.io'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', true),
'throw' => false,
],

Use it like any disk:

use Illuminate\Support\Facades\Storage;
$path = $request->file('avatar')->store('avatars', 's3'); // upload
$contents = Storage::disk('s3')->get($path); // read
$url = Storage::disk('s3')->temporaryUrl($path, now()->addMinutes(30)); // presigned link
Storage::disk('s3')->delete($path);

Storage::url($path) builds a public link from AWS_URL; it only works for files in a public bucket. For private buckets, use temporaryUrl().

Install django-storages with boto3:

Terminal window
pip install "django-storages[s3]"
settings.py
import os
AWS_ACCESS_KEY_ID = os.environ["HIVE_BUCKETS_ACCESS_KEY_ID"]
AWS_SECRET_ACCESS_KEY = os.environ["HIVE_BUCKETS_SECRET_ACCESS_KEY"]
AWS_STORAGE_BUCKET_NAME = "my-app-uploads"
AWS_S3_ENDPOINT_URL = "https://s3.dockhive.io"
AWS_S3_REGION_NAME = "auto"
AWS_S3_ADDRESSING_STYLE = "path"
AWS_S3_SIGNATURE_VERSION = "s3v4"
AWS_DEFAULT_ACL = None # files inherit the bucket's visibility
AWS_QUERYSTRING_AUTH = True # file.url returns presigned links (private bucket)
AWS_QUERYSTRING_EXPIRE = 3600
STORAGES = {
"default": {"BACKEND": "storages.backends.s3.S3Storage"},
"staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
}

Now FileField and ImageField uploads go to your bucket, and instance.file.url returns a presigned link that works for an hour.

Keep AWS_QUERYSTRING_AUTH = True. Every .url is a presigned link, so files stay private.

To serve collectstatic output from a bucket as well, point "staticfiles" at storages.backends.s3.S3Storage with a public bucket of its own (pass the bucket in "OPTIONS": {"bucket_name": "my-app-static", "querystring_auth": False}).