把 Storage Server 用在 WordPress 上:什么能行,什么不行

发布于 阅读时间 9 分钟

关于 WordPress 和外部存储读到的东西,并不是都真能用。本文把三种情形分开来讲:备份马上就能做,下载花点小功夫,而媒体库只在一个条件下成立。

wp-content/uploads 这个目录,是 WordPress 里会一路长下去的那部分。图片、PDF 文件、视频,再加上 WordPress 为每张图自动生成的好几个尺寸。几年之后那里就躺着几十个 GB,而 Web 服务器上的空间,是能买到的最贵的那种。

Storage Server 的价钱只是其中一个零头。问题只在于,到底哪些东西真能挪出去。网上关于这件事写了很多,而在实际中并不成立。本文把三种情形干净地分开。

三种情形一览

做什么行不行?要花的工夫
备份行,马上就行一刻钟,免费插件
大体积下载行一个小脚本或一个下载插件
媒体库,自有服务器行挂载一次,之后就看不见了
媒体库,共享主机不行缺的正是合适的插件

最后一条是多数人栽跟头的地方。所以先说那句不中听的实话。

为什么媒体库没有插件

WordPress 那几个有名的外挪插件说的都是同一种语言:S3。它们连到 Amazon S3 或某个兼容它的服务,把文件传过去,删掉本地副本,再把文章里的地址换成该服务的一个公开地址。

这件事恰恰没法照搬到 Storage Server 上,原因有两个:

  • 存储会说 SMB、SFTP 和 WebDAV,但不会说 S3。
  • 每个文件都没有公开地址。每一次访问都要登录,所以不可能有一个让访客浏览器直接去取的链接。

确实有个别插件用 FTP 工作,但没有哪个在传播度和维护上拿得出手、能把媒体库完整地通过 SFTP 或 WebDAV 挪出去。找到一个的,在用之前请先看最后一次更新的日期和活跃安装量。

真能走通的那条路:挂载,而不是外挪

在有 root 权限的自有服务器上,这件事可以反过来做。不是去教 WordPress 跟别处的存储说话,而是把存储搬到 WordPress 本来就要往里写的那个位置:

apt install -y cifs-utils
mkdir -p /mnt/storage
printf 'username=u123456-sub1\npassword=YOUR_PASSWORD\n' > /etc/samba/storage.cred
chmod 600 /etc/samba/storage.cred

/etc/fstab 里的条目:

//u123456.storage.kernelhost.net/backup /mnt/storage cifs credentials=/etc/samba/storage.cred,uid=www-data,gid=www-data,file_mode=0660,dir_mode=0770,seal,_netdev,nofail 0 0

然后把已有的文件搬过去,再把目录替换掉:

mount -a
mkdir -p /mnt/storage/uploads
rsync -a /var/www/example.com/wp-content/uploads/ /mnt/storage/uploads/
mv /var/www/example.com/wp-content/uploads /var/www/example.com/wp-content/uploads.alt
ln -s /mnt/storage/uploads /var/www/example.com/wp-content/uploads

WordPress 完全察觉不到,对应用来说那就是一个普通路径。旧目录会以 uploads.alt 的名字留着,直到您确认一切正常。到那时再删,不要提前删。

这里的陷阱:缩略图

WordPress 会为每张图生成好几个尺寸,并在每次打开页面时加载它们。这些小文件放在网络存储上,每个文件就要再加上一次网络往返的时间,于是一个有四十张图的相册就要等四十次。

两个办法,都不错:

  • 在前面放一层缓存,比如在 Web 服务器里做缓存,把分发出去的文件在本地留一份。
  • 只把原件放到存储上,让生成出来的那些尺寸留在本地。这要多做一点事,但对图片很多的站点来说是最干净的路。

备份:来得最快的好处

如果您只做一件事,就做这件。备份在同一台服务器上,不算备份:硬盘被删掉或者网站被加密,它就一起没了。放在独立存储上,它能活下来。

免费插件 WPvivid 的基础版就能通过 SFTP 备份到存储上,带计划任务和保留规则。完整的操作步骤见把 WordPress 备份到 Storage Server。

在自己的服务器上还能更好,也就是直接从一个计划任务里用 rsync 或 BorgBackup。那样您只传输变化的部分,而 BorgBackup 还会额外去重。

分发大体积下载

对那些要让访客下载的文件来说,存储正合适:它们很少被读取、体积大,而且不需要快,只需要送到。访问走一个小脚本,由它先检查权限:

<?php
// 放在 functions.php 里,或者做成一个自己的插件
add_action('template_redirect', function () {
    if (!isset($_GET['kh_download'])) {
        return;
    }
    if (!is_user_logged_in()) {
        wp_die('请先登录', '', ['response' => 403]);
    }

    $pfad = '/mnt/storage/downloads/' . basename($_GET['kh_download']);
    if (!is_readable($pfad)) {
        wp_die('文件未找到', '', ['response' => 404]);
    }

    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename($pfad) . '"');
    header('Content-Length: ' . filesize($pfad));
    readfile($pfad);
    exit;
});

