The final result I'm trying to create is a scenario in which the Web API is not exposed to the localhost, yet the Web MVC website can communicate with the Web API, parsing its results.
I'm new to the Docker world, and as I learned how to run multi containers side-by-side, now I'm trying to back-track everything I have learned so far using networking between two of the containers.
I have created two simple, out-of-the-box .NET 5.0 applications:
1. Web API (reaching through HTTP,
using port 7070
)
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 7070
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["CreatingWebAPI/CreatingWebAPI.csproj", "CreatingWebAPI/"]
RUN dotnet restore "CreatingWebAPI/CreatingWebAPI.csproj"
COPY . .
WORKDIR "/src/CreatingWebAPI"
RUN dotnet build "CreatingWebAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "CreatingWebAPI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://+:7070
ENTRYPOINT ["dotnet", "CreatingWebAPI.dll"]
launchSettings.json
: "Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true,
"useSSL": true
}
Program.cs
CreateHostBuilder(string[] args)
as follow:webBuilder.UseUrls("http://*:7070").UseStartup<Startup>();
2. Web MVC that shows a parsed table from the Web API
Running the Web API application through Visual Studio (using Docker
configuration) works just fine, and I can access the localhost:<port>/swagger
without an issue. The problem is that while trying to reproduce the same process using the Docker CLI - I cannot access the /swagger
interface matter what or what port I'm trying to access.
Attached is a photo of the docker CLI showing the same details about both of the containers:
docker run --network personal-net --name api -p 50000:7070 creatingwebapi
I have used different networks and tried to create only one of them at a time. I even tried docker container inspect
on both of these to check for any differences between them without seeing anything different. What might be the issue then?
Specifically about your issue: Swagger exposes your endpoints inputs, outputs, models and even allows anyone to test them ("try it out" button). You don't want that in any environment other than DEVELOPMENT. Same thing applied to wcf and metadata exposure back in the days.
The webapi template follows this rationale and you can find it in the startup.cs file:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication2 v1"));
}
The "if (env.IsDevelopment())" allows usage of swagger only in development environment, or let's say: ASPNETCORE_ENVIRONMENT=Development. If you dont specify the environment, then it's blank, it's not Development, so env.isdevelopment() is false hence you don't get swagger.
I can think of 3 options at least for you to explore and to understand what's going on. Any of these 3 should give you swagger as they set the environment to DEVELOPMENT or they remove this "only development" condition:
ENTRYPOINT ["dotnet", "WebApplication2.dll","--environment=Development"]
docker run -e "ASPNETCORE_ENVIRONMENT=Development" -P --name WebApplication2 webapplication2
I personally would be against item 3. Swagger metadata is useful in lower environments (where you can even create proxy objects out of it), but should not be exposed in Production.
I think there's a bigger picture here: you don't want your API to be exposed to the outside world. So by your definition, swagger should not be accesible by anyone from outside the docker environment (not even you).
I'm thinking how access to the api can be denied from the outside world (hopefully triggering ideas here):
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With