0% прочитано

Use MinIO Locally Without Changing Production Laravel Configuration

Local MinIO should not require a separate filesystems.php or environment-specific branches in application code. I keep one Laravel S3 configuration and vary only the endpoint, credentials, bucket, and addressing mode through environment variables.

8 жовтня 2026 р. 8 хв читанняLaradock

After I connected MinIO through Laravel's standard S3 disk, the next question was whether local MinIO needed a separate filesystem configuration.

I decided it did not.

Local development and production use the same filesystem contract. Laravel works through s3 in both environments.

Only the destination behind that disk changes.

I therefore keep config/filesystems.php generic and move environment differences into environment variables.

If local and production storage support the same S3 contract, changing environments should not require application code changes.

One filesystems.php Across Environments

One S3 configuration
's3' => [    'driver' => 's3',     'key' =>        env('AWS_ACCESS_KEY_ID'),     'secret' =>        env('AWS_SECRET_ACCESS_KEY'),     'region' =>        env('AWS_DEFAULT_REGION'),     'bucket' =>        env('AWS_BUCKET'),     'endpoint' =>

There is no current-environment check in this file.

There is no dedicated minio disk for local development and a separate s3 disk for production.

There is one s3 disk whose values come from the environment.

The environment decides which server, bucket, and credentials are used.

I Avoid if local Branches in Filesystem Configuration

Configuration knows about a specific environment
'endpoint' => app()->environment('local')    ? 'http://minio:9000'    : null, 'use_path_style_endpoint' =>    app()->environment('local'),

This code can work, but it moves knowledge about local MinIO into general application configuration.

Later there may be another environment, another S3-compatible provider, or another deployment target, and the branching grows.

I prefer keeping configuration declarative: Laravel reads values instead of deciding which environment is currently active.

Only Environment Values Change Locally

Example local .env
AWS_ACCESS_KEY_ID=laradockAWS_SECRET_ACCESS_KEY=laradock AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET=local-files AWS_ENDPOINT=http://minio:9000 AWS_USE_PATH_STYLE_ENDPOINT=true

These values describe local infrastructure.

MinIO has its Docker-network endpoint, local credentials, and a local bucket.

Nothing changes in application code.

In Production the Same Disk Receives Different Values

Schematic production environment example
AWS_ACCESS_KEY_ID=<production value>AWS_SECRET_ACCESS_KEY=<production secret> AWS_DEFAULT_REGION=<region> AWS_BUCKET=<production bucket> AWS_ENDPOINT=<provider endpoint if required> AWS_USE_PATH_STYLE_ENDPOINT=<true or false>

Real production secrets, bucket names, and provider endpoints should not be committed to the repository.

The important point is that the configuration structure does not change.

Another environment simply supplies different values for the same parameters.

The Endpoint Belongs to the Environment, Not Laravel Code

Locally, AWS_ENDPOINT=http://minio:9000 makes sense because Laravel runs inside Docker.

I covered why the container uses minio:9000 instead of localhost separately.

Another environment may use a different endpoint or may not need an explicit AWS_ENDPOINT when the driver uses the provider default.

Laravel application code does not need to know why those values differ.

Credentials Are Environment Data Too

Local MinIO credentials may be simple values intended only for development.

Production secrets should be stored according to the deployment environment security rules.

In both cases Laravel reads them through the same configuration keys.

Application code does not access AWS_SECRET_ACCESS_KEY directly or make decisions based on it.

The Bucket Can Change Without Code Changes

Different buckets, the same file code
Local AWS_BUCKET=local-files        |        vMinIO bucket  Production AWS_BUCKET=<production bucket>        |        vProduction storage  

Addressing Mode Is Environment Configuration Too

Local MinIO at minio:9000 works conveniently with AWS_USE_PATH_STYLE_ENDPOINT=true.

Another provider may have different requirements.

This is another reason not to hardcode the addressing mode into filesystems.php as a special MinIO case.

File Operations Stay the Same

The same code in every environment
Storage::disk('s3')->put(    $path,    $contents,); $contents = Storage::disk('s3')->get(    $path,); Storage::disk('s3')->delete(    $path,);

This is the main sign that the boundary is in the right place.

Store, read, and delete operations should not need to know whether the application is running locally.

They use the s3 disk. The environment configuration handles the rest.

A Separate minio Disk Often Only Duplicates s3

Two nearly identical disks
'minio' => [    'driver' => 's3',    // ...], 's3' => [    'driver' => 's3',    // ...],

A separate disk can make sense when the application intentionally uses two storage systems at the same time.

But if MinIO only replaces production S3-compatible storage locally, a second disk creates an unnecessary difference between environments.

Local code then uses minio while production uses s3, even though they represent the same application dependency.

I keep one disk name and change only its infrastructure parameters.

After Environment Changes I Check Laravel Configuration Cache

Clear local configuration cache
php artisan config:clear

If .env has changed but Laravel still contacts the old endpoint, I check the configuration cache.

This is especially easy to miss while switching from local storage to S3-compatible storage.

I Verify Laravel's Resolved Configuration, Not Only .env

What Laravel Actually Sees
config(    'filesystems.disks.s3.endpoint',); config(    'filesystems.disks.s3.bucket',); config(    'filesystems.disks.s3.use_path_style_endpoint',);

The .env file alone does not prove that application configuration is correct.

During debugging I inspect the resolved filesystems.disks.s3 values.

This makes it easier to separate a configuration problem from Docker networking or storage connectivity.

What Stays Stable and What Changes

Boundary Between Code and Environment
Stays the same: - driver = s3- disk name = s3- Storage::disk('s3')- application code- file-handling rules  Changes by environment: - endpoint- credentials- region- bucket- path-style setting

What I Check Before Adding Separate Local Configuration

My short checklist:

  • Do local and production storage support the same S3 contract?
  • Is a second disk actually necessary?
  • Can one driver=s3 remain in place?
  • Can the endpoint come from the environment?
  • Are credentials kept out of the repository?
  • Is the bucket name supplied externally?
  • Is addressing mode configurable as well?
  • Is there no if local in application code?
  • Does every environment use the same Storage::disk('s3') contract?

The Environment Changes Values, Not Application Structure

For me, local MinIO is not a separate Laravel operating mode.

It is another implementation of the same infrastructure dependency.

I therefore do not add a separate minio disk, branch filesystems.php by environment, or add local-storage-specific application code.

Laravel continues using the standard s3 disk.

Only the endpoint, credentials, bucket, and addressing mode change locally.

When the contract stays the same, environment differences should stay in configuration rather than spreading through application code.

A local environment should place different infrastructure behind the same contract rather than make the application follow different rules.