MoreRSS

site iconLala | 荒岛修改

一个应用分享、教程类的博客,主要是那些需要自部署的。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Lala | 荒岛的 RSS 预览

自建开源SSO(单点登录)身份验证服务:VoidAuth

2026-01-12 16:49:46

VoidAuth是一款开源的SSO身份验证和用户管理软件,可为您的自托管应用程序保驾护航,并支持诸多实用功能,例如Passkey登录、邀请注册、自助注册、电子邮件支持等等。

VoidAuth特点(摘自项目文档):

🌐 OpenID Connect (OIDC) Provider
🔄 Proxy ForwardAuth
👤 User and Groups Management
📨 User Self-Registration and Invitations
🎨 Customizable (Logo, Title, Theme Color, Email Templates)
🔑 Multi-factor Authentication, Passkeys, and Passkey-Only Accounts
📧 Secure Password Reset with Email Verification
🔒 Encryption-At-Rest with Postgres or SQLite Database

其实类似VoidAuth这样开源并且支持自建的SSO程序有很多,在接触VoidAuth之前,我部署过很多个,这里就不详细说了。我只想简单谈一下个人体验,我用过的这些软件里面或多或少都有这样的问题:安装和配置非常复杂、程序本身设计的过于臃肿,对于个人自托管爱好者而言(个人用户),甚至有很多用不到的功能,而VoidAuth完美的解决了上述问题,它非常轻量且易于使用。

VoidAuth最让我觉得好用的一个功能是ProxyAuth(转发认证),我自建的这些服务里面并不是所有都原生支持OIDC的,对于那些不支持OIDC的应用程序,我现在可以通过ProxyAuth来实现SSO,真正做到了一个账号登录所有服务。

这篇文章记录下VoidAuth安装以及OIDC、ProxyAuth的配置。

安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录新建compose文件:

mkdir /opt/voidauth && cd /opt/voidauth && nano docker-compose.yml

写入如下内容:

services:
  voidauth: 
    image: voidauth/voidauth:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - ./voidauth/config:/app/config
    environment:
      APP_URL: https://voidauth.example.com # 设置你的域名
      APP_PORT: 3001
      STORAGE_KEY: JW8G+gr2sa8vuStV2F/6rR7VeqvarijvogwvE8jIDD0= # 使用openssl rand -base64 32命令生成
      DB_PASSWORD: yourdbpassword # 设置数据库密码
      DB_HOST: voidauth-db
      SIGNUP: false
      SIGNUP_REQUIRES_APPROVAL: true
      ENABLE_DEBUG: false
    depends_on:
      voidauth-db:
        condition: service_healthy

  voidauth-db:
    image: postgres:18
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: yourdbpassword # 设置数据库密码
    volumes:
      - db:/var/lib/postgresql/18/docker
    healthcheck:
      test: "pg_isready -U postgres -h localhost"

volumes:
  db:

启动:

docker compose up -d

默认的管理员账号与密码可通过查看容器日志获取:

docker compose logs -f

注:仅容器第一次启动会输出管理员账号与密码,后续不再显示,务必保存好。

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

voidauth.example.com {
   header "Access-Control-Allow-Origin" "*"
   proxy "http://127.0.0.1:3001/"
}

重载Ferron:

systemctl reload ferron

现在来配置ProxyAuth,让不支持OIDC的服务接入VoidAuth,实现单点登录。开始前先简单介绍一下这个功能是怎么实现的。

我现在的自托管环境,基本都是用Docker启动的服务,直接暴露服务的地址和端口,例如:127.0.0.1:5030,然后通过主机的Web Server反向代理127.0.0.1:5030,实现域名绑定、SSL证书申请、服务对外的发布(公网访问)。

VoidAuth的ProxyAuth其实就是ForwardAuth(转发认证),这个功能是需要与反向代理配合使用的,也就是说需要Web Server软件支持才行。我们配置Web Server,让服务在公网访问的时候先跳转到VoidAuth进行身份认证,认证完成后再跳转回源服务,这就是大致的流程。

