最近在研究git lfs server,本來在測試git lfs test server,但官方不建議作為線上使用,後來找到了 rudolfs,因為我的主機架在虛擬機裡面,測試 local 模式時,如果是直接用虛擬機的空間是正常的,但若設定成實體主機映照到虛擬機裡面就會有問題,但為了避免虛擬機的硬碟爆炸,不考慮直接放虛擬機的空間裡面,因為 rudolfs 也支援 minio,做了簡單的研究後瞭解它是一個 local 的儲存服務,據說相容 aws s3的雲端儲存api。
但要轉換到 minio 也費了一番波折,rudolfs有提供docker-compose的設定檔,其中的mino的設定可以直接透過docker-compose啟用,但測試時一直不成功 ,也沒有明確的錯誤訊息,後來因故發現作者的github issue裡的有提到可能的原因是rusoto sdk造成的。
因為 rudolfs 要連線到 minio 時是用 rusoto 這個sdk,但這個 sdk 建立 http 連線不知何故強迫用https,並且要求http2,所以如果 minio 佈署在 local ,沒有額外設定滿足 https 及http2 的話,rudolfs 就會無法正常連線,所以我就直接把 minio 佈署成公開網站,這對我來講可能簡單多了,因為本來就有在架站,直接加子網域並設定lets encrypt就很快,相對在虛擬機設定虛擬機還要自簽ssl複雜多了。
底下的說明請先從 minio 的部份先完成,再處理 rudolfs
安裝rudolfs
git clone https://github.com/jasonwhite/rudolfs.git
cd rudolfs
# 產生加密用key,輸出結果請複製備用
openssl rand -hex 32
在 rudolfs 資料夾下產生 .env,內容如下
AWS_ACCESS_KEY_ID=xxxxxxxx # 可以是 minio帳號,也可以是 mc 產生的 access key
AWS_SECRET_ACCESS_KEY=xxxxxxxxx # 可以是 minio帳號密碼,也可以是 mc 產生的 access secret
AWS_DEFAULT_REGION=us-west-1 # 照填
LFS_ENCRYPTION_KEY=xxxxxxxxxxxx # 上面 openssl rand -hex 32 的結果
LFS_S3_BUCKET=rudolfs-bucket # minio 產生的 bucket 名稱
LFS_MAX_CACHE_SIZE=10GB
AWS_S3_ENDPOINT=https://{you minio api domain}
編輯 rudolfs 資料夾 下的 docker-compose.minio.yml 為以下內容,主要移除裡面的 minio ,後面要自架 minio 。
# 編輯 rudolfs 下的 docker-compose.minio.yml為以下內容
# 主要是移除既有的 minio 設定
# Copy this file to another location and modify as necessary.
version: "3"
services:
app:
image: jasonwhite0/rudolfs:latest
#build:
# context: .
# dockerfile: Dockerfile
ports:
- "8081:8080"
volumes:
- data:/data
restart: always
environment:
- AWS_REGION
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_DEFAULT_REGION
- LFS_ENCRYPTION_KEY
- LFS_S3_BUCKET
- LFS_MAX_CACHE_SIZE
- AWS_S3_ENDPOINT
entrypoint:
- /tini
- --
- /rudolfs
- --cache-dir
- /data
- --key
- ${LFS_ENCRYPTION_KEY}
- --max-cache-size
- ${LFS_MAX_CACHE_SIZE}
- s3
- --bucket
- ${LFS_S3_BUCKET}
# A real production server should use nginx. How to configure this depends on
# your needs. Use your Google-search skills to configure this correctly.
#
# nginx:
# image: nginx:stable
# ports:
# - 80:80
# - 443:443
# volumes:
# - ./nginx.conf:/etc/nginx/nginx.conf
# - ./nginx/errors.log:/etc/nginx/errors.log
volumes:
data:
啟用docker
# 啟用 docker
sudo docker-compose -f ./docker-compose.minio.yml up -d
安裝 minio
go install github.com/minio/minio@latest
安裝完成後會在所在資料夾下產生 go/bin/minio,其中 minio 就是執行檔,要啟用服務就執行下列指令
go/bin/minio server /data
這時候會提示兩個服務監聽資訊,分別是 api (預設是 9000 port),以及web ui (console) (預設動態 port,每次啟用都不一樣).
其中 /data 為儲存資料夾,可替代成實際要用的資料夾名稱。
若要固定 web ui 的監聽port,可透過 –console-address 設定,例如:
go/bin/minio server --console-address 0.0.0.0:9001 /data
api 這個服務是用來程式呼叫的,web ui (console) 則是網頁介面,可以新增、刪除 bucket,以及查看bucket裡的檔案列表。因為我自己用的minio coummunity edition,其實就只有上述提到的這些功能,網路上有些 minio 教學的截圖裡顯示功能多了,目前要有完整的介面就請付費取得 license。
但大部份的功能還是可以透過 mc 這個 client 執行,所以有興趣的話請再自行研究一下 mc 的作法,官方文件其實蠻清楚的。
如果 rudolfs 和 minio 在同一個區域,minio 完全不需要經過apache proxy也可以用,但如果要進一步設定 proxy,因為 minio 有兩個服務api, web ui (console),建議將兩個服務獨立成兩個子網域並將 / 代理對應到兩個不同的 port 以避免麻煩,至少我自己測試 web ui (console) 代理到子目錄時,例如 /console/,網頁的一些css, js 還是指向 / ,也許apache可能還是可以進一步處理,但就會麻煩許多。
所以如你也打算將 minio 做 apache proxy 轉發,請務必準備兩個子網域對應api 及web ui (console)。
底下說明 rufolfs 、 minio 的api 及 web ui (console) 以及 rudolfs 的 apache proxy設定,下列提到的設定只是部份內容,請加到您既有可用的的 apache virtual host 檔裡。
web ui 的 apache proxy設定
底下的設定請放到apache的virtual host設定裡,其中需要啟用的 apache 模組有 headers proxy proxy_http proxy_balancer proxy_wstunnel ssl http2 mpm_event
# 啟用 http2 協定
Protocols h2 http/1.1
# ==================== 關鍵設定 ====================
# 1. 保留原始 Host(SigV4 簽名依賴此!)
ProxyPreserveHost On
# 2. 告訴 MinIO 原始協定是 HTTPS
RequestHeader set X-Forwarded-Proto "https"
# 3. 允許 MinIO 生成正確的公開 URL(選用)
RequestHeader set X-Forwarded-Host %{HTTP_HOST}s
# 4. 啟用 SSL Proxy(若 MinIO 後端是 HTTPS)
SSLProxyEngine On
# SSLProxyVerify none # 若 MinIO 自簽憑證才加
# ==================== MinIO Console (port 9001) ====================
# WebSocket 支援(Console 需要)
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) ws://127.0.0.1:9001/$1 [P,L]
# Console 靜態資源與 API
ProxyPass / http://127.0.0.1:9001/
ProxyPassReverse / http://127.0.0.1:9001/
# 允許斜線編碼(S3 物件名稱常有 /)
AllowEncodedSlashes NoDecode
# ==================== 安全與日誌 ====================
<Proxy *>
Require all granted
</Proxy>
api 的 apache proxy設定
# apache可用的協,加上 http2
Protocols h2 http/1.1
# ==================== 關鍵設定 ====================
# 1. 保留原始 Host(SigV4 簽名依賴此!)
ProxyPreserveHost On
# 2. 告訴 MinIO 原始協定是 HTTPS
RequestHeader set X-Forwarded-Proto "https"
# 3. 允許 MinIO 生成正確的公開 URL(選用)
RequestHeader set X-Forwarded-Host %{HTTP_HOST}s
# 4. 啟用 SSL Proxy(若 MinIO 後端是 HTTPS)
SSLProxyEngine On
# 1. 較特定的路徑優先
ProxyPass / http://127.0.0.1:9000/ nocanon
ProxyPassReverse / http://127.0.0.1:9000/
# 允許斜線編碼(S3 物件名稱常有 /)
AllowEncodedSlashes NoDecode
<Proxy *>
Require all granted
</Proxy>
rudolfs 的 apache proxy 設定
# apache可用的協,加上 http2
Protocols h2 http/1.1
# 據說是保留 http header
ProxyPreserveHost On
# 讓 rudolfs知道目前的連線是 https, rudolfs本身是 http
RequestHeader set X-Forwarded-Proto "https"
# 以下不能加,加了會導致 rudolfs回覆內容的網址變成 localhost
# RequestHeader set X-Forwarded-Host %{HTTP_HOST}s
# 這裡的 port 請依啟用 rudolfs時的port設定
ProxyPass / http://127.0.0.1:8081/ nocanon
ProxyPassReverse / http://127.0.0.1:8081/
# 允許斜線編碼(S3 物件名稱常有 /)
AllowEncodedSlashes NoDecode