欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用docker創(chuàng)建minio鏡像并上傳文件并提供demo

 更新時(shí)間:2023年09月21日 10:18:03   作者:天河歸來(lái)  
這篇文章主要介紹了使用docker創(chuàng)建minio鏡像并上傳文件,提供demo,minio還是很方便的,從部署到使用,都可以非??焖俚拇罱?而且比較穩(wěn)定,需要的朋友可以參考下

使用docker創(chuàng)建minio鏡像并上傳文件,提供demo

1. 整體描述

MinIO是一個(gè)對(duì)象存儲(chǔ)解決方案,它提供了一個(gè)Amazon Web Services S3兼容的API,并支持所有S3的核心特性。MinIO可以部署在任何地方——公共云或私有云、裸機(jī)基礎(chǔ)設(shè)施、編排環(huán)境和邊緣基礎(chǔ)設(shè)施。

本文檔介紹MinIO最新穩(wěn)定版本RELEASE.2023-09-04T19-57-37Z在Windows平臺(tái)上部署MinIO的操作、管理和開(kāi)發(fā)。

上面是官網(wǎng)介紹,用有道翻譯的,官網(wǎng)地址: 鏈接。

2. 環(huán)境搭建

使用docker搭建minio環(huán)境,可以直接用官網(wǎng)下載minio鏡像,我們先用windows環(huán)境搭建一下。

2.1 windows環(huán)境搭建

在官網(wǎng)下載頁(yè)面,選擇windows,下載的是一個(gè)minion.exe文件。我放在了d:/minio目錄下,在此再創(chuàng)建一個(gè)data文件夾,用來(lái)儲(chǔ)存minio上傳的文件。然后在命令行執(zhí)行如下指令啟動(dòng)minio:

setx MINIO_ROOT_USER minioadmin
setx MINIO_ROOT_PASSWORD minioadmin
D:\minio\minio.exe server D:\minio\data\ --console-address ":9001"

看到如下就說(shuō)明啟動(dòng)成功了:

然后通過(guò)瀏覽器訪問(wèn):http://localhost:9001/進(jìn)入如下登錄頁(yè)面:默認(rèn)用戶名和密碼都是minioadmin

2.2 docker部署

使用docker部署就更簡(jiǎn)單了,首先拉取官方鏡像:

docker pull minio/minio

拉取成功之后,執(zhí)行創(chuàng)建和啟動(dòng)容器:

docker run -p 9000:9000 -p 9001:9001 minio/minio server /data --console-address ":9001"

看到如下就說(shuō)明啟動(dòng)成功:

同樣通過(guò)瀏覽器訪問(wèn):http://localhost:9001/進(jìn)入如下登錄頁(yè)面:默認(rèn)用戶名和密碼都是minioadmin

3. spring集成

通過(guò)springboot框架集成minio,實(shí)現(xiàn)上傳文件的目的。

3.1 添加依賴

首先創(chuàng)建一個(gè)springboot工程,添加如下依賴:

<!-- lombok 自動(dòng)生成方法-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
        <!--io常用工具類 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
        <!--常用工具類 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- minio-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.4.6</version>
        </dependency>

3.2 配置文件

在springboot的yml配置文件中添加minio環(huán)境的配置:

#minio相關(guān)配置
minio:
  endpoint: http://127.0.0.1:9000
  accessKey: minioadmin
  secretKey: minioadmin

3.3 創(chuàng)建config類

package com.thcb.miniodemo.config;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
 * MinioUtil
 *
 * @author thcb
 * @date 2023-09-05
 */
@Component
public class MinioClientConfig {
    @Value("${minio.endpoint}")
    private String endpoint;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;
    /**
     * 注入minio 客戶端
     *
     * @return
     */
    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }
}

3.4 創(chuàng)建minio操作類

minio操作類,用來(lái)寫(xiě)minio基礎(chǔ)方法