现在主流的NGINX、Caddy、Traefik Web Server都是支持ForwardAuth的,如果您使用的是这类软件,可以参考VoidAuth官方的文档来配置。我目前使用的是Ferron Web Server,官方没有相应的文档,所以这里我只记录与Ferron相关的内容。

编辑Ferron配置文件:

nano /etc/ferron.kdl

加入如下配置,建议直接配置在全局(*):

* {
    trust_x_forwarded_for #true
}

根据Ferron 2.2.1版本的发布记录可以得知,这将让Ferron在默认情况下信任“X-Forwarded-For”标头,且不再覆盖X-Forwarded-Host、X-Forwarded-Proto标头,这个配置非常关键,没有这个配置Ferron将无法与VoidAuth配合使用。

假设我要保护的服务域名是:slskd.example.com,写入如下配置:

slskd.example.com {
   auth_to "https://voidauth.example.com/api/authz/forward-auth"
   auth_to_no_verification #false
   auth_to_copy "Remote-User" "Remote-Email" "Remote-Name" "Remote-Groups"
   proxy "http://127.0.0.1:5030/"
}

重载Ferron使新配置生效:

systemctl reload ferron

在VoidAuth添加需要保护的服务域名:slskd.example.com:

这样就配置好了,是不是特别简单,当用户访问slskd.example.com时,会先跳转到VoidAuth进行身份认证。

现在简单介绍一下OIDC的配置,您在VoidAuth的管理员后台点击OIDC Apps,可以查看对接服务需要用到的各种OIDC Endpoints:

然后您可以在VoidAuth的管理员后台创建一个OIDC App,这里我以Arcane Docker容器管理平台为例:

Arcane配置:

这里需要注意的是适用范围需要加上:groups,管理员声明需要配置为:groups,值配置为:auth_admins。因为我没有在VoidAuth创建新的管理员账号,默认的管理员账号(auth_admin)所属的组就是auth_admins,这样配置就可以让您以管理员的身份通过OIDC登录到Arcane。

最后,也许您可以看看VoidAuth官方的文档,他们提供了众多服务的OIDC接入指南可供参考。

Arcane:高颜值的Docker容器管理平台

2026-01-10 11:12:33

作为一个颜控,不得不说这个Arcane的前端设计的是真好看,尤其是在设置内打开了玻璃特效后,就一个词形容:精美。

其实这个项目刚出来没多久我就部署过,好像当时Gayhub的Star还没过500,确实哈,当时这个项目的完成度很低,而且有很多BUG,前端也没有现在好看。

但是但是但是,自从1.0版本作者把后端用Go重写后,这个项目似乎步入正轨了,我最近又重新部署了一遍,试用了一下,发现这个项目确实比之前强太多了,用在生产环境完全没问题。

当然就目前而言,我个人认为Arcane还是有一些小瑕疵的,比如中文翻译,有些地方翻译的不准确,但这问题不大。目前最让我不爽的是还不支持compose build指令,这意味着只能使用预构建的image,我有点纳闷的是前两天发布的新版本都支持Git Sync了为啥还不支持compose build=-=,但是看这个issue应该是计划上了,如果需要的人多,作者会考虑开发。

安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录新建compose文件:

mkdir /opt/arcane && cd /opt/arcane && nano docker-compose.yml

写入如下内容:

services:
  arcane:
    image: ghcr.io/getarcaneapp/arcane:latest
    container_name: arcane
    restart: unless-stopped
    environment:
      - APP_URL=https://arcane.example.com
      - PUID=1000
      - PGID=1000
      - ENCRYPTION_KEY=
      - JWT_SECRET=
    ports:
      - '127.0.0.1:3552:3552'
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - arcane-data:/app/data

volumes:
  arcane-data:

ENCRYPTION_KEY、JWT_SECRET可使用如下命令启动一个临时容器(运行完毕自动删除)生成:

docker run --rm ghcr.io/getarcaneapp/arcane:latest /app/arcane generate secret

启动:

docker compose up -d

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

arcane.example.com {
   proxy "http://127.0.0.1:3552/"
}

