nixos-nexus缓存仓库

待整理

你描述的这个需求,在 NixOS 社区里确实已经有了非常成熟的解决方案。你设想的“代理 + 本地缓存”工作流,正是 **Nix Cache Proxy** 这类项目的核心功能。

### 🎯 核心解决方案:ncps

**ncps (Nix Cache Proxy Server)** 是一个高性能的代理服务器,完全实现了你描述的缓存逻辑。它的工作流程是:

1.  **请求到达**:Nix 客户端向 ncps 请求一个 store path。
2.  **检查本地缓存**:ncps 首先检查本地是否已有该路径。如果有,直接快速返回。
3.  **向上游获取**:如果本地没有,ncps 会从配置的上游缓存(如 `cache.nixos.org`)获取。
4.  **缓存并签名**:获取后,ncps 会在本地存储一份,并使用自己的私钥对其进行签名,然后返回给客户端。

它**原生支持 Docker 部署**,可以完美融入你的 Docker Compose 工作流。

### 📦 其他可选方案

除了 ncps,还有几个项目也值得了解,你可以根据具体需求进行选择:

*   **Spongix**:一个用 Go 编写的代理,同样具备本地缓存和签名功能,并支持将 NAR 文件转发到 S3 进行长期存储。
*   **Attic**:一个可自托管的 Nix 二进制缓存服务器,特点是支持**全局去重**和垃圾回收,适合规模较大的部署场景。
*   **nix-serve**:Nix 官方的参考实现,功能简单直接,适合快速搭建一个基础的二进制缓存服务。
*   **Nginx 透明代理**:如果你不想引入额外的服务,也可以使用 Nginx 的 `proxy_store` 模块,配置一个透明的缓存代理,将上游的包镜像到本地磁盘。

### 🚀 如何在 NixOS 上快速启用

在 NixOS 上,你可以通过 `nix-ld` 来运行 ncps 的 Docker 容器,或者直接使用社区提供的 NixOS 模块。以下是一个 Docker Compose 的配置示例:

```yaml
version: '3.8'
services:
  ncps:
    image: ghcr.io/kalbasit/ncps:latest
    container_name: ncps
    restart: unless-stopped
    ports:
      - "8501:8501"
    volumes:
      - ncps-storage:/storage
    command: >
      /bin/ncps serve
      --cache-hostname=ncps.local
      --cache-storage-local=/storage
      --cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite
      --cache-upstream-url=https://cache.nixos.org
      --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
volumes:
  ncps-storage:
```

启动容器后,在你的 NixOS 配置中,将 `substituters` 指向这个代理即可:

```nix
# configuration.nix
nix.settings.substituters = [ "http://ncps.local:8501" ];
```

这样,所有 `nixos-rebuild` 的请求都会优先经过 ncps 代理,实现你期望的加速和缓存效果。

### 💎 总结

**ncps** 是你需求最直接的对应方案,它通过 Docker 部署,完美实现了你描述的“代理 + 缓存 + 签名”的完整工作流。你可以直接从它的 Docker 镜像开始,快速搭建起自己的私有 Nix 缓存代理。

是的,**ncps 可以通过在其 Docker 容器中设置环境变量来使用代理**,这独立于 NixOS 系统的全局代理配置。

### 解决方案:在 Docker Compose 中注入代理环境变量

在 `docker-compose.yml` 文件中,为 `ncps` 服务添加 `environment` 字段,写入 `http_proxy` 和 `https_proxy` 变量即可:

```yaml
services:
  ncps:
    image: ghcr.io/kalbasit/ncps:latest
    # ... 其他配置
    environment:
      - HTTP_PROXY=http://你的代理地址:端口
      - HTTPS_PROXY=http://你的代理地址:端口
      - NO_PROXY=localhost,127.0.0.1
    # ...
```

### 原理与注意事项

*   **独立于宿主系统**:Docker 容器的环境变量与宿主机是隔离的。通过 `environment` 注入的代理设置,能确保 ncps 在向 `cache.nixos.org` 等上游地址发起请求时,流量会经过你指定的代理服务器。
*   **区分大小写**:建议同时设置 `HTTP_PROXY` 和 `http_proxy`,以兼容不同的网络库实现。`HTTPS_PROXY`/`https_proxy` 同理。
*   **`NO_PROXY` 变量**:推荐设置 `NO_PROXY`,将 `localhost` 和 `127.0.0.1` 排除在外,避免容器内部通信也走代理。
*   **代理地址可达性**:请确保你填写的代理地址(如 `http://127.0.0.1:7890`)在 **Docker 容器的网络命名空间内是可达的**。如果代理运行在宿主机上,通常可以使用 `http://host.docker.internal:7890` 或宿主机的局域网 IP 地址。

这样配置后,ncps 就能通过你指定的代理服务器去拉取和缓存包,解决没有全局代理时的网络问题。