package com.thcb.miniodemo.minio;
import com.thcb.miniodemo.utils.*;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
 * MinioUtil
 *
 * @author thcb
 * @date 2023-09-05
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class MinioUtil {
    private final MinioClient minioClient;
    /**
     * 兩票數(shù)據(jù)桶
     */
    public static String TEST_BUCKET = "test";
    private static String POLICY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::%s\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::%s/*\"]}]}";
    public void initMinIo() {
        log.warn("start initMinIo.");
        if (!bucketExists(TEST_BUCKET)) {
            log.warn("start makeBucket {}.", TEST_BUCKET);
            makeBucket(TEST_BUCKET);
            log.warn("finish makeBucket {}.", TEST_BUCKET);
        }
        try {
            log.warn("start setBucketPolicy {}.", TEST_BUCKET);
            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(TEST_BUCKET).config(String.format(POLICY, TEST_BUCKET, TEST_BUCKET)).build());
            log.warn("finish setBucketPolicy {}.", TEST_BUCKET);
        } catch (Exception e) {
            log.error("setBucketPolicy from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
        }
    }
    /**
     * 查看存儲(chǔ)bucket是否存在
     *
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("bucketExists from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
            return false;
        }
        return found;
    }
    /**
     * 創(chuàng)建存儲(chǔ)bucket
     *
     * @return Boolean
     */
    public synchronized Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            log.error("makeBucket from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
            return false;
        }
        return true;
    }
    /**
     * 刪除存儲(chǔ)bucket
     *
     * @return Boolean
     */
    public synchronized Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            log.error("removeBucket from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
            return false;
        }
        return true;
    }
    /**
     * 獲取全部bucket
     */
    public List<Bucket> getAllBuckets() {
        try {
            List<Bucket> buckets = minioClient.listBuckets();
            return buckets;
        } catch (Exception e) {
            log.error("getAllBuckets from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
        }
        return null;
    }
    /**
     * 文件上傳
     *
     * @param file       文件
     * @param bucketName 桶名稱
     * @return Boolean
     */
    public synchronized String upload2Bucket(MultipartFile file, String bucketName) {
        return String.format("/%s/%s", bucketName, upload(file, bucketName));
    }
    /**
     * 文件上傳
     *
     * @param file       文件
     * @param bucketName 桶名稱
     * @return Boolean
     */
    public synchronized String upload(MultipartFile file, String bucketName) {
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)) {
            throw new CustomException("文件格式錯(cuò)誤");
        }
        String fileName = UUIDUtil.UUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = DateUtils.dateTimeNow(DateUtils.YYYYMMDD) + "/" + fileName;
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名稱相同會(huì)覆蓋
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            log.error("upload file to minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
            return null;
        }
        return objectName;
    }
    /**
     * 文件上傳
     *
     * @param file 文件
     * @return Boolean
     */
    public synchronized String upload(MultipartFile file) {
        return upload(file, TEST_BUCKET);
    }
    /**
     * 預(yù)覽
     *
     * @param fileName
     * @return
     */
    public String preview(String fileName) {
        return preview(fileName, TEST_BUCKET);
    }
    /**
     * 預(yù)覽
     *
     * @param fileName
     * @param bucketName 桶名稱
     * @return
     */
    public String preview(String fileName, String bucketName) {
        // 查看文件地址
        GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build();
        try {
            String url = minioClient.getPresignedObjectUrl(build);
            return url;
        } catch (Exception e) {
            log.error("preview file to minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
        }
        return null;
    }
    /**
     * 文件下載
     *
     * @param fileName         文件名稱
     * @param originalFileName 原文件名稱
     * @param res              response
     * @return Boolean
     */
    public void download(String fileName, String originalFileName, HttpServletRequest req, HttpServletResponse res) {
        download(fileName, TEST_BUCKET, req, res);
    }
    /**
     * 文件下載
     *
     * @param fileName         文件名稱
     * @param bucketName       桶名稱
     * @param originalFileName 原文件名稱
     * @param res              response
     * @return Boolean
     */
    public void download(String fileName, String bucketName, String originalFileName, HttpServletRequest req, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
                .object(fileName).build();
        try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                while ((len = response.read(buf)) != -1) {
                    os.write(buf, 0, len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                String type = req.getHeader("User-Agent").toLowerCase();
                String firefox = "firefox", chrome = "chrome";
                String encodedFileName;
                if (type.indexOf(firefox) > 0 || type.indexOf(chrome) > 0) {
                    encodedFileName = new String(originalFileName.getBytes(StandardCharsets.UTF_8), "iso8859-1");
                } else {
                    encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name());
                }
                // 設(shè)置強(qiáng)制下載不打開(kāi)
                // res.setContentType("application/force-download");
                // res.setContentType("application/octet-stream");
                res.setContentType(FileDownloadUtils.getFileContentType(fileName));
                res.addHeader("Content-Disposition", "attachment;fileName=" + encodedFileName + ";filename*=utf-8''" + encodedFileName);
                res.addHeader("Content-Length", bytes.length + "");
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
            res.flushBuffer();
        } catch (Exception e) {
            log.error("download file from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
        }
    }
    /**
     * 刪除
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    public boolean remove(String fileName) {
        return remove(fileName, TEST_BUCKET);
    }
    /**
     * 刪除
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    public synchronized boolean remove(String fileName, String bucketName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            log.error("remove file from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));
            return false;
        }
        return true;
    }
}

3.5 創(chuàng)建啟動(dòng)類

在springboot啟動(dòng)成功后連接minio

package com.thcb.miniodemo.listener;
import com.thcb.miniodemo.minio.MinioUtil;
import com.thcb.miniodemo.utils.ExceptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
 * ApplicationReadyListener
 *
 * @author thcb
 * @date 2023-09-05
 */
@Component
public class ApplicationReadyListener implements ApplicationListener<ApplicationReadyEvent> {
    private static final Logger log = LoggerFactory.getLogger(ApplicationReadyListener.class);
    @Autowired
    private MinioUtil minioUtil;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        try {
            doPostConstruct();
        } catch (Exception e) {
            log.error("e={}", ExceptionUtil.getExceptionMessage(e));
        }
    }
    private void doPostConstruct() {
        log.info("initMinIo");
        initMinIo();
    }
    /**
     * 初始化minio桶文件
     */
    private void initMinIo() {
        minioUtil.initMinIo();
    }
}

3.6 測(cè)試controller

寫(xiě)一個(gè)測(cè)試的controller,測(cè)試minio相關(guān)功能

package com.thcb.miniodemo.controller;
import com.thcb.miniodemo.minio.MinioUtil;
import com.thcb.miniodemo.utils.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
 * TestController
 *
 * @author thcb
 * @date 2023-09-05
 */
@RestController
@RequestMapping("/TestController")
public class TestController {
    private static final Logger log = LoggerFactory.getLogger(TestController.class);
    @Autowired
    private MinioUtil minioUtil;
    @RequestMapping("/test")
    @ResponseBody
    public String test() {
        return "test success";
    }
    @PostMapping("/uploadFile")
    public AjaxResult uploadFile(MultipartFile file) throws Exception {
        try {
            String pathUrl = minioUtil.upload2Bucket(file, MinioUtil.TEST_BUCKET);
            return AjaxResult.success(pathUrl);
        } catch (Exception e) {
            return AjaxResult.error(e.toString());
        }
    }
}

4. 測(cè)試操作

4.1 demo運(yùn)行

運(yùn)行工程,如下log說(shuō)明連接成功:

4.2 頁(yè)面查看

運(yùn)行完成,在頁(yè)面應(yīng)該能看到我們創(chuàng)建的桶:

4.3 上傳文件

使用postman調(diào)用我們寫(xiě)的測(cè)試接口,上傳一個(gè)文件到minio

上傳成功,在頁(yè)面上也可以看到這個(gè)文件:

4.4 預(yù)覽/下載文件

如果上傳的是圖片,通過(guò)返回的url,瀏覽器可以直接訪問(wèn)預(yù)覽,如果是其他類型的文件,是可以通過(guò)這個(gè)返回的url進(jìn)行下載的:http://localhost:9000/test/20230908/2b31664c4a004a5cb4b2934ebf5300cd.jpg

5. demo下載

minio的demo已經(jīng)上傳到csdn,需要的可以自行下載,在本文基本也把主要的核心代碼都貼出來(lái)了,這個(gè)demo使用的是springboot框架,加了一些工具類,可以直接拿來(lái)用,或者新工程改個(gè)名字就能用了。demo結(jié)構(gòu)截圖:

demo工程地址:demo下載地址,傳到了gitcode上,應(yīng)該是csdn弄的一個(gè)代碼倉(cāng)庫(kù),和git差不多。

6. 總結(jié)

minio還是很方便的,從部署到使用,都可以非??焖俚拇罱?,而且比較穩(wěn)定。

到此這篇關(guān)于使用docker創(chuàng)建minio鏡像并上傳文件,提供demo的文章就介紹到這了,更多相關(guān)docker創(chuàng)建minio鏡像內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 更改Docker默認(rèn)數(shù)據(jù)目錄解決部署空間不足問(wèn)題

    更改Docker默認(rèn)數(shù)據(jù)目錄解決部署空間不足問(wèn)題

    隨著使用 Docker 的時(shí)間增加,存儲(chǔ)在默認(rèn)數(shù)據(jù)目錄(通常是 /var/lib/docker)中的數(shù)據(jù)量也會(huì)不斷增大,最終可能導(dǎo)致服務(wù)器上的存儲(chǔ)空間不足,這篇文章將詳細(xì)介紹如何更改 Docker 的默認(rèn)數(shù)據(jù)目錄,以便在服務(wù)器上釋放存儲(chǔ)空間并優(yōu)化資源利用,需要的朋友可以參考下
    2024-06-06
  • 使用?Docker?部署?RStudio?的完美教程

    使用?Docker?部署?RStudio?的完美教程

    在數(shù)據(jù)科學(xué)和統(tǒng)計(jì)分析中,RStudio是重要的IDE,但傳統(tǒng)安裝可能復(fù)雜,Docker提供了容器化技術(shù),簡(jiǎn)化了RStudio的部署,本文介紹使用Docker部署RStudio的方法,包括環(huán)境準(zhǔn)備、拉取鏡像、創(chuàng)建容器命令等步驟,幫助用戶快速搭建穩(wěn)定高效的RStudio環(huán)境
    2024-09-09
  • 修改已有docker容器中的內(nèi)容方法

    修改已有docker容器中的內(nèi)容方法

    這篇文章主要介紹了修改已有docker容器中的內(nèi)容方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 詳解如何將java項(xiàng)目打包成docker鏡像并且可運(yùn)行

    詳解如何將java項(xiàng)目打包成docker鏡像并且可運(yùn)行

    java?項(xiàng)目打包成?Docker?可運(yùn)行的鏡像,其目的是便于運(yùn)用docker容器來(lái)管理項(xiàng)目,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2024-11-11
  • 通過(guò)idea打包項(xiàng)目到docker的操作方法

    通過(guò)idea打包項(xiàng)目到docker的操作方法

    這篇文章主要介紹了通過(guò)idea打包項(xiàng)目到docker的操作方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • docker部署rabbitmq集群的實(shí)現(xiàn)方法

    docker部署rabbitmq集群的實(shí)現(xiàn)方法

    這篇文章主要介紹了docker部署rabbitmq集群的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • docker 免root權(quán)限登陸的解決方案

    docker 免root權(quán)限登陸的解決方案

    這篇文章主要介紹了docker 免root權(quán)限登陸的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • docker中修改鏡像容器的存放目錄的方法

    docker中修改鏡像容器的存放目錄的方法

    本篇文章主要介紹了docker中修改鏡像容器的存放目錄的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • 如何修改Docker鏡像的映射端口號(hào)

    如何修改Docker鏡像的映射端口號(hào)

    這篇文章主要介紹了如何修改Docker鏡像的映射端口號(hào)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Docker容器實(shí)現(xiàn)MySQL多源復(fù)制場(chǎng)景分析

    Docker容器實(shí)現(xiàn)MySQL多源復(fù)制場(chǎng)景分析

    這篇文章主要介紹了Docker容器實(shí)現(xiàn)MySQL多源復(fù)制,通過(guò)本文學(xué)習(xí)可以掌握多源復(fù)制的好處,通過(guò)使用場(chǎng)景分析給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06

最新評(píng)論