【Docker】Asp.net core在docker容器中的端口問題


還記得【One by one系列】一步步學習docker(三)——實戰部署dotnetcore中遇到的問題么?容器內部啟動始終是80端口,並不由命令左右。

docker run --name container-name -p 81:5000 mywebapi

所謂知其然就要知其所以然,淺嘗輒止並不是個好習慣,主要是以下幾個因素共通導致了這種情況。

1.Kestrel配置

ASP.NET Core項目使用Kestrel作為默認的web服務器。

而集成Kestrel的ASP.NET Core有4中方式指定終結點URL:

  • ASPNETCORE_URLS 環境變量
  • --urls命令行參數
  • urls 主機配置鍵
  • UseUrls擴展方法

2.按圖索驥-Dockerfile

2.1 Asp.Net Core Runtime

首先我們按照asp.net core的其中一個版本構建鏡像的Dockerfile

ARG REPO=mcr.microsoft.com/dotnet/core/runtime
FROM $REPO:3.1-buster-slim

# Install ASP.NET Core
RUN aspnetcore_version=3.1.4 \
    && curl -SL --output aspnetcore.tar.gz https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$aspnetcore_version/aspnetcore-runtime-$aspnetcore_version-linux-x64.tar.gz \
    && aspnetcore_sha512='a761fd3652a0bc838c33b2846724d21e82410a5744bd37cbfab96c60327c89ee89c177e480a519b0e0d62ee58ace37e2c2a4b12b517e5eb0af601ad9804e028f' \
    && echo "$aspnetcore_sha512  aspnetcore.tar.gz" | sha512sum -c - \
    && tar -ozxf aspnetcore.tar.gz -C /usr/share/dotnet ./shared/Microsoft.AspNetCore.App \
    && rm aspnetcore.tar.gz
  • 基於.net core基礎鏡像
  • 運行命令,下載asp.net core指定版本的運行時壓縮包
  • 驗證壓縮包正確性
  • 解壓壓縮文件
  • 刪除壓縮文件

2.2 .Net Core Runtime

根據上面的Dokcerfile,可以看到asp.net core的鏡像是在.net core的基礎上構建的,所以繼續找到.net core的構建鏡像的Dockerfile

ARG REPO=mcr.microsoft.com/dotnet/core/runtime-deps
FROM $REPO:3.1-buster-slim

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        curl \
    && rm -rf /var/lib/apt/lists/*

# Install .NET Core
RUN dotnet_version=3.1.4 \
    && curl -SL --output dotnet.tar.gz https://dotnetcli.azureedge.net/dotnet/Runtime/$dotnet_version/dotnet-runtime-$dotnet_version-linux-x64.tar.gz \
    && dotnet_sha512='1869565558e5a85b6a898e792d7b5dece611b25f7f6fd8f015ffb16dccc7485f1412e04809da2e3f56744d24c75e1d3addbd2856c45ae7e66a2c7b71ea23e827' \
    && echo "$dotnet_sha512 dotnet.tar.gz" | sha512sum -c - \
    && mkdir -p /usr/share/dotnet \
    && tar -ozxf dotnet.tar.gz -C /usr/share/dotnet \
    && rm dotnet.tar.gz \
    && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet

2.3 .NET Core Runtime Dependencies

根據上面的Dokcerfile,可以看到.net core的鏡像是在runtime-deps的基礎上構建的,所以繼續找到runtime-deps的構建鏡像的Dockerfile

FROM amd64/debian:buster-slim

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        ca-certificates \
        \
# .NET Core dependencies
        libc6 \
        libgcc1 \
        libgssapi-krb5-2 \
        libicu63 \
        libssl1.1 \
        libstdc++6 \
        zlib1g \
    && rm -rf /var/lib/apt/lists/*

# Configure web servers to bind to port 80 when present  
# 這就是真相
ENV ASPNETCORE_URLS=http://+:80 \
    # Enable detection of running in a container
    DOTNET_RUNNING_IN_CONTAINER=true

3.真相浮出水面

ENV ASPNETCORE_URLS=http://+:80 \

沒錯正是在基礎鏡像.NET Core Runtime Dependencies構建鏡像的Dockerfile中指定了應用終結點URL

ENV ASPNETCORE_URLS=http://+:80

所以你想修改默認端口,在你的Dockerfile添加如下,修改默認值即可:

ENV ASPNETCORE_URLS=http://+:5000

4.寫在末尾

  • 通過這樣剝洋蔥般的溯源鏡像,你會發現到最后,最后一個鏡像一定是操作系統鏡像,這也說明了一個鏡像就是在一個操作系統鏡像上不斷增加運行環境、SDK等等,進而形成特定的新鏡像.
  • Docker容器的最佳實踐是一個容器只運行一個進程,意味着一個容器就暴露一個端口,所以去修改默認端口沒有很大的必要性。這里對其問題溯源只是作為一個了解.

作者:Garfield

同步更新至個人博客:http://www.randyfield.cn/

本文版權歸作者所有,未經許可禁止轉載,否則保留追究法律責任的權利,若有需要請聯系287572291@qq.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM