这是一篇与随后准备写的部署Mastodon实例相关的文章。
S3是Simple Storage Service的缩写,是亚马逊提供的一种云存储模式,目前已是一种主流的云存储,大多数前端服务都支持S3接入,大多数的商业云存储服务也都兼容S3。
商业云存储目前大多数都是付费模式,个别限时或限量的免费体验版整体来说使用起来都不很自由。
借助开源软件的免费优势,我们今天来尝试在家庭服务器上部署自托管的MinIO对象存储服务。MinIO本身是兼容S3的,作为一种低成本解决方案,一旦部署好就可以基本替代商业云存储。要注意的是,低成本不代表无成本,基本替代也很难成为完美替代。
首先我们家中需要一台服务器(或者是服务器上的虚拟机)和一个域名。另外家庭宽带也需要公网IP,宽带上下行速度会直接影响文件传输速度。如果没有公网IP想用frp穿透的话,其数据传输速度自然会更加受影响,所以建议要有公网IP。后面会以安装好Docker的Debian/Ubuntu系统举例,当然你要用Podman也没问题。
先使用路由器的动态DNS(DDNS)功能把家庭宽带的公网IP自动更新到域名托管的DNS服务。然后再用路由器防火墙的端口映射功能把WAN口的9000端口映射到你服务器的9000端口。
然后再服务器里建立工作文件夹,并生成MinIO的配置文件
mkdir minio
cd minio
vim minioconfig
将如下内容按实际修改后粘贴进去。MinIO更多的环境变量可以参见这里。
# MINIO_ROOT_USER 和 MINIO_ROOT_PASSWORD 设置 MinIO 服务器的 root 帐户。
# 该用户拥有对部署中的任何资源执行 S3 和管理 API 操作的不受限制的权限。
# 如将其备注掉不设置则使用默认值“minioadmin:minioadmin”。
# MinIO 建议设置非默认值作为最佳实践,无论环境如何
MINIO_ROOT_USER=myminioadmin
MINIO_ROOT_PASSWORD=minio-secret-key-change-me
# MINIO_VOLUMES 设置用于 MinIO 服务器的存储卷或路径。
MINIO_VOLUMES="/mnt/data"
# MINIO_SERVER_URL 设置与 MinIO 服务器一起使用的本地计算机的主机名
# MinIO 假设您的网络控制界面可以正确将此主机名解析到本地计算机
# 取消注释以下行,并将该值替换为本地计算机的正确主机名和 MinIO 服务器的端口(默认为 9000)。
# 如https://你的域名:9000
#MINIO_SERVER_URL="https://minio.example.net:9000"
填入之后保存退出vim,之后来准备Docker Compose文件
vim docker-compose.yml
我们部署一个单节点单驱动的实例,进入编辑界面后把下面的内容按实际修改后填入
version: '2'
services:
minio:
container_name: minio
command: server --console-address ":9090"
environment:
- MINIO_CONFIG_ENV_FILE=/etc/config.env
image: quay.io/minio/minio:latest
volumes:
- ./data:/mnt/data
- ./minioconfig:/etc/config.env
restart: always
ports:
- "9001:9000"
- "9090:9090"
这里设定工作文件夹下的data文件夹是整个存储的目录,你可以按需求把第11行冒号前面的./data修改成你想要的目录。或者你可以在工作目录下建立一个名为data的链接到你想要的目标目录。也可以用nfs协议把内网其他位置的硬盘目录映射到这个data上,总之按你的需要来处理存储位置的设置。同时为了后面使用NGINX来实现反向代理端口,容器的9000端口先映射到主机的9001端口了。
保存退出后就可以下载镜像生成容器了
docker compose up -d
容器顺利生成并启动后,我们来配置NGINX,首先设置站点配置文件
vim /etc/nginx/sites-available/minio
将下面的内容贴入编辑界面
server {
listen 9000 ssl default_server;
listen [::]:9000 ssl default_server;
include snippets/snakeoil.conf;
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
server_name _;
# To allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 1000m;
# To disable buffering
proxy_buffering off;
proxy_request_buffering off;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://127.0.0.1:9001;
}
}
这里我们假定了证书的储存位置是/etc/nginx/snippets/snakeoil.conf写的
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
如果你希望是别的位置请修改相应的内容。保存退出后使用ln命令将其链接到enabled文件夹,并删掉其中的default配置
ln -s /etc/nginx/sites-available/minio /etc/nginx/sites-enabled/
rm /etc/nginx/sites-enabled/default
然后我们使用acme.sh的DNS API功能来申请证书,使用DNS API申请证书不需要80端口,非常适合国内家庭宽带申请证书,而且acme.sh也支持大量的DNS服务商。具体的申请方法可参见这篇文章的前半部分。
证书设置完毕后就可以重启NGINX了,也可以先用nginx -t来检查一下配置是否正确。这里我只把MinIO的服务端口9000映射到了公网,而网页控制台的9090端口依然还在内网,从而确保服务的安全。如果你需要在外网访问的话可以考虑使用Tailscale之类的服务来远程访问这台主机的端口。
最后我们用这台服务器的内网IP加9090端口在浏览器上就可以访问MinIO的网页控制台,使用minioconfig中设置的用户名和密码登录即可。
完