C#は様々な用途に利用できる言語ですが、.NETになってからはサーバーサイドとしてはLinuxで動かすのが自然な選択肢になっています。なぜLinuxで動かすのか理由をいくつか挙げてみます。
もしかすると
C#はWindows向けに開発された言語、.NET Framework (.NET Coreではないもの)のころはWindowsでしか動作しなかったという印象が残っている方もいるのではないでしょうか。この記事は、2020年に.NETとしてブランドが統一されてからは、Windows専用ではなくなりLinuxで動かすことが妥当になっている理由をなるべく分かりやすく解説することを目的としています。
はじめに
.NET Coreの登場以降(現在は.NET)1、クロスプラットフォーム対応が進み、Linuxでも高いパフォーマンスと安定性を発揮するようになりました。私自身は過去に.NET FrameworkだったころC#をWindowsサーバーで動かしていましたが、.NET以降はLinuxで運用していることがほとんどです。
C#サーバーをLinuxで動かす理由として、コスト、コンテナ、エコシステム、パフォーマンス・安定性、セキュリティ、トラブルシュートの6つが挙げられます。別に難しいことはなく、要するに他の言語と同じ理由であって、C#もLinuxで動かすのが合理的判断ということです。
1. コスト
Linuxを選ぶ最大の理由はコストです。LinuxとWindowsはライセンス費用に大きな差があり、主要クラウドのIaaSにおいてLinuxはWindowsより低コストです。オンプレ環境でWindowsサーバーを安く調達できるなどの理由がないなら、Linuxを選ぶと良いでしょう。
背景
どんなサービスにおいても、コストは最優先でサーバー環境を検討することになります。運用コストが低ければ低いほどサービス継続を決定する損益分岐点を下げ、より長くサービスを継続できるのでビジネスサイドに説明し合意を得やすくなります。このため、どんな言語でもどうやったら安く運用できるかは真っ先に検討されるべきですし、みなさんされていることでしょう。C#も例外ではありません。
ARM64にも対応しているのでAWSのGravitonやAzureのArm VM、Google CloudのArm VMを利用でき、x86_64よりもさらに安価なLinuxサーバーを利用できます。x86_64とARM64はビルド時に切り替えるだけで、ほとんどのコードがそのまま動作するため、積極的に狙っていく価値があります。ARM64は経験上、特に暗号系処理で10%程度パフォーマンスが落ちる傾向ですが、x86_64系よりコストが30-40%下がるためトータルで有利です。
IaaS
利用条件にもよりますが、多くのクラウド環境のオンデマンドインスタンスにおいてLinuxインスタンスとWindowsインスタンスで1.7倍程度(ARM64比は2倍程度)の価格差があります。2
以下に主要なクラウドプロバイダーの例を挙げます。
OS | インスタンスタイプ | vCPU | メモリ | 東京リージョンのオンデマンド料金/hour (2025年9月時点) | 同Linuxに対する倍率 |
---|---|---|---|---|---|
Linux | m7i.large | 2 | 8 GB | USD 0.1302 | - |
Linux | m7a.large | 2 | 8 GB | USD 0.14973 | - |
Linux (ARM64) | m7g.large | 2 | 8 GB | USD 0.1054 | - |
Windows | m7i.large | 2 | 8 GB | USD 0.2222 | 170-210% |
Windows | m7a.large | 2 | 8 GB | USD 0.24173 | 172-229% |
OS | マシンタイプ | vCPU | メモリ | 東京リージョンのオンデマンド料金 (2025年9月時点) | 同Linuxに対する倍率 |
---|---|---|---|---|---|
Linux | c4-standard-2 | 2 | 7 GB | USD 0.12439532 | - |
Linux (ARM64) | c4a-standard-2 | 2 | 7 GB | USD 0.11532114 | - |
Windows | c4-standard-2 | 2 | 7 GB | USD 0.21639532 (=0.12439532 + (0.046 * 2 (CPU数))) | 173-187% |
OS | インスタンスタイプ | vCPU | メモリ | 東日本リージョンのオンデマンド料金/hour (2025年9月時点) | 同Linuxに対する倍率 |
---|---|---|---|---|---|
Linux | D2s v6 | 2 | 8 GB | USD 0.1300 | - |
Linux (ARM64) | D2ps v6 | 2 | 8 GB | USD 0.0902 | - |
Windows | D2s v6 | 2 | 8 GB | USD 0.2220 | 170-243% |
FaaS/CaaS
コストを小さくする場合、FaaSやCaaSは有力な選択肢になります。リクエストが散発的であったり、ある程度のボリュームしか来ないなら、サーバーレスは安く、スケール性も担保できて便利です。C#の場合、スタートアップ時間を稼ぐならReadyToRunビルドやNativeAOTビルドを利用することで、コールドスタート時間を小さくできます。
FaaS(Function as a Service)においても、LinuxベースのランタイムはWindowsベースのランタイムよりも安価です。むしろWindowsベースのランタイムを提供しているのは、Microsoft Azure Functionsだけで、AWS LambdaやGoogle Cloud FunctionsはLinuxベースのランタイムしか提供していません。 CaaS(Container as a Service)においては、Linuxコンテナが前提となっています。
2. コンテナ
Linuxコンテナを利用することで、サーバーのデプロイやスケーリングが容易になります。C#はLinuxコンテナでの動作が公式サポートされており、公式からdistroless,chiseledイメージも提供されています。現在では、20MB~前後までイメージサイズが抑えられるようになりました。もちろんサーバーコードが膨れるほどイメージは大きくなりますが、イメージサイズが問題になることはほぼなく、コンテナ動作させるならLinuxコンテナが第一候補になります。
背景
ここ10年でサーバー環境は大きく変化を遂げましたが、特にコンテナ技術の普及は著しいものがあります。C#サーバーも例外ではありません。 .NETは10年に渡って公式にLinux向けコンテナを提供し、.NET 8以降はLinuxコンテナで非root実行をデフォルト化し、Linuxコンテナ運用のベストプラクティスにも沿っています。最新コンテナイメージもDebian/Alpine/Mariner distroless/Ubuntu chiseled3が提供されています。
2023年には、.NETクラウドアプリをRootless Linuxコンテナで実行することを推奨する記事を公開しました。内容は私が認識する限りにおいて、Linuxコンテナサーバーにおける現在合意が取れているものと遜色なく、C#におけるコンテナ運用が一般的であることを示しています。
コンテナOS
C#サーバーをコンテナで動かす場合、Linuxコンテナが普通に利用されます。このため、他言語同様に、一般的なコンテナサービス・プラクティスがそのまま適用できます。コンテナのメモリハードリミットを設定することでC#内部ランタイムのGCやメモリ管理も適切に管理されるため、コンテナのスペック調整でハマることもありません。コンテナにおいてもC#サーバーは非常に安定して動作します。
Kubernetes
コンテナ運用の2台巨頭は、KubernetesとCaaSになって久しいです。CaaSはコンテナにさえなっていれば割と意識することがありません。KubernetesでC#サーバーを動かす場合も、他言語と同様にKubernetesのリソース定義を作成し、デプロイするだけで動作します。C#サーバーだからといって特別な設定は不要です。環境変数で設定を差し込んだり、ConfigMap/Secretを利用したり、Liveness/Readiness Probeを設定したり、Horizontal Pod Autoscalerを設定したりなど一般的なKubernetes運用がそのまま利用できます。
イメージサイズ
コンテナを運用していて最も面倒なのがイメージサイズです。何しろイメージをプルするたびにネットワーク帯域を消費し、ストレージを消費します。特にC#はVM系言語であるため、イメージサイズが大きくなるんじゃないかと印象が先行します。
実際、.NET7までは標準イメージを利用すると200MBを超えるイメージサイズになっていました。しかし、.NET 8以降はchiseledイメージが提供され、VM系の言語でありながらミニマム40-50MB前後の小さなイメージでC#サーバーを動かせます。Alpineベースのイメージも提供されていますが、現行のスタンダードにそってchiseledイメージを利用するのが良いでしょう。
主要なベースイメージのWebサーバーコンテナイメージサイズ例 (2025年9月時点)
以下は.NETWebサーバー用のコンテナイメージのサイズ比較です。デプロイ時に実際に転送されるCompressedサイズに着目すると、Ubuntu Jammyをベースにした場合、chiseledイメージを利用することで約1/5のサイズに削減できます。
Image Kind | Base Image | Uncompressed Image Size | Compressed Image Size | % Size Savings Over Baseline |
---|---|---|---|---|
Baseline | aspnet:8.0-jammy |
217 MB | 90.9 MB | |
Chiseled | aspnet:8.0-jammy-chiseled |
111 MB | 49.3 MB | 46% |
Chiseled + ASP.NET Composite Runtime | aspnet:8.0-jammy-chiseled-composite |
103 MB | 40.8 MB | 55% |
.NETはVM系言語ですが、C#ビルド時に.NETランタイムを同梱(self-contained)して重複排除(triming)することでさらにサイズを小さくできます。このオプションでビルドしても動作に大きな副作用がないので有力な選択です。個人的にまだNativeAOTはおすすめしにくいので、chiseled + Self-contained + Trimmingがおすすめです。
Image Kind | Base Image | Uncompressed Image Size | Compressed Image Size | % Size Savings Over Baseline |
---|---|---|---|---|
Self-contained + Trimming | runtime-deps:8.0-jammy |
146 MB | 57.9 MB | 36% |
Chiseled + Self-contained + Trimming | runtime-deps:8.0-jammy-chiseled |
39.3 MB | 16.4 MB | 82% |
Native AOT | runtime-deps:8.0-jammy-chiseled |
27.7 MB | 12.4 MB | 86% |
3. エコシステム
サーバーを動かすにあたりLinuxにはツールやミドルウェアが充実しています。C#サーバーをLinuxで動かすことで、これらを活用できるため、開発や運用が容易になります。Windowsで運用していた時に都度Windowsで動かせるか気にしていたことを振り返ると、豊富なLinuxノウハウがそのまま活用できるのは地味ですが大きなメリットだと感じます。
背景
Linuxで動作させることで、豊富なオープンソースライブラリやツールを利用できます。これにより、開発効率が向上し、コミュニティへのフィードバックしやすくなります。例えばプロキシサーバーのnginxやEnvoy、各種CLIツール、OpenTelemetry系ツールはわかりやすい例でしょう。特に気にしなくてもLinuxで動くツールと連携できます。
サーバーとしてのC#アプリケーションはASP.NET Coreがデファクトスタンダードとなっていますが、nginxやEnvoyをリバースプロキシとして組み合わせることで、SSL終端や負荷分散、キャッシュなどの機能を簡単に追加できます。4これはKubernetesなどの内部サービス通信で依然として利用されるパターンです。
この辺りは、AIとの協業という観点でも重要です。何しろツールの情報が豊富かどうかは回答の精度に大きく影響します。Linuxツールの情報は豊富であることを背景に、AIを活用した開発や運用がしやすくなります。とはいえ、新しいツールなどでは情報が不足していることもあるので、そういう時は自分で頑張りましょう。
FaaSサポート
エコシステムにはツールだけでなく、FaaSサービスも含めるのが適切でしょう。FaaSは基本的にLinuxベースですが、いずれも最新のC# LTSランタイムがサポートされています。5
サービス | サポートされているC#ランタイム |
---|---|
AWS Lambda | 8.0 |
Google Cloud Run Functions | 8.0 |
Azure Functions | 8.0, 9.0, 10.0 (preview) |
OCI Functions | 8.0 |
4. パフォーマンス・安定性
C#は.NET Core(現在は.NET)においてLinuxで動作することを前提に進化してきたため、パフォーマンスや安定性も備わっています。実際、私の経験でもLinuxの方がパフォーマンスよく小さいリソースで安定動作します。特に安定になって困ったことはないので安心して利用しています。
背景
Linuxは低オーバーヘッドのユーザーランド/カーネル、ネットワーク/I/Oスタックを持っています。.NET/C#もLinuxでの動作を改善する方向に多くの改善が行われています。.NET5、.NET6、.NET7、.NET8、.NET9と毎年のようにパフォーマンス改善が行われており、これらの記事でもたびたびLinuxでの動作最適化が取り上げられています。
Windowsと比較して、Linuxは軽量でリソース消費が少なく、C#サーバーのパフォーマンスを最大限に引き出せます。特にコンテナ環境では、Linuxの軽量性が際立ちます。Windowsだとミニマムでも4-8GB程度のメモリや2vCPUが推奨されますが、Linuxなら256-512MB、1vCPUでも十分に動作します。サイジングをしていてWindowsはOS負荷が大きく、サーバー運用としては余計にリソースが必要だと感じることは否めません。
TechEmpower
WebサーバーのパフォーマンスベンチマークであるTechEmpowerはWindowsがなくLinuxのデータですが、多くの実装の中でC#の位置づけを客観的に見る1つの指標になります。以下は2025年9月時点のRound 23のPlaintextの結果です。C#サーバーであるaspnetcore
は、Linuxで動かす様々な言語のWebサーバー構成の中でも割と良いスコアを出しています。6
TechEmpowerでのスコアはC#ランタイムやASP.NET CoreのIssueでもたびたび参照されており、C#のパフォーマンス改善に関する議論で引用・改善結果の報告が行われているものの、あくまでも参考程度にどうぞ。7
5. セキュリティ
LinuxはOSとしてのセキュリティ機能が豊富です。また、コンテナで動作させることで、より脅威に対する多層防御が可能になります。もちろんOSレベルのセキュリティは最終防御なので、その前にネットワーク・アプリケーションレベルでセキュリティ対策が必要ですが、OSレベルのセキュリティ機能が充実していることは大きな利点です。
背景
SELinux/AppArmor、Capabilities、read-only root filesystem、seccompなど、Linuxには多くのセキュリティ機能が組み込まれています。C#サーバーをLinuxで動かすことで、これらのセキュリティ機能を活用でき、アプリケーションのセキュリティを強化できます。
Windowsにもセキュリティ機能はありますが、Linuxはより細かな制御が可能で、また多くのチューニング情報が公開されているため運用する上で救われることも多いです。もちろん、WindowsにもDefender ATPなど高度なセキュリティ機能があることは付記します。
ディストリビューションの選択
.NETとして複数のLinuxディストリビューションを公式サポートしています。AWSはAmazon Linux (AL2023)もサポートしており、自分が動作する環境に合わせてディストロを選べます。経験上は、コンテナならchiseledイメージ、AWSならAL2023、他ではDebian系(Ubuntu/Debian)が選びやすいです。
6. トラブルシュート
トラブルシュートは、OS、C#アプリケーションそれぞれの観点で行う必要があります。Linuxには多くの診断ツールがあり、C#サーバーもLinuxで診断ツールが利用できるため、Linuxだからといってトラブルシュートで困ったケースはありません。この辺りはどの言語であっても、ある程度の習熟が必要になるため、C#だから特別に難しいということはありません。
背景
トラブルシュートの観点によって異なりますが、Linuxにはstrace
、ltrace
、perf
、gdb
、valgrind
、tcpdump
、iftop
、htop
など多くの診断ツールがあります。Windowsにも診断ツールはあるものの、Linuxの方が多くのツールが利用でき、また多くの情報が公開されているため、OSとしてのトラブルシュートが容易になります。
C#サーバーとして考えたとき、Linuxではdotnet-counters
、dotnet-trace
、dotnet-dump
、dotnet-gcdump
などの診断ツールが利用できます。これらのツールを用いてメモリリークやパフォーマンス問題時にメモリダンプを取得し、必要ならWindowsで解析もできます。必要ならリモートデバッグも可能なので、Linuxだからといってトラブルシュートの道が閉ざされることはありません。
Windowsが好ましいケース
ここまでLinuxで動かす理由を挙げてきましたが、Windowsで動かす方が好ましいケースもあります。例えば以下のようなケースです。
- 自前データセンターやオンプレでWindowsサーバーが安く調達できる
- Windows用ミドルウェアを利用している (あるいはActive Directory連携など)
- .NET Frameworkを利用している (.NET (Core)でないとLinux動作がサポートされていない)
特に業務システムや官公庁システムには該当することもあるでしょうし、環境を刷新しない選択をしている場合もあるでしょう。この記事はLinuxで動かす理由を挙げたものであり、Windowsで動かすことを否定するものではありません。.NETになっても、Windowsで安定して動作するのはC#サーバーの利点です。
まとめ
C#サーバーはLinuxで動かすのが第一選択になった理由を説明しましたが、Windowsを用いるケースも含めて向いているケースを例示してみます。あくまでも一例なので、ご自身の選択を尊重してください。
選択肢 | 向いているケース |
---|---|
Linux | コスト重視、コンテナ利用、最新.NETを利用する、エコシステム活用(OSSツールやFaaS/CaaSが標準的に利用可能) |
Windows | オンプレWindows安価調達、AD/Windowsミドルウェア連携、.NET Frameworkを利用する |
- 過去に.NET Coreと呼ばれていたこともありますが、.NET 5以降は単に.NETと呼ばれています。↩
- 料金ページにある通り、おおむねライセンス費用と考えても差し支えないでしょう。スポットインスタンスやリザーブルドインスタンスに相当する利用条件でも変わります↩
- アプリケーションとランタイム依存関係のみを含む超小型Ubuntuと言えます。https://canonical.com/blog/chiselled-ubuntu-ga↩
- C#自身でリバースプロキシを実装するYARPというライブラリもありますが、既存のプロキシを利用するのが第一候補になるのは他言語と変わりません。↩
- 主要なFaaSのサポート状況: AWS Lambda、Google Cloud Functions、Azure Functions、OCI Functions↩
- TechEmpowerのベンチマークは、ベンチマークハックがやりやすく以前のコードはあまり参考になりませんでしたが、現在は素のシンプルなコードになったので健全なベンチマークと言えます。↩
- dotnet/runtime - Issues、dotnet/aspnetcore -Issues↩