
我が家のサーバで移行ついでについにDocker Composeを利用した仮想環境で構築することにしました。
そのうち忘れそうなので備忘録的にDocker ComposeにてApache 2とASP.Netの連携をしてみようと思います。
検証環境
| 項目 | 詳細 |
|---|---|
| PC | VMware Workstation Pro 仮想マシン |
| OS | Ubuntu 24.04 |
| CPU | Core i7-10700K |
| .Net | .Net 8 |
Apache 2による連携のメリット
ASP.Netはこれ自体にWebサーバの役割があるので基本的にApache 2を介する必要はありません。
これだけなら80番またはHTTPS対応してるなら443番をバインドすればいいだけ。
しかしながら今後サーバが増えていく事を考えると直にポートをバインドしてしまうと他のサービスの公開ができなくなってしまいます。
なのでここではApache 2にWebサーバの役目をしてもらい、ASP.Netとのプロキシになってもらいます。
HTTPSの対応も簡単ですからApache 2やnginxを使うほうが色々とメリットも大きいでしょう。
構築
構成図
構成の図はこのような感じでいきます。

詳細はこのあと書いていきますが、外側へ公開するのはApache 2の80番と443番のポートだけでASP.Netの5000番は公開しません。
もうちょっと構成が増えれば内部ネットワークも分けてもいいと思います。
ファイル構成
ファイル構成はこのような感じに行きます。
Sample
L Apache
L sites
L 000-default.conf
L Dockerfile
L App
L www # Apache 2のwww用
L index.html
L asp # ASP.Netのアプリケーション
L sample.dll
L Asp-App
L Dockerfile
Appディレクトリはコンテナではなく公開したいアプリケーションやファイルを配置する用に使います。
docker-compose.yml
docker-compose.ymlはこんな感じに。
Apache 2とASP.Netだけのシンプルな構成ですが、実際はMySQLやら連携が必要なものが増えていくと思います。
基本は今回のやり方と同じなので増やしていけるかなと。
各内容は個別に書いていきます。
services: apache: build: context: ./Apache dockerfile: Dockerfile restart: always ports: - "80:80" volumes: - "./App/www:/var/www/html" asp-app: build: context: ./Asp-App dockerfile: Dockerfile restart: always volumes: - "./App/asp:/App/asp"
各コンテナ
asp-app
順番が逆になりますが、ASP.Net合ってのApache 2なのでこちらから構築していきます。
今回はASP.Net MVCの初期テンプレートのままで構築するので開発中のアプリに置き換えて見てもらえればと思います。
docker-compose.ymlではDockerfileの指定とボリュームの指定だけとなります。
ボリュームはどこでも良いのでお好きな場所へ。
・docker-compose.yml
asp-app: build: context: ./Asp-App dockerfile: Dockerfile restart: always # ports: # # 動作確認する時だけバインドしておくと便利 # - "8080:5000" volumes: # HOSTの領域とコンテナの領域をバインド - "./App/asp:/App/asp"
Dockerfileでは.Net 8のイメージを指定し、先程バインドしたディレクトリをワーキングディレクトリとします。
あとはdotnetコマンドでアプリケーションを実行するだけ。
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /App/asp ENTRYPOINT ["dotnet", "sample.dll"]
直接関連はないですが、Ubuntuイメージを利用して特定のバージョンの.Netを使う場合はICU等のエラーが出るのでこちらを参考に。
apache
docker-compose.ymlではASP.Netの設定と大体同じですが、それに加えてportsによるHOSTのポートとコンテナのポートのバインドを指定します。
今回はHTTP(80)をバインドします。
実際に運用するのであれば現在はHTTPSが必須の時代なのでHTTPS(443)もバインドしてSSL証明書の用意が必要です。
・docker-compose.yml
apache: build: context: ./Apache dockerfile: Dockerfile restart: always ports: # HOSTの80番とコンテナの80番をバインド - "80:80" volumes: # HOSTの領域とコンテナの領域をバインド - "./App/www:/var/www/html"
公式でhttpdがありますが、個人的にUbuntuのApache 2に慣れているので今回はUbuntuイメージから作成することにしました。
Dockerfile
FROM ubuntu:24.04 RUN apt-get update -y RUN apt-get install -y apache2 COPY ./sites/000-default.conf /etc/apache2/sites-available/000-default.conf RUN a2enmod proxy proxy_html proxy_http ENTRYPOINT ["apachectl", "-D", "FOREGROUND"]
ASP.Netアプリケーションとのプロキシ設定を行います。
000-default.conf
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined ProxyPreserveHost on ProxyPass / http://asp-app:5000/ ProxyPassReverse / http://asp-app:5000/ </VirtualHost>
ここで肝なのがプロキシで指定するURLのホスト名にはDocker Composeのコンテナ名が利用できるところです。
Docker Composeではコンテナ名がそのままホスト名になるので、コンテナ同士が同じネットワークで繋がっていればコンテナ名を指定するだけで接続が可能になります。
ちなみに5000番はASP.Netの実装やappsettings.jsonの設定次第で変わるので注意してください。
一応後で違う場合の確認方法を記載しておきます。
もし今後MySQLやPHP-FPMを入れる事になってもコンテナ名を指定するだけで接続ができるので覚えておきましょう。
起動
ここまでできたらあとは起動するだけです。
# イメージのビルド $ sudo docker compose build # コンテナの起動 $ sudo docker compose up -d
初回やdocker-compose.ymlの修正ならup -dだけでいいんですが、Dockerfileの修正が入るとイメージの作り直しがいるので、buildもセットで行うと良いでしょう。
大体初手でうまくは行かないのでダメなときはトラブルシューティングしていきましょう。
接続確認
構築できたら最後はHOSTのIPアドレスへ繋ぐだけです。