重载Ferron:

systemctl reload ferron

默认的管理员账号:arcane,密码:arcane-admin

Arcane还支持“远程环境”,也就是说你可以通过Arcane管理多台服务器的Docker,只需要在每台服务器内部署一个arcane-agent即可,具体操作见:

https://getarcane.app/docs/features/environments

如果你觉得让Arcane直接连接到Docker套接字这种部署方法不安全,也可以改为使用套接字代理,详细信息见:

https://getarcane.app/docs/setup/socket-proxy

Rote:一个看起来与众不同的个人笔记库

2026-01-06 06:07:58

Rote并不是传统意义上的笔记软件,与Obsidian、Notion这类软件有本质区别,我个人感觉Rote更像是一个类似Twitter的社交平台,或者微博客、朋友圈之类的。Rote应该更适合记录一些碎碎念,或者简短的内容。

Rote支持自建服务器,且Web UI设计的非常精美,还有iOS客户端可以使用,iOS客户端的UI也好看,说实话第一眼就喜欢上了,当时部署的时候还遇到S3配置的问题请教过作者,作者也很热心的帮忙解决。

这篇文章记录下部署过程,开始前需要准备一个S3服务,不配置S3也能用,但所有需要用到上传文件的功能都将不可用,建议还是配置一下体验完整版。

请注意目前Rote并不完全支持所有S3服务商,使用Rustfs、MinIO等S3实现可能会出现问题。目前只建议使用AWS S3/CF R2/Garage。我这里用的S3实现是Garage,有关Garage的生产环境部署可参考这篇文章

安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录新建compose文件:

mkdir /opt/rote && cd /opt/rote && nano docker-compose.yml

写入如下内容:

services:
  rote-backend:
    image: rabithua/rote-backend:latest
    pull_policy: always
    container_name: rote-backend
    environment:
      # 配置数据库连接密码,默认密码:pgpassword
      - POSTGRESQL_URL=postgresql://rote:pgpassword@rote-postgres:5432/rote
    ports:
      - "127.0.0.1:18000:3000"
    depends_on:
      rote-postgres:
        condition: service_healthy
    restart: unless-stopped
    command:
      [
        "sh",
        "-c",
        "sleep 15 && bun run dist/scripts/runMigrations.js && bun run dist/server.js",
      ]

  rote-frontend:
    image: rabithua/rote-frontend:latest
    pull_policy: always
    container_name: rote-frontend
    ports:
      - "127.0.0.1:18001:80"
    depends_on:
      - rote-backend
    environment:
      # 配置后端URL
      - VITE_API_BASE=https://rote-backend.example.com
    restart: unless-stopped

  rote-postgres:
    image: postgres:17
    container_name: rote-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: rote
      # 配置数据库连接密码,默认密码:pgpassword
      POSTGRES_PASSWORD: pgpassword
      POSTGRES_DB: rote
    volumes:
      - ./pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U rote -d rote"]
      interval: 5s
      timeout: 3s
      retries: 10
      start_period: 30s

networks:
  default:
    name: rote-network
    driver: bridge

启动Rote:

docker compose up -d

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

rote-backend.example.com {
    proxy "http://127.0.0.1:18000/"
}

rote.example.com {
    proxy "http://127.0.0.1:18001/"
}

重载Ferron:

systemctl reload ferron

如果遇到Ferron上传速度慢、上传大文件失败等问题,可参考这篇文章解决。

首次访问Rote需要初始化配置,这里先暂时跳过S3存储配置,因为这个页面不支持配置Garage S3:

初始化完成后,在管理员后台->存储设置,继续配置S3存储:

由于我们用的是Garage S3,这里的区域和URL前缀是必须要填写的。

效果如下,首页:

探索页:

个人主页:

MyTube:您的自托管YouTube,支持MissAV下载

2026-01-05 08:54:39

MyTube是一个支持YouTube、Bilibili、MissAV及yt-dlp站点的自托管视频下载器与播放器。具备频道订阅、自动下载及本地化存储功能。UI 设计精美,支持收藏集分类管理。内置Cloudflare Tunnel支持,无需端口映射即可实现安全远程访问。支持Docker一键部署。

