C# Linux环境部署完全指南


引言

随着.NET Core的发布和后续.NET 5/6/7的发展,C#应用程序已能完美运行在Linux环境中。本文将全面介绍如何将C#应用部署到Linux服务器,涵盖从基础环境配置到高级部署策略的完整流程,帮助开发者实现从Windows开发环境到Linux生产环境的无缝迁移。

1. 环境准备

1.1 选择Linux发行版

主流支持的选择:

  • Ubuntu (20.04/22.04 LTS) – 最常用的部署选择
  • Debian (10/11) – 稳定性优先
  • CentOS/RHEL (7/8) – 企业级环境
  • Alpine Linux – 容器化部署首选

1.2 安装.NET运行时

Ubuntu/Debian示例:

# 添加微软包仓库
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

# 安装.NET SDK
sudo apt-get update
sudo apt-get install -y dotnet-sdk-6.0

# 仅安装运行时(生产环境)
sudo apt-get install -y aspnetcore-runtime-6.0

验证安装:

dotnet --info

2. 应用发布方式

2.1 框架依赖发布(FDD)

dotnet publish -c Release -f net6.0
  • 需要目标机器安装对应运行时
  • 部署包较小
  • 需确保运行时版本匹配

2.2 独立发布(SCD)

dotnet publish -c Release -f net6.0 -r linux-x64 --self-contained true
  • 包含所有依赖
  • 部署包较大
  • 无需安装运行时

2.3 单文件发布

dotnet publish -c Release -f net6.0 -r linux-x64 --self-contained true /p:PublishSingleFile=true
  • 所有依赖打包到单个可执行文件
  • 启动更快
  • 调试信息需单独处理

3. 部署到Linux服务器

3.1 手动部署流程

  1. 本地发布应用:
   dotnet publish -c Release -r linux-x64 --self-contained true -o ./publish
  1. 上传到服务器:
   scp -r ./publish user@server:/var/www/myapp
  1. 设置执行权限:
   chmod +x /var/www/myapp/MyApp
  1. 测试运行:
   cd /var/www/myapp
   ./MyApp

3.2 自动化部署脚本

#!/bin/bash
# deploy.sh

APP_NAME="MyApp"
DEPLOY_DIR="/var/www/$APP_NAME"
TEMP_DIR="/tmp/$APP_NAME-build"

# 清理旧构建
rm -rf $TEMP_DIR
mkdir -p $TEMP_DIR

# 发布应用
dotnet publish -c Release -r linux-x64 --self-contained true -o $TEMP_DIR

# 停止现有服务
sudo systemctl stop $APP_NAME.service

# 部署新版本
sudo rm -rf $DEPLOY_DIR
sudo mkdir -p $DEPLOY_DIR
sudo cp -r $TEMP_DIR/* $DEPLOY_DIR
sudo chmod +x $DEPLOY_DIR/$APP_NAME

# 启动服务
sudo systemctl start $APP_NAME.service

4. 作为系统服务运行

4.1 创建systemd服务单元

/etc/systemd/system/myapp.service

[Unit]
Description=My .NET Application
After=network.target

[Service]
Type=notify
WorkingDirectory=/var/www/myapp
ExecStart=/var/www/myapp/MyApp
Restart=always
RestartSec=10
KillSignal=SIGINT
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

4.2 管理服务

# 重载服务配置
sudo systemctl daemon-reload

# 启用开机启动
sudo systemctl enable myapp.service

# 启动服务
sudo systemctl start myapp.service

# 查看状态
sudo systemctl status myapp.service

# 查看日志
journalctl -u myapp.service -f

5. 反向代理配置

5.1 Nginx配置示例

/etc/nginx/sites-available/myapp

server {
    listen        80;
    server_name   example.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;
    }
}

启用配置:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx

5.2 Kestrel配置调整

appsettings.json

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      }
    }
  }
}

6. 容器化部署

6.1 Dockerfile示例

# 构建阶段
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app

# 运行时阶段
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.dll"]

6.2 构建和运行

docker build -t myapp .
docker run -d -p 8080:80 --name myapp-container myapp

6.3 使用Docker Compose

docker-compose.yml

version: '3.8'

services:
  myapp:
    image: myapp
    build: .
    ports:
      - "8080:80"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    restart: unless-stopped

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - myapp

7. 高级部署策略

7.1 零停机部署

使用Nginx的流量切换:

upstream backend {
    server 127.0.0.1:5000;
    server 127.0.0.1:5001 backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

部署流程:

  1. 启动新版本到5001端口
  2. 测试新版本
  3. 切换Nginx配置
  4. 停止旧版本

7.2 蓝绿部署

  1. 准备两个相同环境(蓝/绿)
  2. 当前生产流量指向蓝环境
  3. 部署新版本到绿环境并测试
  4. 切换流量到绿环境
  5. 蓝环境变为待机状态

8. 监控与维护

8.1 日志管理

配置日志轮转:

# /etc/logrotate.d/myapp
/var/www/myapp/logs/*.log {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    create 644 root root
}

8.2 健康检查端点

app.MapHealthChecks("/health");
app.MapGet("/version", () => Assembly.GetEntryAssembly()?.GetName().Version?.ToString());

8.3 使用Prometheus监控

安装NuGet包:

dotnet add package prometheus-net.AspNetCore

配置中间件:

app.UseMetricServer();
app.UseHttpMetrics();

9. 常见问题解决

9.1 文件权限问题

sudo chown -R www-data:www-data /var/www/myapp
sudo chmod -R 755 /var/www/myapp

9.2 端口冲突

netstat -tulnp | grep :5000
sudo kill <PID>

9.3 依赖缺失错误

ldd MyApp  # 检查依赖库
sudo apt-get install libunwind8 libicu66

10. 安全最佳实践

  1. 最小权限原则
   sudo useradd -r -s /bin/false myappuser
   sudo chown -R myappuser:myappuser /var/www/myapp
  1. 防火墙配置
   sudo ufw allow 80/tcp
   sudo ufw enable
  1. 定期更新
   sudo apt-get update
   sudo apt-get upgrade
  1. 禁用不必要服务
   sudo systemctl disable unnecessary-service

结语

将C#应用程序部署到Linux环境已成为现代开发的标准实践。通过本文介绍的方法,开发者可以构建稳定、高效且易于维护的Linux部署方案。无论是选择传统的系统服务部署,还是采用现代化的容器化方案,.NET在Linux平台上的表现都能满足企业级应用的需求。随着.NET平台的持续发展,Linux环境下的C#应用部署将变得更加简单高效。


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注