うまく繋がればOK。
バーチャルホストを使ったプロジェクト等でドメインがいる場合はhostsを弄る等ちょっと工夫がいります。
トラブルシューティング
Apache 2に繋がらない
接続確認でそもそも繋がらない場合はApache 2が動いてません。
この場合はコンテナのログを見てみましょう。
$ sudo docker compose logs apache
例えば000-default.confを不正な形式にしてみると
$ sudo docker compose logs apache apache-1 | AH00526: Syntax error on line 7 of /etc/apache2/sites-enabled/000-default.conf: apache-1 | Invalid command 'ss', perhaps misspelled or defined by a module not included in the server configuration
こんな感じにエラーのログが出ていることがあるのでエラーを解決しましょう。
Service Unavailableが出る
Apache 2には繋がるけど503エラーが出る場合はASP.Netが動いていません。
まずはASP.Netのログを見ます。
$ sudo docker compose logs asp-net asp-app-1 | The command could not be loaded, possibly because: asp-app-1 | * You intended to execute a .NET application: asp-app-1 | The application 'sample_bad.dll' does not exist. asp-app-1 | * You intended to execute a .NET SDK command: asp-app-1 | No .NET SDKs were found. asp-app-1 | asp-app-1 | Download a .NET SDK: asp-app-1 | https://aka.ms/dotnet/download asp-app-1 | asp-app-1 | Learn about SDK resolution: asp-app-1 | https://aka.ms/dotnet/sdk-not-found
今回はDockerfileのエントリーポイントに誤りがあるのでそれを直せば動きます。
・Dockerfile
ENTRYPOINT ["dotnet", "sample.dll"]
あとは再ビルドして再起動しましょう。
Proxy Errorが出る
Proxy Errorが出る場合はプロキシ設定に誤りがあります。
この場合はまずはapacheコンテナに入ってログを見ましょう。
$ sudo docker compose exec apache /bin/bash root@70f6f91f12cb:/# cd /var/log/apache2 root@70f6f91f12cb:/var/log/apache2# cat error.log AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message [Thu Jun 12 18:47:11.415362 2025] [mpm_event:notice] [pid 21:tid 125944831571840] AH00489: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations [Thu Jun 12 18:47:11.415447 2025] [core:notice] [pid 21:tid 125944831571840] AH00094: Command line: '/usr/sbin/apache2 -D FOREGROUND' [Thu Jun 12 18:47:14.162441 2025] [proxy:error] [pid 22:tid 125944816043712] [client 192.168.0.81:55906] AH00898: DNS lookup failure for: asp-app_bad returned by / [Thu Jun 12 18:47:25.942234 2025] [proxy:error] [pid 24:tid 125944816043712] [client 192.168.0.81:55912] AH00898: DNS lookup failure for: asp-app_bad returned by /
すると一番下に「asp-app_bad」DNSルックアップ失敗の一文があるのでホスト名が誤ってそうだとわかります。
一応ネットワークが繋がっていない可能性もあるのでcurlで正しいと思われるURLのチェックして問題ないか見ておきましょう。
root@70f6f91f12cb:/# apt update root@70f6f91f12cb:/# apt install curl root@70f6f91f12cb:/# curl http://asp-app:5000/ ... (html)
正常にHTMLが取得できればネットワークも問題ないのでプロキシ設定を修正して再ビルドしましょう。
・000-default.conf
ProxyPreserveHost on
ProxyPass / http://asp-app:5000/
ProxyPassReverse / http://asp-app:5000/
ASP.Netは起動してるのにApache 2から繋がらない
Ubuntuベースでdotnetを個別に構築している場合やASP.Netのソース次第ではありますが、localhostからの接続以外は受け付けないようになっている場合があります。
$ sudo docker compose logs asp-app asp-app-1 | info: Microsoft.Hosting.Lifetime[14] asp-app-1 | Now listening on: http://localhost:5000 asp-app-1 | info: Microsoft.Hosting.Lifetime[0] asp-app-1 | Application started. Press Ctrl+C to shut down. asp-app-1 | info: Microsoft.Hosting.Lifetime[0] asp-app-1 | Hosting environment: Production asp-app-1 | info: Microsoft.Hosting.Lifetime[0] asp-app-1 | Content root path: /App/asp
このようにlistening onが「http://localhost:5000」になっていると外部からの接続は受けて受けてくれません。
この場合は同じDocker Compose内と言っても接続が受け付けてくれないので設定を変更してlocalhost以外も受け付けてくれるようにする必要があります。
・appsettings.json
{ "Kestrel": { "Endpoints": { "Http": { "Url": "http://*:5000" } } }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Kestrel.Endpoints.Http.Urlをこのようにワイルドカードにすることで全HOSTからの接続を受け付けるようになります。
また、リスニングポートをここで変更することも可能です。
またはDockerfileに環境変数を指定することでも同様の対応が可能です。
・Dockerfile
... ENV ASPNETCORE_URLS http://*:5000 ...
再度ビルドして再起動するとこのように「http://[::]:5000」となるのでApache 2からも接続できるようになります。
$ sudo docker compose logs asp-app asp-app-1 | info: Microsoft.Hosting.Lifetime[14] asp-app-1 | Now listening on: http://[::]:5000 asp-app-1 | info: Microsoft.Hosting.Lifetime[0] asp-app-1 | Application started. Press Ctrl+C to shut down. asp-app-1 | info: Microsoft.Hosting.Lifetime[0] asp-app-1 | Hosting environment: Production asp-app-1 | info: Microsoft.Hosting.Lifetime[0] asp-app-1 | Content root path: /App/asp
ちなみに公式の「mcr.microsoft.com/dotnet/aspnet:8.0」等のイメージを使うとデフォルトでワイルドカード相当の設定がなされているようでこの問題は基本的に起きません。