development-environmentminio

How to set up a MinIO to use virtual-hosted–style URLs for local development?


I have faced with the following problem: I use aws s3 as media storage. Since some moment aws was made path-style urls (e.g. http://s3.aws.com/bucket-name/object-key) deprecated and now the correct way to build urls is to use virtual-host-style urls (e.g. http://bucket-name.s3.aws.com/object-key).

For deployments (prod, stage, etc.) it sounds good to use virtual-host-style approach. But it seems that MinIO does not provide some suitable solution to use virtual-host-style for local dev.

I use docker-compose file to setup local infrastructure. Here is my compose file:

services:
  minio:
    container_name: "minio"
    image: minio/minio:RELEASE.2025-03-12T18-04-18Z
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      - MINIO_ROOT_USER=user
      - MINIO_ROOT_PASSWORD=1234678
    command: server /data --console-address ":9001"

I use dotnet:

private static void AddAmazonS3(this IServiceCollection services)
{
    var options = new AmazonS3Config
    {
        UseHttp = true,
        ServiceURL = "http://localhost:9000",
    };
    services.AddSingleton<IAmazonS3>(_ => new AmazonS3Client("user", "12346578", options));
}

I have configured hosts file to resolve routing, but it still not working:

127.0.0.1 bucket-name.localhost

I have created bucket with the correct name and once I have tried to upload a file I got the error: Amazon.S3.AmazonS3Exception: The specified bucket does not exist

It seems that minio does not support virtual-host-style.


Solution

  • Minio supports virtual-host-style.

    Here is how to setup local env to work with minio and virtual-host-style.

    1. Register IAmazonS3 client:
    private static void AddAmazonS3(this IServiceCollection services)
    {
        var options = new AmazonS3Config
        {
            UseHttp = true,
            ServiceURL = "http://localhost:9000",
        };
        services.AddSingleton<IAmazonS3>(_ => new AmazonS3Client("user", "12346578", options));
    }
    

    I use

    <PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.7.400" />
    <PackageReference Include="AWSSDK.S3" Version="3.7.501.15" />
    
    1. Add new domain to "C:/Windows/System32/drivers/etc/hosts" file:
    127.0.0.1 bucket-name.localhost
    
    1. Configure docker-compose.yaml file:
    services:
      minio:
        container_name: "minio"
        image: minio/minio:RELEASE.2025-03-12T18-04-18Z
        ports:
          - "9000:9000"
          - "9001:9001"
        environment:
          - MINIO_ROOT_USER=user
          - MINIO_ROOT_PASSWORD=1234678
          - MINIO_DOMAIN=localhost
        command: server /data --console-address ":9001"
    

    NOTE: here we have added MINIO_DOMAIN=localhost. It helps minio to resolve bucket name from incoming URL.

    So now once you put an object client will generate request to http://bucket-name.localhost:9000/object-key. The request will be resolved by local hosts file and will be redirected to 127.0.0.1:9000. Container will get the http://bucket-name.localhost:9000/object-key request and using MINIO_DOMAIN=localhost resolve the bucket name - bucket-name.