如何在Docker Compose中为.NET C#控制台应用传递命令行参数?
如何在Docker Compose中为.NET控制台应用正确传递命令行参数?
问题现象
运行.NET C#控制台应用时,日志抛出参数为空的异常:
2025-01-15 13:07:47 System.ArgumentException: Required input args was empty. (Parameter 'args') 2025-01-15 13:07:47 at Ardalis.GuardClauses.GuardClauseExtensions.NullOrEmpty[T](IGuardClause guardClause, IEnumerable`1 input, String parameterName, String message, Func`1 exceptionCreator) 2025-01-15 13:07:47 at Personnel.Infrastructure.Migrator.Program.Main(String[] args) in C:\Users\user\RiderProjects\staffpro.learn.redkozubov\src\Services\Personnel\Infrastructure\Personnel.Infrastructure.Migrator\Program.cs:line 21
相关配置代码
Docker Compose配置
personnel_migrator: container_name: personnel_migrator build: context: . dockerfile: src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Migrator/Dockerfile depends_on: - personnel_db networks: - personnel_db ports: - "5001:5001" environment: - CONNECTION_STRING=${CONNECTION_STRING} command: dotnet Personnel.Infrastructure.Migrator.dll --${CONNECTION_STRING}
.env文件内容
CONNECTION_STRING="ConnectionString"
Program.cs核心代码
private static readonly Migrator Migrator = new(); internal static void Main(string[] args) { try { Guard.Against.NullOrEmpty(args); Migrator.Migrate(args); } catch (Exception exception) { Console.WriteLine(exception); throw; } }
Dockerfile代码
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base USER $APP_UID WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Migrator/Personnel.Infrastructure.Migrator.csproj", "src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Migrator/"] COPY ["src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Data/Personnel.Infrastructure.Data.csproj", "src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Data/"] COPY ["src/Services/Personnel/Domain/Personnel.Domain/Personnel.Domain.csproj", "src/Services/Personnel/Domain/Personnel.Domain/"] RUN dotnet restore "src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Migrator/Personnel.Infrastructure.Migrator.csproj" COPY . . WORKDIR "/src/src/Services/Personnel/Infrastructure/Personnel.Infrastructure.Migrator" RUN dotnet build "Personnel.Infrastructure.Migrator.csproj" -c $BUILD_CONFIGURATION -o /app/build FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "Personnel.Infrastructure.Migrator.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish .
解决方案
1. 修正Docker Compose的command参数格式
当前command配置存在两个问题:字符串形式传递命令时shell可能错误解析变量,以及不必要的--前缀(若应用未要求)。改为数组形式传递,避免解析异常:
command: ["dotnet", "Personnel.Infrastructure.Migrator.dll", "${CONNECTION_STRING}"]
如果应用期望参数带命名前缀(如--connection-string xxx),则调整为:
command: ["dotnet", "Personnel.Infrastructure.Migrator.dll", "--connection-string", "${CONNECTION_STRING}"]
2. 修正.env文件的变量格式
.env中变量值的引号会被当作参数的一部分传递,导致应用无法正确识别,直接去掉引号:
CONNECTION_STRING=ConnectionString
3. 可选:通过Dockerfile设置ENTRYPOINT简化配置
在Dockerfile的final阶段添加ENTRYPOINT,固定启动命令,后续Docker Compose只需传递参数:
FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Personnel.Infrastructure.Migrator.dll"]
此时Docker Compose的command可简化为:
command: ["${CONNECTION_STRING}"]
若需带命名前缀则改为:
command: ["--connection-string", "${CONNECTION_STRING}"]
4. 验证参数传递(可选)
在Program.cs的Main方法开头添加日志,确认参数是否正常接收:
Console.WriteLine($"Received args: {string.Join(", ", args)}");
内容的提问来源于stack exchange,提问作者LemonPotion
相关产品推荐
相关产品推荐

