使用 MinIO + Nginx + dotnet core 搭建图床

一开始看了一篇使用阿里云 OSS 搭建图床的文章,于是有了使用 OSS 搭建图床的想法,但我不想用现成的 OSS,后来想到之前使用过免费的 Minio: Setup private object storage using MinIO,遂用之

首先搜索了一下,发现已经有人实现过了:Minio+Nginx搭建图床一键上传博客图片,实话实说,吸取了链接文章的部分经验

环境

  • Ubnutu 18.04
    • docker
  • Windows 10 Pro 1909
    • VS 2019
    • dotnet core 3.1.302

参考

步骤

MinIO 负责图片的存储,Nginx 负责展示图片,dotnet core 编写程序负责上传图片到 MinIO

使用 Typora 作为 Markdown 编辑器,并设置 Typora 在插入图片时自动上传

搭建 MinIO

详情可见 Setup private object storage using MinIO ,这里选用 docker,复读一遍:

  1. 下载镜像
    • 执行指令
      sudo docker pull minio/minio
  2. 启动容器
    • 执行指令
      docker run -d -p 9000:9000 --name minio1 \
        -e "MINIO_ACCESS_KEY=[your username]" \
        -e "MINIO_SECRET_KEY=[your password]" \
        -v /home/azhuge233/minio-data:/data \
        minio/minio server /data

      路径映射可以自行更改,我在主目录新建了 minio-data 文件夹作为 minio 存储路径

    • MinIO 界面

配置 Nginx

上传到 MinIO 的图片是无法直接在浏览器查看的,MinIO 只能够上传、存储和下载,所以需要网页服务器代理

  1. 新建配置文件
    • 在 /etc/nginx/sites-available 下新建配置文件 minio,写入以下内容
      server{
          listen 80;
          server_name _;
          location / {
              root /home/azhuge233/minio-data/;    
          }
      }

      其中监听端口、服务器名称和根目录可自行更改

    • 新建软链接,执行指令
      sudo ln -s /etc/nginx/sites-available/minio /etc/nginx/sites-enabled/
  2. 测试并重启 nginx
    • 执行指令
      sudo nginx -t
      sudo nginx -s reload
  3. 测试效果

编写上传图片程序

使用 dotnet core 3.1,需要 nuget 安装 MinIO SDK

可以通过修改项目的 .csproj 配置文件中的 RuntimeIdentifier ,使项目编译为 macOS、Linux 版本

以下为代码:

using System;
using System.IO;
using System.Threading.Tasks;
using Minio;
using Minio.Exceptions;

namespace Minio_Console {
    class Program {
        static void Main(string[] args) {

            #region Check Path Valid
            if (args.Length < 1) {
                Console.WriteLine(" Please specify a path.");
                Console.ReadLine();
                return;
            } else if (args.Length > 1) {
                Console.WriteLine("Only one picture can be transfered at a time.");
                Console.ReadLine();
                return;
            }

            string picPath = Path.GetFullPath(args[0]);
            if (!Path.HasExtension(picPath)) {
                Console.WriteLine("Please enter a valid path.");
                Console.ReadLine();
                return;
            }
            #endregion

            #region Upload Picture
            try {
                var minio = new MinioClient( //MinIO 客户端实例
                    "192.168.10.22:9000", //MinIO 地址
                    "azhuge233", //MinIO AccessKey
                    "VeryStrongPassword" //MinIO SercretKey
                    );
                Program.Upload(minio, picPath).Wait();
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
            }
            #endregion
        }

        private async static Task Upload(MinioClient minio, string picPath) {
            string bucketName = "pictures";
            string objectName = Path.GetFileName(picPath);
            try {
                bool isExist = await minio.BucketExistsAsync(bucketName);
                if (!isExist) {
                    await minio.MakeBucketAsync(bucketName);
                }
                await minio.PutObjectAsync(bucketName, objectName, picPath);
                Console.WriteLine("Picture Upload Success.");
            } catch (MinioException ex) {
                Console.WriteLine("Picture Upload Error: [0]", ex.Message);
            }
        }
    }
}

其中,需要根据自身情况修改 MinIO 客户端实例化处的变量

控制台输出会引发一个不影响使用的 bug feature,下文会提到

设置Typora

在 Typora 内打开偏好设置,按下图设置

效果

如果在程序内输出提示性的文字,例如在上传成功后输出“Picture Upload Success”,Typora 会认为图片上传失败,如下图:

实际上是成功的

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据