.NET Web 应用 Linux 部署全指南:从环境搭建到生产上线

简介

背景和优势

ASP.NET Core.NET Core 1.0(2016 年)起支持跨平台,Linux 部署具有以下优势:

  • 高性能:Linux 服务器(如 Ubuntu)资源占用低,适合高并发。

  • 成本效益:开源操作系统,降低服务器成本。

  • 生态支持:支持 MySQL、Docker、Nginx 等,适配微服务和云原生。

  • 社区活跃:Linux 是云部署(如 AWS、Azure)的首选。

部署方式

ASP.NET Core Web 项目在 Linux 上有以下主要部署方式:

  • 独立部署(Self-contained):

    • 打包应用和 .NET 运行时,独立运行。

    • 适合无 .NET 运行时的 Linux 服务器。

  • 框架依赖部署(Framework-dependent):

    • 仅打包应用,依赖服务器安装的 .NET SDK/运行时。

    • 适合已配置 .NET 环境的服务器。

  • Docker 容器部署:

    • 使用 Docker 容器封装应用和依赖。

    • 适合微服务、云原生和 CI/CD

  • 云平台部署:

    • 使用云服务(如 Azure App Service、AWS Elastic Beanstalk)。

    • 适合快速部署和扩展。

前提条件

目标机器

  • 发行版(Ubuntu、CentOS、Debian、Alpine 等)

  • 已安装 .NET 运行时或 SDK(建议至少 .NET 6 LTS 及以上)

.NET 安装

shell 复制代码
# 以 Ubuntu 为例,安装 .NET 6 运行时
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install -y aspnetcore-runtime-6.0

防火墙与端口

确保托管应用使用的端口(如 500080/443)在防火墙/安全组中开放。

发布与运行(Self-Contained vs Framework-Dependent)

Framework-Dependent 部署

依赖目标主机已安装 .NET 运行时,发布包更小。

shell 复制代码
dotnet publish -c Release -o ./publish

Self-Contained 部署

包含运行时,无需预装 .NET,但体积更大。

shell 复制代码
dotnet publish -c Release -r linux-x64 --self-contained true -o ./publish
  • -c Release:发布优化版本。

  • -o ./publish:输出到 publish 目录。

  • --self-contained true:包含 .NET 运行时。

  • -r linux-x64:目标运行时(Linux 64 位)。

运行:./publish/YourApp

部署应用

传输文件

  • 使用 scprsyncpublish 目录上传到 Linux 服务器:
shell 复制代码
scp -r ./publish user@server:/var/www/yourapp

设置权限

shell 复制代码
sudo chown -R www-data:www-data /var/www/yourapp
sudo chmod -R 755 /var/www/yourapp

直接运行(Kestrel 自托管)

启动应用

shell 复制代码
cd yourapp
dotnet YourApp.dll        # Framework-Dependent
# 或 ./YourApp             # Self-Contained

监听所有接口

appsettings.json 或环境变量中配置:

json 复制代码
"Kestrel": {
  "Endpoints": {
    "Http": { "Url": "http://0.0.0.0:5000" }
  }
}

或:

shell 复制代码
export ASPNETCORE_URLS="http://0.0.0.0:5000"
dotnet YourApp.dll
  • 优点:部署简单;

  • 缺点:缺少负载均衡、TLS 终端、日志管理等企业特性。

使用 systemd 守护进程

将应用作为服务后台运行并随系统启动。

创建 systemd Unit 文件 /etc/systemd/system/kestrel-yourapp.service

ini 复制代码
[Unit]
Description=YourApp ASP.NET Core Service
After=network.target

[Service]
WorkingDirectory=/var/www/yourapp
ExecStart=/usr/bin/dotnet /var/www/yourapp/YourApp.dll
Restart=always
RestartSec=10
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://0.0.0.0:5000

[Install]
WantedBy=multi-user.target

启动与启用

shell 复制代码
sudo systemctl daemon-reload
sudo systemctl start kestrel-yourapp
sudo systemctl enable kestrel-yourapp
sudo journalctl -fu kestrel-yourapp

反向代理(Nginx/Apache)+ Kestrel

推荐生产环境中使用反向代理,实现静态文件缓存、TLS 终端、路径重写等。

安装 Nginx

shell 复制代码
sudo apt install -y nginx

配置 Nginx

/etc/nginx/sites-available/yourapp 中:

nginx 复制代码
server {
    listen 80;
    server_name your.domain.com;

    # 将 HTTP 重定向到 HTTPS(可选)
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name your.domain.com;

    ssl_certificate     /etc/ssl/certs/your.crt;
    ssl_certificate_key /etc/ssl/private/your.key;

    location / {
        proxy_pass         http://127.0.0.1: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;
    }

    # 可选:静态文件直连
    location /static/ {
        root /var/www/yourapp/wwwroot;
        expires 30d;
    }
}

启用配置并重启 Nginx