MyTube的功能特点(摘自项目文档)

视频下载:通过简单的 URL 输入下载 YouTube、Bilibili 和 MissAV 视频。
视频上传:直接上传本地视频文件到您的库,并自动生成缩略图。
Bilibili 支持:支持下载单个视频、多 P 视频以及整个合集/系列。
并行下载:支持队列下载,可同时追踪多个下载任务的进度。
批量下载:一次性添加多个视频链接到下载队列。
并发下载限制:设置同时下载的数量限制以管理带宽。
本地库:自动保存视频缩略图和元数据,提供丰富的浏览体验。
视频播放器:自定义播放器,支持播放/暂停、循环、快进/快退、全屏和调光控制。
字幕:自动下载 YouTube / Bilibili 默认语言字幕。
搜索功能:支持在本地库中搜索视频,或在线搜索 YouTube 视频。
收藏夹:创建自定义收藏夹以整理您的视频。
订阅功能:订阅您喜爱的频道,并在新视频发布时自动下载。
登录保护:通过密码登录页面保护您的应用。
国际化:支持多种语言,包括英语、中文、西班牙语、法语、德语、日语、韩语、阿拉伯语、葡萄牙语和俄语。
分页功能:支持分页浏览,高效管理大量视频。
视频评分:使用 5 星评级系统为您的视频评分。
移动端优化:移动端友好的标签菜单和针对小屏幕优化的布局。
临时文件清理:直接从设置中清理临时下载文件以管理存储空间。
视图模式:在主页上切换收藏夹视图和视频视图。
Cookie 管理:支持上传 cookies.txt 以启用年龄限制或会员内容的下载。
yt-dlp 配置: 通过用户界面自定义全局 yt-dlp 参数、网络代理及其他高级设置。
访客模式:启用只读模式,允许查看视频但无法进行修改。非常适合与他人分享您的视频库。
云存储集成:下载后自动将视频和缩略图上传到云存储(OpenList/Alist)。
Cloudflare Tunnel 集成: 内置 Cloudflare Tunnel 支持,无需端口转发即可轻松将本地 MyTube 实例暴露到互联网。

安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录新建compose文件:

mkdir /opt/mytube && cd /opt/mytube && nano docker-compose.yml

写入如下内容:

services:
  backend:
    image: franklioxygen/mytube:backend-latest
    container_name: mytube-backend
    pull_policy: always
    restart: unless-stopped
    environment:
      - PORT=5551
      - MAX_FILE_SIZE=5000000000
    volumes:
      - ./uploads:/app/uploads
      - ./data:/app/data
  frontend:
    image: franklioxygen/mytube:frontend-latest
    container_name: mytube-frontend
    pull_policy: always
    restart: unless-stopped
    ports:
      - "5556:5556"
    depends_on:
      - backend
    environment:
      # 在大多数设置中,这些默认值都可以正常工作,不需要修改。
      - VITE_API_URL=/api
      - VITE_BACKEND_URL=

启动:

docker compose up -d

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

mytube.example.com {
    proxy "http://127.0.0.1:5556/"
    proxy_request_header_replace "Host" "{header:Host}"
}

管理员的默认密码是123,登录进去后请立即修改密码,并且关闭“允许重置密码”的功能,如果可以建议使用passkey登录:

如果遇到下载的视频分辨率太低,可以在后台自定义修改yt-dlp的配置:

-S res:2160

如果遇到下载速度慢,可以适当增加线程:

-N 15

效果:

Ferron Web Server上传速度慢、上传大文件失败解决办法

2026-01-04 14:02:39

最近在使用Ferron Web Server的时候遇到几个问题,记录下解决办法。

编辑Ferron配置文件:

nano /etc/ferron.kdl

上传速度慢,增加HTTP2窗口大小(单位字节)即可,streams(多路复用)也可以增加,但好像这个streams的配置对上传速度的影响不明显:

h2_initial_window_size 512000000
h2_max_concurrent_streams 256

