'Swagger not working inside Docker in .Net core project?

net core Web API application. I have created swagger with Azure AD authentication. My swagger properly works when I am using IIS. When I run using docker I get This site can’t be reached. Below is my startup code.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        azureActiveDirectoryOptions = configuration.GetSection("AzureAd").Get<AzureActiveDirectoryOptions>();
        swaggerUIOptions = configuration.GetSection("Swagger").Get<SwaggerUIOptions>();
    }

    public IConfiguration Configuration { get; }

    private readonly AzureActiveDirectoryOptions azureActiveDirectoryOptions;
    private readonly SwaggerUIOptions swaggerUIOptions;
    //
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services
           .AddAuthentication(o =>
           {
               o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

           })
           .AddJwtBearer(o =>
           {
               o.Authority = azureActiveDirectoryOptions.Authority;

               o.TokenValidationParameters = new TokenValidationParameters
               {

                   ValidAudiences = new List<string>
                   {
                      azureActiveDirectoryOptions.AppIdUri,
                      azureActiveDirectoryOptions.ClientId
                   },
                   ValidateIssuer = true,
                   ValidateAudience = true,
                   ValidIssuer = "https://KmartAus.onmicrosoft.com/oauth2/default",
                   RoleClaimType = ClaimTypes.Role
               };
           });

        services.AddMvc(options =>
        {

            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); ;

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });

            c.AddSecurityDefinition("oauth2", new OAuth2Scheme
            {
                Type = "oauth2",
                Flow = "implicit",
                AuthorizationUrl = swaggerUIOptions.AuthorizationUrl,
                TokenUrl = swaggerUIOptions.TokenUrl,
                Scopes = new Dictionary<string, string>
                {
                    {"Read", "13269k8-a2ea-45a1-96e7-6580f57b6e30/.default" }
                }
            });
            c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
            {
                    { "oauth2", new[] { "readAccess", "writeAccess" } }
            });
        });


    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {

            c.OAuthClientId(swaggerUIOptions.ClientId);
            c.OAuthClientSecret(swaggerUIOptions.ClientSecret);
            c.OAuthRealm(azureActiveDirectoryOptions.ClientId);
            c.OAuthAppName("Swagger");
            //c.OAuthAdditionalQueryStringParams(new { resource = azureActiveDirectoryOptions.ClientId });
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
        app.UseAuthentication();
        app.UseMvc();
    }
}

Below is my docker file.

FROM microsoft/dotnet:2.1-sdk AS build
ENV ASPNETCORE_URLS http://*:44319
EXPOSE 44319
WORKDIR /src
COPY ["LocationServicesAPI/LocationServicesAPI.csproj", "LocationServicesAPI/"]
RUN dotnet restore "LocationServicesAPI/LocationServicesAPI.csproj"

COPY . .
WORKDIR /src/LocationServicesAPI/


RUN dotnet build LocationServicesAPI.csproj -c Release -o /app

ENTRYPOINT ["dotnet", "LocationServicesAPI.dll"]

When I hit run on Docker, http://localhost:54330/ starts in browser and If I hit http://localhost:54330/swagger/index.html nothing opens up. If I try to hit http://localhost:44319/swagger/index.html then also I am not able to open swagger. Below is my container port mapping whne I do docker ps.

44319/tcp, 0.0.0.0:54330->80/tcp Below files exist inside the container.

Controllers  Dockerfile  LocationServicesAPI.csproj  LocationServicesAPI.csproj.user  Models  Program.cs  Properties  Startup.cs  appsettings.Development.json  appsettings.json  bin  obj  out  wwwroot

Can someone help me to figure it out the issue? Any help would be appreciated. Thanks



Solution 1:[1]

Using the default configuration for ASP.NET Core, swagger only works in the development environment. Add the following environment variable to your Dockerfile

FROM microsoft/dotnet:2.1-sdk AS build
ENV ASPNETCORE_URLS http://*:44319

ENV ASPNETCORE_ENVIRONMENT=Development #Add this line.

EXPOSE 44319
WORKDIR /src
COPY ["LocationServicesAPI/LocationServicesAPI.csproj", "LocationServicesAPI/"]
RUN dotnet restore "LocationServicesAPI/LocationServicesAPI.csproj"

COPY . .
WORKDIR /src/LocationServicesAPI/


RUN dotnet build LocationServicesAPI.csproj -c Release -o /app

ENTRYPOINT ["dotnet", "LocationServicesAPI.dll"]

Solution 2:[2]

the swagger UI is accessible only in dev env by default so rather you change the env to dev or you change the condition in app middelware so you take the swagger middleware out of the condition

 if (env.IsDevelopment())
   {
     app.UseDeveloperExceptionPage();
     app.UseSwagger();
     app.UseSwaggerUI(c => 
     c.SwaggerEndpoint("/swagger/v1/swagger.json", "myappname v1"));
    }

so it will become like this

if (env.IsDevelopment()) {...}
   app.UseSwagger();
   app.UseSwaggerUI(c => 
   c.SwaggerEndpoint("/swagger/v1/swagger.json","myappname v1")); 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zachbugay
Solution 2