shell 复制代码
sudo ln -s /etc/nginx/sites-available/yourapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

容器化部署(Docker)

使用 Docker 将环境一致性和可移植性做到极致。

Dockerfile 示例

dockerfile 复制代码
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["YourApp.csproj", "./"]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "YourApp.dll"]

构建与运行

shell 复制代码
docker build -t yourapp:1.0 .
docker run -d -p 80:80 --name yourapp -e ASPNETCORE_ENVIRONMENT=Production yourapp:1.0

使用 Docker Compose

yaml 复制代码
version: '3.8'
services:
  web:
    image: yourapp:latest
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:80"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    depends_on:
      - mysql
    networks:
      - app-network

  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=password
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - app-network
  nginx:
    image: nginx:latest
    ports:
        - "80:80"
    volumes:
        - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
        - web
    networks:
        - app-network  

networks:
  app-network:
    driver: bridge

volumes:
  mysql-data:

Nginx 配置(nginx.conf):

nginx 复制代码
events {}
http {
    server {
        listen 80;
        location / {
            proxy_pass http://web:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

PaaS 平台部署

若不想自管服务器,可选用云厂商 PaaS

  • Azure App Service for Linux

  • AWS Elastic Beanstalk (Docker/.NET Core 平台)

  • Google Cloud Run (容器化)

  • Heroku (使用 Docker buildpacks)

这些平台通常只需推送代码或镜像,自动完成构建、运行、负载均衡与 TLS

运维与监控

  • 日志集中

使用 Microsoft.Extensions.Logging 输出到文件、SyslogELK/EFKPrometheus

  • 健康检查

Startup 配置健康检查端点 app.MapHealthChecks("/health"),并让负载均衡器探活。

  • 自动重启

systemdRestart=alwaysKuberneteslivenessProbe

  • 性能分析

利用 dotnet-counters、dotnet-trace、Application Insights、Prometheus + Grafana 等。

shell 复制代码
# 安装 dotnet-counters
dotnet tool install -g dotnet-counters

# 监控应用性能
dotnet-counters monitor -n your-app --counters System.Runtime,Microsoft.AspNetCore.Http

# 安装 dotnet-trace
dotnet tool install -g dotnet-trace

# 收集性能跟踪
dotnet-trace collect -n your-app --format Speedscope

关键诊断命令

shell 复制代码
# 检查端口监听
sudo ss -tulpn | grep ':5000\|:5001'

# 查看应用日志
journalctl -u your-app --since "10 minutes ago" -f

# 测试数据库连接
psql -h localhost -U your_app_user -d your_app_db -c "SELECT 1"

# 网络连通性测试
curl -v http://localhost:5000/health

# 分析内存使用
top -p $(pgrep -f YourApp)

最佳实践清单

环境标准化:

  • 使用相同版本的 OS.NET 运行时

  • 配置统一的环境变量管理

安全优先:

  • 最小权限原则(非 root 用户运行)

  • 定期更新安全补丁

  • 强制 HTTPS 连接

可靠部署:

  • 使用 CI/CD 流水线自动化部署

  • 实现蓝绿部署或金丝雀发布

  • 保留上一个版本的回滚能力

性能优化:

  • 启用 ReadyToRun 编译

  • 配置响应压缩

  • 使用负载均衡和水平扩展

监控告警:

  • 实现全面的健康检查

  • 集成 APM 工具(如 Application Insights

  • 设置关键指标告警(CPU、内存、错误率)

灾难恢复:

  • 定期备份数据库和应用配置

  • 制定并测试恢复计划

  • 多区域部署关键应用

小结

方式 优点 缺点
直接运行(Kestrel) 最简单、零依赖 缺少 TLS、负载均衡
systemd 管理 稳定重启、开机自启 无反向代理、证书管理需额外
Nginx/Apache 反向代理 + systemd TLS 终端、路径重写、静态缓存 配置略复杂
Docker 容器化 环境隔离、可移植、高度一致 学习成本、镜像管理
云 PaaS 最少运维、自动伸缩 平台依赖、成本相对较高

资源和文档

官方文档:

相关推荐
Charles_go12 小时前
41、C#什么是单例设计模式
java·设计模式·c#
夏霞13 小时前
c# ASP.NET Core SignalR 客户端与服务端自动重连配置指南
开发语言·c#·asp.net
Scout-leaf13 小时前
九成九新自用C#入门文档
c#
烛阴15 小时前
隐式vs显式:解密C#类型转换的底层逻辑
前端·c#
梦里不知身是客1116 小时前
kafka作为Sink
c#·linq
猿来是你_L16 小时前
C# Dictionary 转换成 List
windows·c#·list
kokunka16 小时前
C#类修饰符功能与范围详解
java·开发语言·c#
mudtools17 小时前
.NET驾驭Excel之力:工作簿与工作表操作基础
c#·.net·excel
mudtools17 小时前
.NET驾驭Excel之力:单元格与区域操作详解
c#·.net·excel