(This tutorial is based on “Scale ASP.NET Core Apps with Docker Swarm Mode” tutorial by Stefan Prodan.)
Using Visual Studio 2019, create an ASP.NET Web API project named TokenGen.
Be sure to “Enable Docker Support” by clicking on the chechbox as shown in the image below.

It will create a Dockerfile with these contents:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["TokenGen/TokenGen.csproj", "TokenGen/"]
RUN dotnet restore "TokenGen/TokenGen.csproj"
COPY . .
WORKDIR "/src/TokenGen"
RUN dotnet build "TokenGen.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "TokenGen.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TokenGen.dll"]
(For an explanation on what these Dockerfile contents mean, you can refer to this: “How Visual Studio builds containerized apps (version vs-2019)”)
After the projects is created, go to the Controllers folder and add a new controller named TokenController with the following content:
namespace TokenGen.Controllers
{
[Route("api/[controller]")]
public class TokenController : Controller
{
[HttpGet]
public dynamic Get()
{
return new
{
Guid = Guid.NewGuid().ToString(),
Expires = DateTime.UtcNow.AddHours(1),
Issuer = Environment.MachineName
};
}
}
}
appsettings.json
Add SampleSettings to your appsettings.json file like so:
{
"Logging": {
...
},
...
"SampleSettings": {
"Setting1": "setting-1",
"Setting2": "setting-2"
}
}
SampleSettings classCreate a class that will hold your new settings:
public class SampleSettings
{
public const string SETTINGS_NAME = "SampleSettings";
public string Setting1 { get; set; }
public string Setting2 { get; set; }
}
SampleSettings
Configure SampleSettings to get data from the appsettings.json. Then add it to your DI container by updating the ConfigureServices() method in your Startup class like this:
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
...
services.Configure<SampleSettings>(Configuration.GetSection(SampleSettings.SETTINGS_NAME));
}
...
}
Then inject the SampleSettings in your TokenController using the IOptionsMonitor interface, then use it inside the Get() action method to retrieve the settings from the appsettings.json.
Using IOptionsMonitor allows your app to be able to get the latest changes in your appsettings.json file without the need to restart the app.
(For more information about IOptionsMonitor, go here)
[Route("api/[controller]")]
public class TokenController : Controller
{
private readonly IOptionsMonitor<SampleSettings> sampleSettings;
public TokenController(IOptionsMonitor<SampleSettings> sampleSettings)
{
this.sampleSettings = sampleSettings;
}
[HttpGet]
public dynamic Get()
{
return new
{
Guid = Guid.NewGuid().ToString(),
Expires = DateTime.UtcNow.AddHours(1),
Issuer = Environment.MachineName,
Setting1 = sampleSettings.CurrentValue.Setting1,
Setting2 = sampleSettings.CurrentValue.Setting2,
};
}
}
(You can see the resulting project in this public GitHub repository.)
Open a command window in root folder of the project created in Step 1 (the folder where the .sln file is located).
Execute this command to build a Docker image named tokengen-img:
docker build -t tokengen-img -f ./TokenGen/Dockerfile .
After that, when you execute
docker images
you will see tokengen-img as one of the images listed.
REPOSITORY TAG IMAGE ID
tokengen-img latest be76db52e663
mcr.microsoft.com/dotnet/core/sdk 3.1-buster 9ab567a29502
mcr.microsoft.com/dotnet/core/aspnet 3.1-buster-slim bdca989bc8d3
First, enable Docker Swarm mode by executing this command:
docker swarm init
Then create a service. (For an explanation of the difference between a Docker container and a Docker service, go here.)
docker service create --publish 5000:80 --name tokengen tokengen-img
Execute this command to check if the service is running:
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
y547fhp4q76x tokengen replicated 1/1 tokengen-img:latest *:5000->80/tcp
Now, open a PowerShell window then run this:
Invoke-RestMethod http://localhost:5000/api/token
You will get a response that looks similar to this:
guid : 16488c14-5e91-470e-819f-1a36423b8049
expires : 2020-09-02T05:41:22.8778958Z
issuer : f579e9da1691
setting1 : setting-1
setting2 : setting-2
Update the app settings by running this command:
docker service update --env-add SampleSettings:Setting1=new-setting-1-value tokengen
Note that we are SampleSettings:Setting1, with the colon. That is how you refer to the Setting1 setting inside the appsettings.json file:
"SampleSettings": {
"Setting1": "setting-1"
...
Open the PowerShell window again then run
Invoke-RestMethod http://localhost:5000/api/token
You will see that setting1 has now changed to the new value, new-setting-1-value:
guid : b88f9715-5a78-4cd5-899e-2a05210cde25
expires : 2020-09-02T05:48:58.228479Z
issuer : 2e3b9e0e4949
setting1 : new-setting-1-value
setting2 : setting-2
The end.
Bow. ![]()
Update (Oct 11, 2020):
I found a very interesting talk about Docker: “Heresy in the Church of Docker” by Corey Quinn, a Cloud Economist. Watch it if you have time ![]()