在 AWS 上部署 NixOS + Nextcloud

关于 NixOS 的介绍和本地服务器安装，请参考之前发的博客「安装最小化 NixOS 的基本步骤」。

NixOS 下载页面中，提供了简单快速部署到 AWS 的方法。我们采用这种方法，快速部署 NixOS。

创建 EC2 实例

有时候（比如写这篇博客的时候），不能在下载页面中找到 NixOS 的 AMI。这时候，可以在 AWS 控制台中搜索nixos，就可以找到 NixOS 的 AMI 了。

选择 AMI 时，注意架构，选择x86_64。正确的 AMI 应该类似下图：

你应该按照成本和性能的需求，选择合适的实例类型。博主选择了t2.micro，因为它是免费的。

在初次使用 AWS 时，你需要创建一个新的密钥对。密钥对是连接到 EC2 实例的唯一方法，所以务必妥善保管密钥对。如果你不是第一次使用 AWS，也建议创建一个新的密钥对，以防你的密钥对泄露。

对于网络安全组，你必须开放 SSH 端口（默认 22），以便连接到 EC2 实例。因为这是一台 Web 服务器，所以还需要开放 80（HTTP）和 443（HTTPS）端口。

如果遇到了连通性问题，可以暂时开放所有端口，以便排查问题。但仅限非生产环境排查问题时，结束后务必及时关闭。

尽管最小化 NixOS 占用的空间很少，但是我们还是建议你选择至少 8GB 的存储空间。如果你的实例类型支持 EBS 优化，那么请开启 EBS 优化。

连接到 EC2 实例并复制配置

连接到 EC2 实例

在 AWS 控制台中，你可以看到 EC2 实例的公有 IP 地址。你可以使用这个 IP 地址，连接到 EC2 实例。

接下来假设公有 IP 地址为1.14.51.4，用户名为ec2-user。
这个 IP 地址来自于一个梗。有趣的是，这个 IP 地址是真实存在的，并由一家中国的大型互联网公司（腾讯）拥有。

Copy
sudo ssh -i /path/to/your/key.pem ec2-user@1.14.51.4

我们在之前的博客中, 已经在本地部署过了 Nextcloud 并编写好了 Nix 配置文件。我们可以从 EC2 实例中下载配置文件，如果不会造成破坏性操作，则将配置文件复制到 EC2 实例中。

这个过程建议使用 FileZilla + VS Code，因为方便。如果你不想使用 FileZilla，可以使用scp命令。

复制配置文件

事实上，AWS 中的configurations.nix和先前安装的 NixOS 中的configurations.nix有非常大的不同。在23.05版本，配置如下：

Copy
{ modulesPath, ... }: {
imports = [ "${modulesPath}/virtualisation/amazon-image.nix" ];

}

是的，我没有做任何修改。差距就是这么大。

但也不是因为差距大就不会用了。在本地测试的文件中，我们这样配置了 Nextcloud

Copy
environment.systemPackages = with pkgs; [
vim
wget
curl
openssh
msmtp
];

services.nextcloud = {
enable = true;
hostName = "nextcloud.tld";
config = {
dbtype = "pgsql";
dbuser = "nextcloud";
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
dbname = "nextcloud";
adminpassFile = "/path/to/your/nextcloud/adminpass";
adminuser = "root";
};
package = pkgs.nextcloud26;
};

services.postgresql = {
enable = true;
ensureDatabases = [ "nextcloud" ];
ensureUsers = [
{ name = "nextcloud";
ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
}
];
};

systemd.services."nextcloud-setup" = {
requires = ["postgresql.service"];
after = ["postgresql.service"];
};

networking.firewall.allowedTCPPorts = [ 80 443 465 587 ];

这是一个示例文件，里面有一些占位符如/path/to/your/nextcloud/adminpass，需要根据实际情况进行修改。

我们可以将这些配置复制到初始配置文件预留的空位中，然后用编辑过的配置文件替换原始配置文件。

在 FileZilla 中，可以直接将修改后的文件上传并覆盖原始文件。