上传大文件失败,浏览器控制台报错误的HTTP2协议(ERR_HTTP2_PROTOCOL_ERROR),服务器端的Ferron日志内没有有用的信息。

排查了半天发现是Ferron默认的超时时间(单位毫秒)配置太短导致,因为上传速度比较慢,触发了超时,Ferron把连接重置了,解决办法很简单把超时时间改长一点或者关闭:

timeout 21600000 // 6小时
timeout #false // 关闭

上面提到的配置建议直接应用全局:

* {
    h2_initial_window_size 512000000
    h2_max_concurrent_streams 256
    timeout 21600000
    ...
}

重载配置使其生效:

systemctl reload ferron.service

参考Ferron文档:https://ferron.sh/docs/configuration-kdl

Garage S3对象存储单节点部署指南

2025-12-30 21:32:58

本文根据官方的quick-start文档编写,着重记录、解决一些“坑点”。

Garage有一些独有的特性(后续详细介绍),初次使用可能有点难上手,但是只要你熟悉了,就和用MinIO等众多S3实现差不多了,其实我也不想多花时间去学,但是没办法啊,MinIO自己作死=-=,我知道还有一个RustFS,我也部署过,但是目前来看还是等他们发布正式版再考虑了,有些不痛不痒的小毛病用着还是有点蛋疼。

安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录新建compose文件:

mkdir /opt/garage && cd /opt/garage && nano docker-compose.yml

写入如下内容:

services:
  garage:
    image: dxflrs/garage:v2.1.0
    container_name: garage
    restart: unless-stopped
    ports:
      - 127.0.0.1:3900:3900
      - 127.0.0.1:3901:3901
      - 127.0.0.1:3902:3902
      - 127.0.0.1:3903:3903
    volumes:
      - ./garage.toml:/etc/garage.toml
      - ./meta:/var/lib/garage/meta
      - ./data:/var/lib/garage/data

新建garage.toml配置文件:

nano garage.toml

写入如下内容:

metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"

replication_factor = 1

rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = ""

