Currently, at the company I work for, we are working on rebuilding some modules of older applications. During this process, we decided to replace CarrierWave (a system we used for avatar uploads, for example) with Active Storage, as we believe it better suits our needs.
To understand the differences between the CarrierWave gem and Active Storage, I recommend reading two excellent articles:
From CarrierWave to Active Storage
Active Storage in production: lessons learned and in-depth look at how it works
Once the decision to use Active Storage was made, we needed to consider the method or service for storing these files. This is important because we have other applications that also need to load these files. An important point is that we have powerful local servers available, so if possible, we would prefer to use these servers instead of a service like Amazon S3 or Azure for example. This led us to choose Min.io, and this is what this article will talk about.
Min.io is a high-performance, distributed object storage system designed for large-scale private cloud infrastructure. The great advantage is that it is fully compatible with Amazon S3.
To use Min.io, all we have to do is configure Active Storage through
config/storage.yml as if we were using S3, but point it to a different endpoint, which will be our server running MinIO. In our example, the endpoint will be our own machine, so we will use
In our example, we will run MinIO directly on our machine (Linux), but it is also possible to run it using Docker, Kubernetes, or other non-Linux operating systems. For more information, refer to the Min.io documentation.
After installing MinIO as following the instructions in documentation, we can start the server with the following command:
minio server ~/minio. We will know the server is running when our terminal displays the following information:
MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>
Version: RELEASE.2023-07-21T21-12-44Z (go1.19.11 linux/amd64)
Status: 1 Online, 0 Offline.
S3-API: http://192.168.1.7:9000 http://127.0.0.1:9000
Console: http://192.168.1.7:36187 http://127.0.0.1:36187
$ mc alias set myminio http://192.168.1.7:9000 minioadmin minioadmin
Warning: The standard parity is set to 0. This can lead to data loss.
Once our MinIO server is running, we need to create a bucket. To do this, we must access one of the addresses listed in our terminal from the previous step; let's use
http://127.0.0.1:9000. We will log in to the system using the username and password
minioadmin, and in the menu, we will go to the Bucket option and create a new bucket. In our case, we will name it
With everything set up, we will now configure the 'config/storage.yml' file to make everything work. We will configure it as if we were using S3 as the service but add a different endpoint. Our configuration will look like this:
In this example, I left the
secret_access_key visible for didactic purposes, but I recommend using Rails Credentials to store these keys securely. Additionally, it is necessary to include
force_path_style: true because otherwise, Active Storage will use a bucket context as a subdomain, and MinIO expects the
bucket to be included after the domain.
It is also important to note that we used the name
local: for this service in
storage.yml, so in our
development.rb file, we need to have the same service name in the configurations:
config.active_storage.service = :local. If you used a different name in
storage.yml, be sure to change it accordingly in
Furthermore, we need to add the gem
aws-sdk-s3 to our Gemfile.
Everything is now ready, and our application is set to use MinIO together with Active Storage. The next time we upload a file, it will go directly to our bucket in MinIO, on our local server.
I hope this helps! :)