注意：你需要修改第一行的{ modulesPath, ... }: { 为{ config, pkgs, ... }: {
我想你很可能没有学过 Nix 的语法，所以这里简单解释一下。

在覆盖原有配置文件之后，应用配置文件。

Copy
sudo nixos-rebuild switch

nixos-rebuild命令会使用大量空间，务必确认你的硬盘空间足够。同时，注意不要在nix-shell下使用nixos-rebuild命令。

配置调整

不同于本地部署，我们需要调整一些配置，以适应 AWS 的环境。需要调整的配置可以参考 Nextcloud 的概览页面。

配置 HTTPS

首先处理这个警告。

按照Wiki, 可以做如下配置以启动 HTTPS。

Copy
services.nextcloud = {
enable = true;
[...]
hostName = "example.org";
https = true;
};

services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
forceSSL = true;
enableACME = true;
};

这个配置使用了ACME来自动获取免费的 Let's Encrypt 证书。对于大多数用户而言，这是一个非常好的选择。

当然，既然使用了 ACME，那我们就需要配置它。在配置 ACME 之前，请确保你有一个域名，并且已经将域名解析到了你的服务器上。

Copy
security.acme = {
acceptTerms = true;
email = "your-email@example.com"; # Replace with your email.
certs = {
"yourdomain.com".extraDomains = [ "www.yourdomain.com" ]; # Replace with your domain and subdomains.
};
};

你可能会遇到报错undefined variable 'config'，这是因为你没有在{ modulesPath, ... }: {中添加config。请参考上文的解释。

你不需要在environment.systemPackages中手动安装 ACME，当你设置security.acme.acceptTerms = true的时候，Nix 会自动安装。默认情况下，ACME 能够自动续签证书。所以你可以不用担心证书过期的问题。

如果遇到了问题，你可以在/var/log/acme/acme.log中查看日志。

设置默认电话区域

请参考这篇文章。

虽然是英文，但我相信你会使用翻译工具的，对吧。

OPcache 模块没有被正确配置

如上图，警告 strings buffer 接近上限。解决这个警告不难，只需要按照上面所说的那样，把opcache.interned_strings_buffer调高即可。

这里我把它设置成了16。

Copy
services.nextcloud = {
enable = true;
[...]
phpOptions = {
"opcache.interned_strings_buffer" = "16";
};
};

邮件发送

由于我把 Nextcloud 搭建在 EC2 上，所以我使用了 AWS 的 SES 服务来发送邮件。你也可以选择使用其他服务，比如 SendGrid。

SES 配置比较麻烦，但简单来说，需要做以下几步：

在 AWS 控制台中创建一个 IAM 用户，给予 SES 的发送邮件权限。

在 SES 中验证你的域名。

在 SES 中创建一个 SMTP 凭证。获取到 IAM 用户的 SMTP 用户名和密码。

添加收件人邮箱或者申请解除沙箱限制。

在 Nextcloud 中配置 SMTP。

Copy
services.nextcloud = {
enable = true;
[...]
extraOptions = {
mail_smtpmode = "smtp";
smtpsecure = "ssl";
mail_sendmailmode = "smtp";
mail_from_address = "nextcloud";
mail_domain = "example.com";
mail_smtphost = "smtp.example.com";
mail_smtpport = "465";
mail_smtpauth = 1;
mail_smtpname = "nextcloud@example.com";
mail_smtppassword = "password";`
};
};

SMTP 的配置需要参考 AWS 控制台中的 SMTP 凭证。smtp 服务器地址和端口需要参考 SES 中的信息。

启动应用商店

当使用 Nix 配置文件安装应用商店的应用时，会自动禁用应用商店。但可以调整 Nix 配置手动开启。

Copy
services.nextcloud = {
enable = true;
[...]
appstoreEnable = true;
};

Nix 配置文件参考

大体上就是把本地部署的配置文件的一部分复制到 EC2 中，然后按照先前说的那样做一些调整。

完整配置文件的 IPFS 链接

维护

使用块存储比较不划算，在文件更多时，以后可能会需要使用对象存储以节省费用。Nix 提供了方便的将 S3 挂载 Nextcloud 的方法。

因为 php 的性能问题，不建议在 Nextcloud 中存放大量文件。

刚刚搭建好，还没有遇到什么问题，如果遇到了，会在这里更新。对于比较大的问题，可能会单独发一篇文章。如果想要不错过任何消息，请在区块链上关注我的博客。