[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3-garage.example.com"

[s3_web]
bind_addr = "[::]:3902"
root_domain = ".web-garage.example.com"
index = "index.html"

[k2v_api]
api_bind_addr = "[::]:3904"

[admin]
api_bind_addr = "[::]:3903"
admin_token = ""
metrics_token = ""

注意事项:

配置rpc_secret、admin_token、metrics_token请使用如下命令生成高强度的密钥:

openssl rand -hex 32

S3 API的root_domain:.s3-garage.example.com,将其更换为自己的域名,并添加通配符(*)DNS解析记录。

S3 Web的root_domain:.web-garage.example.com,将其更换为自己的域名,并添加通配符(*)DNS解析记录。

S3 Web是Garage与其他S3实现的第一个不同之处,在Garage中没有存储桶策略(bucket policy)的概念,取而代之的是“将存储桶公开为网站”的功能。

举个栗子:在MinIO/RustFS中,你可以设置一个存储桶是公开还是私有,公开就代表这个存储桶可以被匿名访问,反之亦然。而Garage创建的存储桶没有这个功能,默认情况下不能匿名访问,当你用浏览器访问的时候会提示:Forbidden: Garage does not support anonymous access yet。如果你需要存储桶可以被匿名访问,那么就需要启用“将存储桶公开为网站”的功能。

Garage还支持根据存储桶的名称来推断出实际的域名,例如你的存储桶名称是bucket.lala.im,那么这个域名将可以直接访问该存储桶。这个功能主要的目的就是可以让用户选择使用自己的域名来访问存储桶。如果用户没有自己的域名,也可以使用配置文件内指定的子域名访问存储桶:bucket.lala.im.web-garage.example.com

将存储桶公开为网站的这个功能有限:目前仅支持静态网站(不支持PHP或其他语言)、不支持目录列表(列目录)、首页在garage.toml中定义(如index.html)

启动Garage:

docker compose up -d

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

s3-garage.example.com,*.s3-garage.example.com {
    proxy "http://127.0.0.1:3900/"
    proxy_request_header_replace "Host" "{header:Host}"
}

*.web-garage.example.com {
    proxy "http://127.0.0.1:3902/"
    proxy_request_header_replace "Host" "{header:Host}"
}

注意事项:

其中s3-garage.example.com域名用于path(路径风格),*.s3-garage.example.com域名用于virtual-hosted-style(虚拟主机风格)

*.web-garage.example.com用于为用户提供子域名访问存储桶,也就是之前提到的“将存储桶公开为网站”功能。

Ferron默认会将请求发送到后端服务器之前重写“Host”标头,并在“X-Forwarded-Host”标头中保留原始的“Host”标头值。然而,Garage无法在这种配置下正常工作,必须将“Host”标头值设置为原始值。所以上面的配置添加了:proxy_request_header_replace “Host” “{header:Host}”

另外因为需要用到通配符域名证书,务必将申请证书的方式改为DNS-01,这里我配置的DNS服务商是CloudFlare,将yourkey修改成你在CloudFlare申请的key:

//    auto_tls_challenge "http-01"
    auto_tls_challenge "dns-01" provider="cloudflare" api_key="yourkey"

重载Ferron:

systemctl reload ferron

Garage第二个不同之处在于需要先初始化(创建布局)才能使用,执行如下命令查看并复制节点ID:

docker exec -ti garage /garage status

创建布局:-z指定区域名称,可任意指定,-c指定容量大小,单位可以用G/T。后跟上节点ID:

docker exec -ti garage /garage layout assign -z netcup -c 1T d34ebe436e60eaa8

应用布局:

docker exec -ti garage /garage layout apply --version 1

如果你后续又创建了新的布局,则这里的版本号要在其基础上+1,查看当前的布局:

docker exec -ti garage /garage layout show

如果正常的话,应该有类似下图的输出:

现在就可以实际使用了,创建一个存储桶,名称为storage:

docker exec -ti garage /garage bucket create storage

创建API密钥:

docker exec -ti garage /garage key create storage-app-key

输出类似:

==== ACCESS KEY INFORMATION ====
Key ID:              GKd9e9193ca3c7fd8e35f79530
Key name:            storage-app-key
Secret key:          445c98c1bd96d1742a8c71f69027d0a9f1d1ae191f5690f88c4fe0d2cae7ef9e
Created:             2025-12-30 11:56:51.778 +00:00
Validity:            valid
Expiration:          never
Can create buckets:  false
==== BUCKETS FOR THIS KEY ====
Permissions  ID  Global aliases  Local aliases

其中Key ID和Secret key是访问凭据,务必保存好。现在我们有了存储桶和密钥,接下来需要授予该密钥对存储桶的访问权限:

docker exec -ti garage /garage bucket allow --read --write --owner storage --key storage-app-key

查看存储桶信息:

docker exec -ti garage /garage bucket info storage

输出类似:

==== BUCKET INFORMATION ====
Bucket:          85115ec8c3c33bd9345c8c6c2cb6c4b13a3f711ef520c73243d8e1268b7fe55f
Created:         2025-12-30 11:56:27.146 +00:00
Size:            0 B (0 B)
Objects:         0
Website access:  false
Global alias:    storage
==== KEYS FOR THIS BUCKET ====
Permissions  Access key                                   Local aliases
RWO          GKd9e9193ca3c7fd8e35f79530  storage-app-key

配置存储桶的CORS策略(跨域资源共享),这对于某些程序来说非常重要。有些程序设计的逻辑是直接通过浏览器访问S3,不经过后端处理,通常在浏览器(前端)直接访问S3会遇到CORS问题。安装awscli:

apt install awscli

配置Access Key ID与Secret Access Key,以及默认region(区域):

aws configure

流程如下:

AWS Access Key ID [None]: GKd9e9193ca3c7fd8e35f79530
AWS Secret Access Key [None]: 445c98c1bd96d1742a8c71f69027d0a9f1d1ae191f5690f88c4fe0d2cae7ef9e
Default region name [None]: garage
Default output format [None]: json

默认的凭据与配置文件保存位置:

~/.aws/config
~/.aws/credentials

新建一个cors.json配置文件:

nano cors.json

写入如下内容:

{
  "CORSRules": [
    {
      "AllowedOrigins": ["*"],
      "AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD", "OPTIONS"],
      "AllowedHeaders": ["*"],
      "ExposeHeaders": ["ETag"],
      "MaxAgeSeconds": 3600
    }
  ]
}

