asp.net Docker,所有API调用返回404

rseugnpd  于 2023-01-27  发布在  .NET
关注(0)|答案(2)|浏览(243)

我正在尝试部署我的应用程序,其中包括Angular和ASP.NET。我已经成功地用docker发布了应用程序。当我用docker启动应用程序并从swagger调用任何方法时,我得到404。我该如何修复这个问题?
也许是因为docker是在本地主机上启动的,并试图向本地主机而不是容器发出请求。尽管如此,我认为如果本地主机成功启动,请求也应该工作(?)。
还有一个问题是-我如何用docker启动我的Angular应用程序?当我运行docker时,api是唯一启动的项目。您可能注意到,我已经从csproj中排除了Angular应用程序,因为我添加了额外的步骤来在dockerfile中构建它。
请随时问我任何细节。
其他信息:

[Route("api/[controller]")]
[ApiController]
public class PingController : ControllerBase
{
    [HttpGet("ping")]
    public int Ping()
    {
        return 1;
    }
}

停靠文件:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
    # Setup NodeJs
    RUN apt-get update && \
        apt-get install -y wget && \
        apt-get install -y gnupg2 && \
        wget -qO- https://deb.nodesource.com/setup_16.x | bash - && \
        apt-get install -y build-essential nodejs
    # End setup
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["SelfWebsiteApi/SelfWebsiteApi.csproj", "SelfWebsiteApi/"]
RUN dotnet restore "SelfWebsiteApi/SelfWebsiteApi.csproj"
COPY . .
WORKDIR "/src/SelfWebsiteApi"
RUN dotnet build "SelfWebsiteApi.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "SelfWebsiteApi.csproj" -c Release -o /app/publish


#Angular build
FROM node as nodebuilder

# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY SelfWebsiteApi/SelfWebsiteAngular/package.json /usr/src/app/package.json
RUN npm install
RUN npm install -g @angular/cli --unsafe

# add app
COPY SelfWebsiteApi/SelfWebsiteAngular/. /usr/src/app

RUN npm run build --prod

#End Angular build

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN mkdir -p /app/SelfWebsiteAngular/dist
COPY --from=nodebuilder /usr/src/app/dist/. /app/SelfWebsiteAngular/dist/
ENTRYPOINT ["dotnet", "SelfWebsiteApi.dll"]

项目:

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <SpaRoot>SelfWebsiteAngular\</SpaRoot>
        <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
        <UserSecretsId>57cd274b-65dd-4fa0-938b-cdb4fb135876</UserSecretsId>
        <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="AutoMapper" Version="11.0.1" />
        <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
        <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.5" />
        <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.6" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.5" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.5" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.5">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />
        <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.4" />
        <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
    </ItemGroup>

    <ItemGroup>
        <Content Remove="$(SpaRoot)**" />
        <None Remove="$(SpaRoot)**" />
        <None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
    </ItemGroup>

    <!--<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
        <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
        <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build - -prod" />

        <ItemGroup>
            <DistFiles Include="$(SpaRoot)dist\**" />
            <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
                <RelativePath>%(DistFiles.Identity)</RelativePath>
                <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
                <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
            </ResolvedFileToPublish>
        </ItemGroup>
    </Target>-->
</Project>

program.cs:

var builder = WebApplication.CreateBuilder(args);
var origin = builder.Configuration.GetValue<string>("SelfWebsiteAngular:Name");
var angularLink = builder.Configuration.GetValue<string>("SelfWebsiteAngular:Link");

builder.Services.AddCors(options =>
{
    options.AddPolicy(origin, builder =>
    {
        builder.WithOrigins(angularLink)
        //.AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    });
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<SelfWebsiteContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("SelfWebsiteDatabase")));
builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration.GetValue<string>("Settings:ServerLink"),
            ValidAudience = builder.Configuration.GetValue<string>("Settings:ServerLink"),
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(
                    builder.Configuration.GetValue<string>("Settings:Authorization:SymmetricSecurityKey"))),
        };
    });

builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

builder.Services.AddTransient<ITokenService, TokenService>();
builder.Services.AddTransient<IAuthService, AuthService>();
builder.Services.AddTransient<IResumeService, ResumeService>();
builder.Services.AddTransient<ILinkService, LinkService>();
builder.Services.AddTransient<ISectionService, SectionService>();
builder.Services.AddSingleton<IMapperProvider, MapperProvider>();
builder.Services.AddSpaStaticFiles(configuration =>
{
    configuration.RootPath = "SelfWebsiteAngular/dist";
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseStaticFiles();
//if (!app.Environment.IsDevelopment())
//{
    app.UseSpaStaticFiles();
//}

app.UseSpa(spa =>
{
    // To learn more about options for serving an Angular SPA from ASP.NET Core,
    // see https://go.microsoft.com/fwlink/?linkid=864501

    spa.Options.SourcePath = "SelfWebsiteAngular";

    //if (app.Environment.IsDevelopment())
    //{
        spa.UseAngularCliServer(npmScript: "start");
        // spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
    //}
});

app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(origin);
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
8yparm6h

8yparm6h1#

默认情况下,只有在环境为“开发”时才可以使用Swagger。默认情况下,容器不是开发环境。
Program.cs中执行此操作的代码如下

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

有多种方法可以使Swagger在容器中可用。
您可以通过删除上面代码中的if使其永久可用,这样它就变成

app.UseSwagger();
app.UseSwaggerUI();

您还可以通过如下设置ASPNETCORE_ENVIRONMENT,将映像中的环境设置为“Development

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
ENV ASPNETCORE_ENVIRONMENT=Development
    # Setup NodeJs
    RUN apt-get update && \
        apt-get install -y wget && \
        apt-get install -y gnupg2 && \
        wget -qO- https://deb.nodesource.com/setup_16.x | bash - && \
        apt-get install -y build-essential nodejs
    # End setup
WORKDIR /app
EXPOSE 80
EXPOSE 443

第三个选项是通过向docker run命令添加-e ASPNETCORE_ENVIRONMENT=Development选项,在该命令上传递环境变量。
您应该选择哪种解决方案取决于您希望Swagger永久可用的程度。

5hcedyr0

5hcedyr02#

试试看
app.使用路由();
然后
应用程序使用授权();
因为对我来说,在调试模式下没有此配置时工作正常,但在Docker中不工作。

相关问题