Mastodon:上傳文件的存儲和鏈接樣式

關於 Mastodon 如何設置上傳文件的前綴域名,以及不同的選擇要考慮到的問題——


Mastodon 有兩種方式,來保存用戶上傳的媒體文件、頭像、和系統的臨時緩存文件。

  • 保存在本地伺服器,
  • 保存在遠程 S3 文件伺服器上。

在 .env.production 設置文件中,通過 S3_ENABLED 參數進行區分。

很多小型實例,因爲 VPS 硬碟容量的限制,選用了 Scaleway 的 S3 存儲服務,每個月 75GB 的 免費容量pullopen 的文檔介紹了如何 Mastodon 設置訪問 Scaleway。

然而,第三方的 S3 存儲服務,未必總是最好的選擇。75GB 的免費空間,對于大多數百人級別的實例來説,是足夠用了。但問題在於,Scaleway 免費額度不僅是存儲容量 75GB,每月的流量也只有 75GB 以内才免費,多出的部分就會從信用卡裏扣錢。如果哪個月,存儲的媒體文件被訪問(or 抓取)得異常頻繁,超出了免費流量,就會很虧。反而是用來運行 Mastodon 的 VPS 伺服器,哪怕是最便宜的款式,也會提供每月 500GB – 1TB 的流量額度。如今很多 VPS 開始提供更多的存儲空間,有的甚至能達到 200 – 400GB。所以,除非是超小硬碟的 VPS,否則,把媒體文件直接存到 Mastodon 伺服器上面,可能是更好的方案。

這些存儲方案,是可以在 Mastodon 建站之後,隨意遷移和改變的:從本地遷移到 S3,從 S3 遷移到本地,或者遷移到另一處更大的 S3。然而,需要考慮的是,無論怎樣遷移,舊有的媒體文件的鏈接,不會變化,從而失效。

Mastodon 提供了 S3_HOSTNAME 參數,作爲上傳文件的固定前綴域名。譬如,文件存儲到 Scaleway 后,實際的地址可能是:

https://s3.nl-ams.scw.cloud/s3-bucket/media_attachments/…/cat.jpg

但設置 S3_HOSTNAME=media.domain 后,這個文件在嘟文中顯示的存儲地址,就變成:

https://media.domain/s3-bucket/media_attachments/…/cat.jpg

然後在 Nginx 裏,把 media.domain 域名指向 Scaleway 的地址:

location /s3-bucket/ {
  add_header 'Access-Control-Allow-Origin' '*';
  proxy_pass https://s3.nl-ams.scw.cloud;
}

這樣,以後從 S3 遷移到另一臺 S3 的時候,站内的媒體文件鏈接,永遠是 https://media.domain/… 的樣式,不會失效。


分配給 S3_HOSTNAME 的域名,可以是

  1. Mastodon 網站域名的子域名,如 media.antisocial.science;
  2. 或者,完全無關的其它域名,如 xxx.com (當然,這個域名也要受你控制,配置 A 類指向和 Nginx 轉向)
  3. 或者,Mastodon 網站域名本身,如 antisocial.science。——是的,你完全可以把 S3_HOSTNAME 設成和 Mastodon 同樣的域名,只要 S3_BUCKET 不要和 Mastodon 自身的第二層名稱衝突。

第三種很重要!向大家推薦的也是這一種:把 S3_HOSTNAME 設成和 Mastodon 同樣的域名。因爲——

當你選擇在本地伺服器上儲存上傳文件,設置 S3_ENABLED=false 后,S3_HOSTNAME 設置的域名前綴,就不再起作用了。

在本地保存的上傳文件的默認鏈接是:

https://antisocial.science/system/media_attachments/…/cat.jpg

默認的 /system/ 看起來很醜陋,可以改。在 .env.production 裏設置參數:

PAPERCLIP_ROOT_URL=/my-file-folder

(注意,這個 my-file-folder 的名字,等你以後遷移到 S3 后,和 S3 伺服器上的 BUCKET 名字是一致的。如果以後的 S3 是多人共用的話,不妨現在就把這個名字取得獨特一點,以免和 S3 其它用戶衝突。)

同時,可以更改上傳文件在本地的實際存儲位置:

PAPERCLIP_ROOT_PATH=/home/mastodon/ext_files

然後更改 antisocial.science 域名的 Nginx 配置

location /my-file-folder/ {
  alias /home/mastodon/ext_files/ ;
}

但是,本地保存上傳文件時,文件前面的域名是不能更改的,一定要和 Mastodon 網站本身的域名一致。也就是說,如果你在最初建站時,就用了另外一個和 Mastodon 網站不一樣的域名或子域名(很多人這樣做,因爲好看)標記上傳文件,那麽以後你就不能用最簡單的辦法,把文件遷移到本地了。

當然解決辦法也有,譬如用 Nginx 把遷移前後的兩個鏈接都指向一起。又譬如,在本機安裝一個 S3 服務(譬如 MinIO)挂在你之前 S3_HOSTNAME 的域名下面,然後用 Mastodon 訪問本地 S3,變相實現本地存儲。這麽做我試過,很好玩,但又要配置很多東西。而且也有很多坑:譬如 MinIO 需要做 https 認證,不然 Mastodon 頁面看不到縮略圖,認證弄起來很煩;譬如要考慮前綴域名是指向 S3 服務,還是直接指向本地文件夾;譬如 MinIO 的 bucket 設置和文件存儲不是保存在一起的,用 Docker 時要考慮很多……

但自建 S3 確實很好玩的。而且如果你有計劃,以後把媒體文件遠程保存在另一個空白伺服器上,那麽自建 S3 應該是唯一選擇了。


所以 Mastodon 的上傳文件存儲,其實一共有 5 種方案:

  1. 本地,默認設置:不能設置額外的上傳文件域名,以及難看的 /system/ 後綴;
  2. 本地,通過 PAPERCLIP_ROOT_URL 參數,更改後綴和存儲位置:仍然不能設置額外的上傳文件域名。
  3. 本地,自建 S3 服務:可以選擇額外的上傳文件域名;配置繁瑣。
  4. 遠程,自建 S3 服務:可以選擇額外的上傳文件域名;配置繁瑣。
  5. 遠程,第三方 S3 服務:可以選擇額外的上傳文件域名;但有超出流量后多付費的危險。

目前本站 antisocial.science,用的是第二種方案。以後擴容時,可能會采用第四種方案。

Leave a comment

Your email address will not be published. Required fields are marked *




Enter Captcha Here :