<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Vodnyy</title>
    <description>The latest articles on Forem by Vodnyy (@vodnyy).</description>
    <link>https://forem.com/vodnyy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1903134%2F404df3e9-fe3b-47e7-b26a-21ae12a9f8ee.jpg</url>
      <title>Forem: Vodnyy</title>
      <link>https://forem.com/vodnyy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vodnyy"/>
    <language>en</language>
    <item>
      <title>Upload image with NestJS Minio S3</title>
      <dc:creator>Vodnyy</dc:creator>
      <pubDate>Fri, 13 Feb 2026 07:47:29 +0000</pubDate>
      <link>https://forem.com/vodnyy/upload-image-with-nestjs-minio-s3-19ml</link>
      <guid>https://forem.com/vodnyy/upload-image-with-nestjs-minio-s3-19ml</guid>
      <description>&lt;p&gt;MinIO - is a cloud-native object store built to run on any infrastructure - public, private or edge clouds. Primary use cases include data lakes, databases, AI/ML, SaaS applications and fast backup &amp;amp; recovery. MinIO is dual licensed under GNU AGPL v3 and commercial license. To learn more, visit &lt;a href="http://www.min.io" rel="noopener noreferrer"&gt;www.min.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Create new project &lt;code&gt;nest new minio-example&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Download packages &lt;code&gt;npm i nestjs-minio-s3 @nestjs/config multer&lt;/code&gt;, and &lt;code&gt;npm i --save-dev @types/multer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Set docker environment variables in &lt;code&gt;.docker.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MINIO_ROOT_USER="minioadmin"
MINIO_ROOT_PASSWORD="minioadmin"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt; Add file docker-compose.yml and new Minio container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  minio:
    image: minio/minio:latest
    container_name: minio
    ports:
      - '9000:9000'
      - '9001:9001'
    env_file:
      - .docker.env
    command: server /data --console-address ":9001"
    volumes:
      - minio:/data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

volumes:
  minio:
    driver: local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt; Start container &lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.&lt;/strong&gt; Add global environment variables in &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MINIO_HOST="localhost"
MINIO_PORT=9000
MINIO_SSL=false
MINIO_USER="minioadmin"
MINIO_PASSWORD="minioadmin"
MINIO_REGION="us-east-1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7.&lt;/strong&gt; Include &lt;code&gt;MinioModule&lt;/code&gt;in AppModule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import {MinioModule} from "nestjs-minio-s3";
import {ConfigModule, ConfigService} from "@nestjs/config";

import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    MinioModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) =&amp;gt; ({
        host: configService.get('MINIO_HOST')!,
        port: +configService.get('MINIO_PORT')!,
        useSSL: configService.get('MINIO_SSL') === 'true',
        accessKey: configService.get('MINIO_USER')!,
        secretKey: configService.get('MINIO_PASSWORD')!,
        region: configService.get('MINIO_REGION') || 'us-east-1',
      }),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;8.&lt;/strong&gt; Add new files &lt;code&gt;AvatarsModule&lt;/code&gt;, &lt;code&gt;AvatarsService&lt;/code&gt;, &lt;code&gt;AvatarsController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.&lt;/strong&gt; Use &lt;code&gt;MinioModule.forFeature&lt;/code&gt;for creating new &lt;em&gt;Buckets S3&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Module} from "@nestjs/common";

import {AvatarsService} from "./avatars.service";
import {AvatarsController} from "./avatars.controller";
import {MinioModule} from "nestjs-minio-s3";

@Module({
    imports: [MinioModule.forFeature({bucketName: 'avatars', policy: 'public'})],
    providers: [AvatarsService],
    controllers: [AvatarsController],
})
export class AvatarsModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;10.&lt;/strong&gt; Use &lt;code&gt;@InjectBucket()&lt;/code&gt;in your services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Injectable} from "@nestjs/common";
import {InjectBucket} from "nestjs-minio-s3/dist/decorators/inject-bucket.decorator";
import {MinioService} from "nestjs-minio-s3";

@Injectable()
export class AvatarsService {
    constructor(@InjectBucket() private readonly bucketName: string,
                private readonly minioService: MinioService) {
    }

    async uploadAvatar(file: Express.Multer.File) {
        const key = `${Date.now()}.${file.originalname.split('.').pop()}`;

        return this.minioService.upload(
            this.bucketName,
            key,
            file.buffer,
            file.mimetype,
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;11.&lt;/strong&gt; And implementing method upload image in controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Controller, Post, UploadedFile, UseInterceptors} from "@nestjs/common";
import type {Express} from 'express';

import {AvatarsService} from "./avatars.service";
import {FileInterceptor} from "@nestjs/platform-express";

@Controller('avatars')
export class AvatarsController {
    constructor(private readonly avatarsService: AvatarsService) {}

    @Post()
    @UseInterceptors(FileInterceptor('avatar'))
    uploadAvatar(@UploadedFile() file: Express.Multer.File) {
        return this.avatarsService.uploadAvatar(file);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;12.&lt;/strong&gt; After completing the request, view the changes at the address &lt;a href="http://localhost:9001" rel="noopener noreferrer"&gt;http://localhost:9001&lt;/a&gt; with authorization data: username: &lt;code&gt;minioadmin&lt;/code&gt;, password: &lt;code&gt;minioadmin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Minio package: &lt;a href="https://www.npmjs.com/package/nestjs-minio-s3" rel="noopener noreferrer"&gt;nestjs-minio-s3&lt;/a&gt;.&lt;br&gt;
GitHub Repository this example: &lt;code&gt;https://github.com/Vodnyy143/nestjs-minio-example.git&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>tutorial</category>
      <category>docker</category>
      <category>nestjs</category>
    </item>
  </channel>
</rss>