这个例子假设存储已经挂载好了。没有挂载的话,就把 readfile() 换成一次 SFTP 或 WebDAV 调用,具体写法见把 Storage Server 用在自己的网站上。

附带的效果很舒服:因为文件从来没有公开地址,谁也没法把链接转给别人。权限检查绕不过去。

共享主机上还剩下什么

打算做的事共享主机自有服务器
用插件备份行行
通过 PHP 分发下载行,走 WebDAV 或 SFTP行
把媒体库挪出去不行行,用挂载
rsync 或 BorgBackup多数情况不行行

在共享主机上,走 HTTPS 的 WebDAV 是最靠得住的路,因为 443 端口几乎从不被封。SFTP 同样能用,但在我们这里跑在 23 端口上,而不是每家服务商都允许往这类端口发起出方向连接。这件事在下单之前该快速查一下。

每个用途一个子账户

每台 Storage Server 都允许最多 100 个子账户,每个都有自己的起始目录、自己的密码和自己的协议开关。对 WordPress 来说,这意味着至少两个:

  • 一个给网站的账户,只看得见 /uploads。
  • 一个给备份的账户,只看得见 /backup。

万一网站哪天被拿下,攻击者会在 wp-config.php 里找到第一个账户的凭据。备份不受影响,因为那个账户根本不认识它们。只用一个主账户的话,到这一步就全没了。

当多个用户各自需要自己的空间

Storage Server 没有按子账户设置的配额。一个账户出不了自己的目录,但在那里面可以把整个套餐填满。想给客户、摄影师或编辑各一份有限额度的,就要在前面放一个应用来接管这件事。Nextcloud 是最顺手的那个,它自带用户、配额和共享链接:把 Nextcloud 连到 Storage Server。

哪个套餐合适

套餐空间子账户价格
Storage-11 TB1009.99 EUR
Storage-25 TB10029.99 EUR
Storage-310 TB10039.99 EUR
Storage-420 TB10069.99 EUR

对一个带备份的单独 WordPress 站点来说,Storage-1 一般能用很久。要把多个站点的媒体库挪出去或者做视频的,很快就会落到 Storage-2 或 Storage-3。所有套餐都在德国,没有安装费,按预付方式结算,也没有最短合约期。换到下一档更大的套餐随时可以,不用动数据。

常见问题

可以用插件把 WordPress 媒体库挪到 Storage Server 上吗?
不行,至少没法可靠地做到。那几个有名的外挪插件只会说 S3 和兼容它的服务。对 SFTP 或 WebDAV,没有哪个还在维护的插件能把媒体库完整挪出去。看到这里仍然找到了某个插件的,请先看它的更新日期和安装量。
那到底怎么才行?
在有 root 权限的自有服务器上。在那里您把存储挂进文件系统,再把 wp-content/uploads 目录放上去。WordPress 完全察觉不到,对应用来说那就是一个普通路径。在没有 root 权限的共享主机上,这条路走不通。
最简单的好处是什么?
备份。像 WPvivid 这样的插件,免费版就能通过 SFTP 备份到存储上,一刻钟就配好了,而且马上带来安全感,因为备份不再和网站躺在同一台机器上。
这会让我的图片加载变慢吗?
如果搭法不对,会。缩略图每次打开页面都要用,而每一次走网络的访问都要花时间。办法是把原件放在存储上,让 WordPress 生成的那些尺寸留在本地或者进缓存。
可以把下载直接链到存储上吗?
不行,对存储的每一次访问都要登录。您要通过一个小的 PHP 脚本或者一个下载插件来分发文件,由它检查权限再把文件转发出去。这其实还是个优势,因为谁也没法把链接转给别人。
在共享主机上该用哪个协议?
走 HTTPS 的 WebDAV,因为 443 端口几乎从不被封。SFTP 也能用,但在我们这里跑在 23 端口上,而有些共享主机服务商不允许往这类端口发起出方向连接。这件事最好提前查清楚。
每个用途都要配一个自己的子账户吗?
非常建议这么做。每台 Storage Server 都允许最多 100 个子账户,各有自己的目录和自己的密码。万一网站哪天被拿下,攻击者也碰不到备份,因为网站那个账户根本看不见它们。
那多个用户、每人都需要自己空间的情况呢?
光靠存储做不了这件事,因为没有按子账户设置的配额。这种情况请在前面放一个 Nextcloud,它自带用户、配额和共享,并把文件存在存储上。
小网站值得这么做吗?
备份的话,值,而且永远值。媒体库则要等到 Web 服务器上的空间紧张或者变贵的时候。一条经验法则:一旦您开始琢磨加买虚拟主机空间,Storage Server 就是更便宜的答案。
这要花多少钱?
1 TB 的 Storage-1 每月 9.99 欧元,5 TB 的 Storage-2 是 29.99,10 TB 的 Storage-3 是 39.99,20 TB 的 Storage-4 是 69.99。机房在德国,无安装费,预付制,无最短合约期。

WordPress Storage Server Mediathek Backup Downloads SFTP WebDAV