应用CORS配置:

aws s3api put-bucket-cors --bucket storage --endpoint-url https://s3-garage.example.com --cors-configuration file://cors.json

查看存储桶当前的CORS配置,确保是之前应用的内容:

aws s3api get-bucket-cors --bucket storage --endpoint-url https://s3-garage.example.com

启用存储桶匿名访问(将存储桶公开为网站的功能)

docker exec -ti garage /garage bucket website --allow storage

现在可以通过下面的这个URL访问到存储桶的资源:

https://storage.web-garage.example.com

之前提到过Garge还支持根据存储桶的名称来推断域名,这样就可以让用户使用自己的域名来访问存储桶。配置起来也很简单,只需要在创建存储桶的时候,将桶的名称设置为相应的域名,例如:

docker exec -ti garage /garage bucket create bucket.lala.im

将域名bucket.lala.im添加DNS解析记录,并且在Ferron内配置好域名:

*.web-garage.example.com,bucket.lala.im {
    proxy "http://127.0.0.1:3902/"
    proxy_request_header_replace "Host" "{header:Host}"
}

需要注意的是,由于通配符证书只能匹配一层子域,对于这种bucket.lala.im.web-garage.example.com更深层的域名是无法匹配到的(浏览器访问会提示不安全)

所以,这两种域名访问的方式最好任选其一,或者你得加上:

*.web-garage.example.com,bucket.lala.im,bucket.lala.im.web-garage.example.com {
    proxy "http://127.0.0.1:3902/"
    proxy_request_header_replace "Host" "{header:Host}"
}

一般情况下是不需要搞这么复杂的,直接用*.web-garage.example.com即可。

其他有用的命令:

docker exec -ti garage /garage bucket list # 列出全部存储桶
docker exec -ti garage /garage bucket delete bucket.lala.im --yes # 删除存储桶
docker exec -ti garage /garage bucket website --deny storage # 取消存储桶匿名访问
docker exec -ti garage /garage bucket deny --read --write --owner storage --key storage-app-key # 取消API密钥对存储桶的访问权限
docker exec -ti garage /garage key list # 列出API密钥
docker exec -ti garage /garage key delete storage-app-key --yes # 删除API密钥

如果你觉得这种命令行操作非常不方便,现在有一个第三方的Web UI可供使用:

services:
  garage:
    image: dxflrs/garage:v2.1.0
    container_name: garage
    restart: unless-stopped
    ports:
      - 127.0.0.1:3900:3900
      - 127.0.0.1:3901:3901
      - 127.0.0.1:3902:3902
      - 127.0.0.1:3903:3903
    volumes:
      - ./garage.toml:/etc/garage.toml
      - ./meta:/var/lib/garage/meta
      - ./data:/var/lib/garage/data

  webui:
    image: khairul169/garage-webui:latest
    container_name: garage-webui
    restart: unless-stopped
    volumes:
      - ./garage.toml:/etc/garage.toml:ro
    ports:
      - 3909:3909
    environment:
      API_BASE_URL: "http://garage:3903"
      S3_ENDPOINT_URL: "http://garage:3900"
      AUTH_USER_PASS: "username:$2y$10$/6t1aIVS5p9b4h6nmDuHg.f8C..."

其中AUTH_USER_PASS需要使用如下命令生成:

htpasswd -nbBC 10 "YOUR_USERNAME" "YOUR_PASSWORD"

如果找不到htpasswd命令请安装如下软件包:

apt install apache2-utils

这个Web UI功能有限,并且开发不积极,缺少很多关键功能,例如:创建布局、配置存储桶的CORS策略,这些功能依旧只能使用命令行操作。