# 搭建 NuGet 私有服务器

DarkM 使用 BaGet 搭建私有 NuGet 服务器,用于管理和分发内部 NuGet 包。


# 📋 为什么搭建私有 NuGet 服务器?

场景 说明
私有包管理 企业内部模块不对外公开
版本控制 统一管理包的版本和依赖
快速分发 内网访问,下载速度快
安全性 控制包的访问权限
离线环境 支持无外网环境开发

# 🎯 BaGet vs NuGet.Server

特性 BaGet NuGet.Server
跨平台 ✅ .NET Core ❌ .NET Framework
管理界面 ✅ 友好 Web UI ❌ 无
API 版本 ✅ NuGet v3 ❌ NuGet v2
数据库支持 ✅ SQLite/SQLServer/MySql/PostgreSQL ✅ SQLServer
存储方式 ✅ 文件系统/云存储 ✅ 文件系统
镜像功能 ✅ 支持 ❌ 不支持
维护状态 ✅ 活跃 ⚠️ 缓慢

结论: 选择 BaGet - 跨平台、功能完善、维护活跃


# 🚀 安装部署

# 方式一:Docker 安装(推荐)

# 1. 创建目录

# 创建 BaGet 数据目录
sudo mkdir -p /srv/baget/{packages,data}
sudo chmod -R 755 /srv/baget
1
2
3

# 2. 创建配置文件

# 创建 appsettings.json
sudo vim /srv/baget/appsettings.json
1
2

配置内容:

{
  "ApiKey": "darkm-nuget-secret-key-2026",
  "PackageDeletionBehavior": "Unlist",
  "AllowPackageOverwrites": true,
  "Database": {
    "Type": "Sqlite",
    "ConnectionString": "Data Source=/var/data/baget.db"
  },
  "Storage": {
    "Type": "FileSystem",
    "Path": "/var/packages"
  },
  "Search": {
    "Type": "Database"
  },
  "Mirror": {
    "Enabled": false,
    "PackageSource": "https://api.nuget.org/v3/index.json"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 3. 启动容器

docker run --detach \
  --name baget \
  --restart always \
  --publish 5000:80 \
  --volume /srv/baget/appsettings.json:/app/appsettings.json \
  --volume /srv/baget/data:/var/data \
  --volume /srv/baget/packages:/var/packages \
  --env BaGet__ApiKey="darkm-nuget-secret-key-2026" \
  baget/baget:latest
1
2
3
4
5
6
7
8
9

参数说明:

参数 说明
--publish 5000:80 映射端口(HTTP)
--volume 数据持久化
--env BaGet__ApiKey API 密钥(用于发布包)

# 4. 查看状态

# 查看容器状态
docker ps | grep baget

# 查看日志
docker logs -f baget
1
2
3
4
5

# 5. 访问管理界面

浏览器访问:http://localhost:5000


# 方式二:自托管部署

# 1. 安装 .NET SDK

# Ubuntu
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y dotnet-sdk-6.0

# macOS
brew install --cask dotnet-sdk

# 验证安装
dotnet --version
1
2
3
4
5
6
7
8
9
10
11

# 2. 下载 BaGet

# 克隆源码
git clone https://github.com/loic-sharma/BaGet.git
cd BaGet

# 编译发布
dotnet publish -c Release -o ./publish
1
2
3
4
5
6

# 3. 配置 BaGet

# 编辑配置文件
vim ./publish/appsettings.json
1
2

# 4. 启动服务

# 进入发布目录
cd ./publish

# 启动 BaGet
dotnet BaGet.dll
1
2
3
4
5

# 5. 配置 Nginx 反向代理

server {
    listen 80;
    server_name nuget.woowis.com;

    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# ⚙️ 配置详解

# 核心配置项

{
  // API 密钥(发布包时必需)
  "ApiKey": "your-secret-key-here",
  
  // 包删除行为:Unlist(隐藏)或 HardDelete(硬删除)
  "PackageDeletionBehavior": "Unlist",
  
  // 是否允许覆盖已发布的包
  "AllowPackageOverwrites": true,
  
  // 数据库配置
  "Database": {
    "Type": "Sqlite",           // SQLite/SqlServer/MySql/PostgreSQL
    "ConnectionString": "Data Source=baget.db"
  },
  
  // 存储配置
  "Storage": {
    "Type": "FileSystem",       // FileSystem/Azure/Aws
    "Path": "/var/packages"     // 包存储路径
  },
  
  // 搜索配置
  "Search": {
    "Type": "Database"          // Database/Lucene
  },
  
  // 镜像配置(代理 NuGet 官方源)
  "Mirror": {
    "Enabled": false,           // 是否启用镜像
    "PackageSource": "https://api.nuget.org/v3/index.json"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 生产环境配置示例

{
  "ApiKey": "darkm-production-key-2026",
  "PackageDeletionBehavior": "HardDelete",
  "AllowPackageOverwrites": false,
  "Database": {
    "Type": "SqlServer",
    "ConnectionString": "Server=192.168.1.100;Database=BaGet;User=baget;Password=***;"
  },
  "Storage": {
    "Type": "FileSystem",
    "Path": "/data/nuget/packages"
  },
  "Search": {
    "Type": "Lucene"
  },
  "Mirror": {
    "Enabled": true,
    "PackageSource": "https://api.nuget.org/v3/index.json"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 📦 创建 NuGet 包

# 项目配置

.csproj 文件中添加包元数据:

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <!-- 包基本信息 -->
    <PackageId>DarkM.Lib.Utils.Core</PackageId>
    <Version>1.2.5</Version>
    <Authors>DarkM</Authors>
    <Company>DarkM</Company>
    <Description>DarkM 框架核心工具库</Description>
    <Copyright>Copyright © DarkM 2026</Copyright>
    
    <!-- 包配置 -->
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <PackageOutputPath>$(SolutionDir)_packages</PackageOutputPath>
    
    <!-- 项目地址 -->
    <PackageProjectUrl>https://glab.woowis.com/Woowis/DarkM</PackageProjectUrl>
    <RepositoryUrl>https://glab.woowis.com/Woowis/DarkM</RepositoryUrl>
    <RepositoryType>git</RepositoryType>
    
    <!-- 许可证 -->
    <PackageLicenseExpression>MIT</PackageLicenseExpression>
    <PackageIcon>logo.png</PackageIcon>
    
    <!-- 标签 -->
    <PackageTags>darkm;utils;core</PackageTags>
    
    <!-- 依赖框架 -->
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
  
  <!-- 包含图标文件 -->
  <ItemGroup>
    <None Include="..\logo.png" Pack="true" PackagePath="\" />
  </ItemGroup>
  
</Project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 打包命令

# 方式一:MSBuild 自动打包(配置了 GeneratePackageOnBuild)
dotnet build

# 方式二:手动打包
dotnet pack -c Release -o ./packages

# 方式三:带版本号打包
dotnet pack -c Release -o ./packages /p:PackageVersion=1.2.5
1
2
3
4
5
6
7
8

# 包结构

DarkM.Lib.Utils.Core.1.2.5.nupkg
├── DarkM.Lib.Utils.Core.dll
├── DarkM.Lib.Utils.Core.xml    # XML 文档
├── lib/
│   └── net5.0/
│       └── DarkM.Lib.Utils.Core.dll
└── DarkM.Lib.Utils.Core.nuspec  # 包描述文件
1
2
3
4
5
6
7

# 🚀 发布包

# 方式一:命令行发布

# 发布单个包
dotnet nuget push DarkM.Lib.Utils.Core.1.2.5.nupkg \
  --api-key darkm-nuget-secret-key-2026 \
  --source http://nuget.woowis.com/v3/index.json \
  --skip-duplicate

# 发布所有包
for file in ./_packages/*.nupkg; do
  dotnet nuget push "$file" \
    --api-key darkm-nuget-secret-key-2026 \
    --source http://nuget.woowis.com/v3/index.json \
    --skip-duplicate
done
1
2
3
4
5
6
7
8
9
10
11
12
13

# 方式二:PowerShell 批量发布

# Windows PowerShell
Get-ChildItem -Path ./_packages/*.nupkg | ForEach-Object {
    dotnet nuget push $_.FullName `
        --api-key darkm-nuget-secret-key-2026 `
        --source http://nuget.woowis.com/v3/index.json `
        --skip-duplicate
}
1
2
3
4
5
6
7

# 方式三:CI/CD 自动发布

.gitlab-ci.yml 示例:

stages:
  - build
  - pack
  - publish

variables:
  NUGET_SOURCE: "http://nuget.woowis.com/v3/index.json"
  NUGET_API_KEY: "$NUGET_API_KEY"  # GitLab CI 变量

build:
  stage: build
  script:
    - dotnet restore
    - dotnet build -c Release

pack:
  stage: pack
  script:
    - dotnet pack -c Release -o ./packages
  artifacts:
    paths:
      - packages/*.nupkg

publish:
  stage: publish
  script:
    - for file in ./packages/*.nupkg; do
        dotnet nuget push "$file" --api-key $NUGET_API_KEY --source $NUGET_SOURCE --skip-duplicate;
      done
  only:
    - tags
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 🔧 配置 NuGet 源

# 全局配置(推荐)

# 添加私有 NuGet 源
dotnet nuget add source http://nuget.woowis.com/v3/index.json \
  --name DarkM \
  --username alex \
  --password darkm-nuget-secret-key-2026 \
  --store-password-in-clear-text

# 查看已配置的源
dotnet nuget list source

# 启用源
dotnet nuget enable source DarkM

# 禁用源
dotnet nuget disable source DarkM

# 删除源
dotnet nuget remove source DarkM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 项目级配置

在项目根目录创建 NuGet.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="DarkM" value="http://nuget.woowis.com/v3/index.json" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceCredentials>
    <DarkM>
      <add key="Username" value="alex" />
      <add key="ClearTextPassword" value="darkm-nuget-secret-key-2026" />
    </DarkM>
  </packageSourceCredentials>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13

# Visual Studio 配置

  1. 打开 工具 → 选项 → NuGet 包管理器 → 包源
  2. 点击 + 添加新源
  3. 填写:
    • 名称: DarkM
    • : http://nuget.woowis.com/v3/index.json
  4. 点击 更新

# 🔍 管理包

# Web 界面管理

访问 http://nuget.woowis.com 可以:

  • ✅ 浏览所有包
  • ✅ 搜索包
  • ✅ 查看包详情
  • ✅ 下载包
  • ✅ 取消列出包(Unlist)
  • ✅ 删除包(如果配置了 HardDelete)

# 命令行管理

# 搜索包
dotnet nuget search DarkM --source http://nuget.woowis.com/v3/index.json

# 查看包详情
dotnet nuget search DarkM.Lib.Utils.Core --source http://nuget.woowis.com/v3/index.json --take 1

# 下载包
dotnet nuget download DarkM.Lib.Utils.Core --version 1.2.5 --source http://nuget.woowis.com/v3/index.json

# 删除包(取消列出)
dotnet nuget delete DarkM.Lib.Utils.Core 1.2.5 \
  --api-key darkm-nuget-secret-key-2026 \
  --source http://nuget.woowis.com/v3/index.json
1
2
3
4
5
6
7
8
9
10
11
12
13

# 📊 监控和维护

# 健康检查

# 检查服务状态
curl http://localhost:5000/v3/index.json

# 查看包统计
curl http://localhost:5000/v3/stats
1
2
3
4
5

# 日志查看

# Docker 方式
docker logs -f baget

# 自托管方式
journalctl -u baget -f
1
2
3
4
5

# 备份数据

# 备份数据库
cp /srv/baget/data/baget.db /backup/baget-$(date +%Y%m%d).db

# 备份包文件
tar -czf /backup/baget-packages-$(date +%Y%m%d).tar.gz /srv/baget/packages
1
2
3
4
5

# 性能优化

{
  // 使用 Lucene 搜索引擎(大数据量时)
  "Search": {
    "Type": "Lucene"
  },
  
  // 使用外部数据库
  "Database": {
    "Type": "SqlServer",
    "ConnectionString": "Server=...;Database=BaGet;..."
  },
  
  // 启用缓存
  "Cache": {
    "Type": "Memory"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 🔒 安全配置

# 1. 启用 HTTPS

server {
    listen 443 ssl;
    server_name nuget.woowis.com;

    ssl_certificate /etc/ssl/certs/nuget.woowis.com.crt;
    ssl_certificate_key /etc/ssl/private/nuget.woowis.com.key;

    location / {
        proxy_pass http://localhost:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2. 配置认证

{
  "ApiKey": "强密钥(至少 32 位)",
  "AllowPackageOverwrites": false
}
1
2
3
4

# 3. 限制访问

# 只允许内网访问
location / {
    allow 192.168.0.0/16;
    allow 10.0.0.0/8;
    deny all;
    
    proxy_pass http://localhost:5000;
}
1
2
3
4
5
6
7
8

# ❓ 常见问题

# 1. 发布失败(401 未授权)

问题: error: Unauthorized

解决:

# 检查 API 密钥是否正确
dotnet nuget push package.nupkg \
  --api-key CORRECT_API_KEY \
  --source http://nuget.woowis.com/v3/index.json
1
2
3
4

# 2. 包已存在

问题: error: Package already exists

解决:

# 方式一:允许覆盖(appsettings.json)
"AllowPackageOverwrites": true

# 方式二:使用 --skip-duplicate
dotnet nuget push package.nupkg --skip-duplicate

# 方式三:删除旧包后重新发布
dotnet nuget delete PackageId 1.0.0 --api-key xxx --source xxx
1
2
3
4
5
6
7
8

# 3. 下载速度慢

解决:

# 检查网络连接
ping nuget.woowis.com

# 使用内网地址
dotnet nuget add source http://192.168.1.100:5000/v3/index.json

# 清除缓存
dotnet nuget locals all --clear
1
2
3
4
5
6
7
8

# 4. Docker 容器启动失败

问题: container exited with code 137

解决:

# 内存不足,增加容器内存限制
docker update --memory 2g baget

# 或增加系统交换空间
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
1
2
3
4
5
6
7
8

# 📚 相关文档


# 🔗 参考链接


最后更新: 2022-08-07