Open Source Web Application Framework for ASP.NET Core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

90 KiB

//[doc-seo]
{
    "Description": "Learn to deploy your ABP application using Docker Compose, including building images and modifying configurations for production environments."
}

Docker Deployment using Docker Compose

//[doc-params]
{
    "UI": ["MVC", "Blazor", "BlazorServer", "NG"],
    "DB": ["EF", "Mongo"],
    "Tiered": ["Yes", "No"]
}

This document assumes that you prefer to use {{ UI_Value }} as the UI framework and {{ DB_Value }} as the database provider. For other options, please change the preference at the top of this document.

This guide will guide you through how to build docker images for your application and run on localhost using docker compose. You will learn the provided build scripts and docker compose files in detail and how to modify them for the production environment.

Building Docker Images

Each application contains a dockerfile called Dockerfile.local for building the docker image. As the naming implies, these Dockerfiles are not multi-stage Dockerfiles and require the project to be built in Release mode to create the image. Currently, if you are building your images using CI & CD pipeline, you either need to include the SDK to your pipeline before building the images or add your own multi-stage dockerfiles.

Since they are not multi-staged Dockerfiles, if you want to build the images individually, you can navigate to the related to-be-hosted application folder and run the following command:

dotnet publish -c Release

To populate the Release folder first, which will be used to build the docker images. Afterward, you can run the following command:

docker build -f Dockerfile.local -t mycompanyname/myappname:version .

To manually build your application image.

To ease the process, application templates provide a build script to build all the images with a single script under etc/docker-compose folder named build-images-locally.ps1. Based on your application name, UI and type, a build image script will be generated.

{{ if UI == "MVC"}}

param ($version='latest')

$currentFolder = $PSScriptRoot
$slnFolder = Join-Path $currentFolder "../../"

Write-Host "********* BUILDING DbMigrator *********" -ForegroundColor Green
$dbMigratorFolder = Join-Path $slnFolder "src/Acme.BookStore.DbMigrator"
Set-Location $dbMigratorFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-db-migrator:$version .

Write-Host "********* BUILDING Web Application *********" -ForegroundColor Green
$webFolder = Join-Path $slnFolder "src/Acme.BookStore.Web"
Set-Location $webFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-web:$version .

	{{ if Tiered == "Yes"}}
Write-Host "********* BUILDING Api.Host Application *********" -ForegroundColor Green
$hostFolder = Join-Path $slnFolder "src/Acme.BookStore.HttpApi.Host"
Set-Location $hostFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-api:$version .

Write-Host "********* BUILDING AuthServer Application *********" -ForegroundColor Green
$authServerAppFolder = Join-Path $slnFolder "src/Acme.BookStore.AuthServer"
Set-Location $authServerAppFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-authserver:$version .
	{{ end }}

### ALL COMPLETED
Write-Host "COMPLETED" -ForegroundColor Green
Set-Location $currentFolder

{{ end }}

{{ if UI == "NG"}}

param ($version='latest')

$currentFolder = $PSScriptRoot
$slnFolder = Join-Path $currentFolder "../../"

Write-Host "********* BUILDING DbMigrator *********" -ForegroundColor Green
$dbMigratorFolder = Join-Path $slnFolder "src/Acme.BookStore.DbMigrator"
Set-Location $dbMigratorFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-db-migrator:$version .

Write-Host "********* BUILDING Angular Application *********" -ForegroundColor Green
$angularAppFolder = Join-Path $slnFolder "../angular"
Set-Location $angularAppFolder
yarn
npm run build:prod
docker build -f Dockerfile.local -t acme/bookstore-angular:$version .

Write-Host "********* BUILDING Api.Host Application *********" -ForegroundColor Green
$hostFolder = Join-Path $slnFolder "src/Acme.BookStore.HttpApi.Host"
Set-Location $hostFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-api:$version .

	{{ if Tiered == "Yes"}}
$authServerAppFolder = Join-Path $slnFolder "src/Acme.BookStore.AuthServer"
Set-Location $authServerAppFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-authserver:$version .
	{{ end }}

### ALL COMPLETED
Write-Host "COMPLETED" -ForegroundColor Green
Set-Location $currentFolder

{{ end }}

{{ if UI == "Blazor" }}

param ($version='latest')

$currentFolder = $PSScriptRoot
$slnFolder = Join-Path $currentFolder "../../"

Write-Host "********* BUILDING DbMigrator *********" -ForegroundColor Green
$dbMigratorFolder = Join-Path $slnFolder "src/Acme.BookStore.DbMigrator"
Set-Location $dbMigratorFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-db-migrator:$version .

Write-Host "********* BUILDING Blazor Application *********" -ForegroundColor Green
$blazorFolder = Join-Path $slnFolder "src/Acme.BookStore.Blazor"
Set-Location $blazorFolder
dotnet publish -c Release -p:PublishTrimmed=false
docker build -f Dockerfile.local -t acme/bookstore-blazor:$version .

Write-Host "********* BUILDING Api.Host Application *********" -ForegroundColor Green
$hostFolder = Join-Path $slnFolder "src/Acme.BookStore.HttpApi.Host"
Set-Location $hostFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-api:$version .
	{{ if Tiered == "Yes"}} 
$authServerAppFolder = Join-Path $slnFolder "src/Acme.BookStore.AuthServer"
Set-Location $authServerAppFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-authserver:$version .
	{{ end }}
### ALL COMPLETED
Write-Host "COMPLETED" -ForegroundColor Green
Set-Location $currentFolder

{{ end }}

{{ if UI == "BlazorServer" }}

param ($version='latest')

$currentFolder = $PSScriptRoot
$slnFolder = Join-Path $currentFolder "../../"

Write-Host "********* BUILDING DbMigrator *********" -ForegroundColor Green
$dbMigratorFolder = Join-Path $slnFolder "src/Acme.BookStore.DbMigrator"
Set-Location $dbMigratorFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-db-migrator:$version .

Write-Host "********* BUILDING Blazor Application *********" -ForegroundColor Green
$blazorFolder = Join-Path $slnFolder "src/Acme.BookStore.Blazor"
Set-Location $blazorFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-blazor:$version .

	{{ if Tiered == "Yes"}}
$authServerAppFolder = Join-Path $slnFolder "src/Acme.BookStore.AuthServer"
Set-Location $authServerAppFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-authserver:$version .

Write-Host "********* BUILDING Api.Host Application *********" -ForegroundColor Green
$hostFolder = Join-Path $slnFolder "src/Acme.BookStore.HttpApi.Host"
Set-Location $hostFolder
dotnet publish -c Release
docker build -f Dockerfile.local -t acme/bookstore-api:$version .
	{{ end }}
### ALL COMPLETED
Write-Host "COMPLETED" -ForegroundColor Green
Set-Location $currentFolder

{{ end }}

The image tag is set to latest by default. You can update the param $version at the first line to set it as a tag for your images.

You can examine all the provided Dockerfiles required to publish your application below;

DBMigrator

DbMigrator is a console application that is used to migrate the database of your application and seed the initial important data to run your application. Such as pre-defined languages, admin user and role, OpenIddict applications and scopes.

Dockerfile.local is provided under this project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "BookStore.DbMigrator.dll"]

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to DbMigrator folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-db-migrator:latest . #Builds the image with "latest" tag

{{ if UI == "MVC" }}

MVC/Razor Pages

​ {{ if Tiered == "Yes" }}MVC/Razor Pages application is a server-side rendering application that uses Cookie authentication as the default scheme and OpenIdConnect as the default challenge scheme.

In the WebModule under authentication configuration, there is an extra configuration for containerized environment support:

if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"]))
{
    context.Services.Configure<OpenIdConnectOptions>("oidc", options =>
    {
        options.TokenValidationParameters.ValidIssuers = new[]
        {
            configuration["AuthServer:MetaAddress"].EnsureEndsWith('/'), 
            configuration["AuthServer:Authority"].EnsureEndsWith('/')
        };

        options.MetadataAddress = configuration["AuthServer:MetaAddress"].EnsureEndsWith('/') +
                                ".well-known/openid-configuration";

        var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider;
        options.Events.OnRedirectToIdentityProvider = async ctx =>
        {
            // Intercept the redirection so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/authorize";

            if (previousOnRedirectToIdentityProvider != null)
            {
                await previousOnRedirectToIdentityProvider(ctx);
            }
        };
        var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut;
        options.Events.OnRedirectToIdentityProviderForSignOut = async ctx =>
        {
            // Intercept the redirection for signout so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/logout";

            if (previousOnRedirectToIdentityProviderForSignOut != null)
            {
                await previousOnRedirectToIdentityProviderForSignOut(ctx);
            }
        };
    });

}

This is used when the AuthServer is running on docker containers(or pods) to configure the redirection URLs for the internal network and the web. The application must be redirected to real DNS (localhost in this case) when the /authorize and /logout requests over the browser but handle the token validation inside the isolated network without going out to the internet. "AuthServer:MetaAddress" appsetting should indicate the container/pod service name while the AuthServer:Authority should be pointing to real DNS for the browser to redirect.

The appsettings.json file does not contain AuthServer:IsOnK8s and AuthServer:MetaAddress settings since they are used for orchestrated deployment scenarios, you can see these settings are overridden by the docker-compose.yml file.

Dockerfile.local is provided under this project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "Acme.BookStore.Web.dll"]

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to the Web folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-web:latest . #Builds the image with "latest" tag

​ {{ end }} {{ if Tiered == "No" }}MVC/Razor Pages application is a server-side rendering application that contains both the OpenID-provider and the Http.Api endpoints within self; it will be a single application to deploy. Dockerfile.local is provided under this project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
RUN dotnet dev-certs https -v -ep authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED

FROM base AS final
WORKDIR /app
COPY --from=build /src .

ENTRYPOINT ["dotnet", "Acme.BookStore.Web.dll"]

You can come across an error when the image is being built. This occurs because of dotnet dev-certs command trying to list the existing certificates inside the container and unavailable to. This error is not important since we aim to generate the authserver.pfx file and discard the container it is built in.

auth-server-pfx-generation-error

Since it contains the openid-provider within, it also uses multi-stages to generate authserver.pfx file which is used by OpenIddict as signing and encryption certificate. This configuration is found under the PreConfigureServices method of the WebModule:

if (!hostingEnvironment.IsDevelopment())
{
    PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
    {
        options.AddDevelopmentEncryptionAndSigningCertificate = false;
    });

    PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
    {
        serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
        serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
    });
}

This configuration disables the DevelopmentEncryptionAndSigningCertificate and uses a self-signed certificate called authserver.pfx. for signing and encrypting the tokens. This certificate is created when the docker image is built using the dotnet dev-certs tooling. It is a sample-generated certificate, and it is recommended to update it for the production environment. You can check the OpenIddict Encryption and signing credentials documentation for different options and customization.

You can always create any self-signed certificate using any other tooling outside the Dockerfile. You need to remember to set them as embedded resource.

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to the Web folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-web:latest . #Builds the image with "latest" tag

​ {{ end }}

{{ end }}

{{ if UI == "BlazorServer" }}

Blazor Server

​ {{ if Tiered == "Yes" }}Blazor Server application is a server-side rendering application that uses Cookie authentication as the default scheme and OpenIdConnect as the default challenge scheme.

In the BlazorModule under authentication configuration, there is an extra configuration for containerized environment support:

if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"]))
{
    context.Services.Configure<OpenIdConnectOptions>("oidc", options =>
    {
        options.TokenValidationParameters.ValidIssuers = new[]
        {
            configuration["AuthServer:MetaAddress"].EnsureEndsWith('/'), 
            configuration["AuthServer:Authority"].EnsureEndsWith('/')
        };

        options.MetadataAddress = configuration["AuthServer:MetaAddress"].EnsureEndsWith('/') +
                                ".well-known/openid-configuration";

        var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider;
        options.Events.OnRedirectToIdentityProvider = async ctx =>
        {
            // Intercept the redirection so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/authorize";

            if (previousOnRedirectToIdentityProvider != null)
            {
                await previousOnRedirectToIdentityProvider(ctx);
            }
        };
        var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut;
        options.Events.OnRedirectToIdentityProviderForSignOut = async ctx =>
        {
            // Intercept the redirection for signout so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/logout";

            if (previousOnRedirectToIdentityProviderForSignOut != null)
            {
                await previousOnRedirectToIdentityProviderForSignOut(ctx);
            }
        };
    });

}

This is used when the AuthServer is running on docker containers(or pods) to configure the redirection URLs for the internal network and the web. The application must be redirected to real DNS (localhost in this case) when the /authorize and /logout requests over the browser but handle the token validation inside the isolated network without going out to the internet. "AuthServer:MetaAddress" appsetting should indicate the container/pod service name while the AuthServer:Authority should be pointing to real DNS for the browser to redirect.

The appsettings.json file does not contain AuthServer:IsOnK8s and AuthServer:MetaAddress settings since they are used for orchestrated deployment scenarios, you can see these settings are overridden by the docker-compose.yml file.

Dockerfile.local is provided under this project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "Acme.BookStore.Blazor.dll"]

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to Blazor folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-blazor:latest . #Builds the image with "latest" tag

​ {{ end }} {{ if Tiered == "No" }}Blazor Server application is a server-side rendering application that contains both the OpenID-provider and the Http.Api endpoints within self; it will be a single application to deploy. Dockerfile.local is provided under this project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
RUN dotnet dev-certs https -v -ep authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED

FROM base AS final
WORKDIR /app
COPY --from=build /src .

ENTRYPOINT ["dotnet", "Acme.BookStore.Blazor.dll"]

You can come across an error when the image is being built. This occurs because of dotnet dev-certs command trying to list the existing certificates inside the container and unavailable to. This error is not important since we aim to generate the authserver.pfx file and discard the container it is built in.

auth-server-pfx-generation-error

Since it contains the OpenID-provider within, it also uses multi-stages to generate authserver.pfx file which is used by OpenIddict as a signing and encryption certificate. This configuration is found under the PreConfigureServices method of the BlazorModule:

if (!hostingEnvironment.IsDevelopment())
{
    PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
    {
        options.AddDevelopmentEncryptionAndSigningCertificate = false;
    });

    PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
    {
        serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
        serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
    });
}

This configuration disables the DevelopmentEncryptionAndSigningCertificate and uses a self-signed certificate called authserver.pfx. for signing and encrypting the tokens. This certificate is created when the docker image is built using the dotnet dev-certs tooling. It is a sample-generated certificate, and it is recommended to update it for the production environment. You can check the OpenIddict Encryption and signing credentials documentation for different options and customization.

You can always create any self-signed certificate using any other tooling outside the Dockerfile. You need to remember to set them as embedded resource.

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to the BlazorModule folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-blazor:blazor . #Builds the image with "latest" tag

​ {{ end }}

{{ end }}

{{ if UI == "NG" }}

Angular

The angular application uses nginx:alpine-slim base image to host the angular application. You can modify the base image based on your preference in the Dockerfile.local, which is provided under the angular folder of your solution as below;

FROM nginx:alpine-slim
WORKDIR /app
COPY dist/BookStore /usr/share/nginx/html
COPY dynamic-env.json /usr/share/nginx/html
COPY /nginx.conf  /etc/nginx/conf.d/default.conf

You can notice that two more files are copied into the application image beside the built Angular application.

The dynamic-env.json file is an empty JSON file representing the angular application's environment variables. The environment variable on image runtime will override this file. If you examine the environment.prod.ts file under the angular/src/environments folder, there is a remote environment configuration for production:

remoteEnv: {
    url: '/getEnvConfig',
    mergeStrategy: 'deepmerge'
  }

This configuration is used to get the environment variables from a remote service. This configuration is used to override environment variables without rebuilding the image. The URL /getEnvConfig is defined in the nginx.conf file:

server {
    listen       80;
    listen  [::]:80;
    server_name  _;
    
    #listen              443 ssl;
    #server_name         www.myapp.com;
    #ssl_certificate     www.myapp.com.crt;
    #ssl_certificate_key www.myapp.com.key;
    
	location / {
        root   /usr/share/nginx/html;        
        index  index.html index.htm;
        try_files $uri $uri/ /index.html =404;		
	}
	
	location /getEnvConfig {
		default_type 'application/json';
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Content-Type' 'application/json';
		try_files $uri /dynamic-env.json;
    }
    
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

This configuration allows returning the dynamic-env.json file as a static file, which ABP Angular application uses for environment variables in one of the first initial requests when rendering the page. The dynamic-env.json file you need to override is located under aspnet-core/etc/docker-compose folder.

​ {{ if Tiered == "No" }}

{
  "production": true,
  "application": {
    "baseUrl":"http://localhost:4200",		// https://myapp.com
    "name": "BookStore",
    "logoUrl": ""
  },
  "oAuthConfig": {
    "issuer": "https://localhost:44354/", 	// https://myapi.com/
    "redirectUri": "http://localhost:4200", // https://myapp.com
    "clientId": "BookStore_App",
    "responseType": "code",
    "scope": "offline_access openid profile email phone BookStore"
  },
  "apis": {
    "default": {
      "url": "https://localhost:44354",		// https://myapi.com
      "rootNamespace": "BookStore"
    },
    "AbpAccountPublic": {
      "url": "https://localhost:44354",		// https://myapi.com
      "rootNamespace": "AbpAccountPublic"
    }
  }
}

​ {{ end }}

​ {{ if Tiered == "Yes" }}

{
  "production": true,
  "application": {
    "baseUrl":"http://localhost:4200",		// https://myapp.com
    "name": "BookStore",
    "logoUrl": ""
  },
  "oAuthConfig": {
    "issuer": "https://localhost:44334/",	// https://myauthserver.com/
    "redirectUri": "http://localhost:4200",	// https://myapp.com
    "clientId": "BookStore_App",
    "responseType": "code",
    "scope": "offline_access openid profile email phone BookStore"
  },
  "apis": {
    "default": {
      "url": "https://localhost:44354",		// https://myapi.com
      "rootNamespace": "BookStore"
    },
    "AbpAccountPublic": {
      "url": "https://localhost:44334",		// https://myauthserver.com
      "rootNamespace": "AbpAccountPublic"
    }
  }
}

​ {{ end }}

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to the angular folder and run:

yarn 				#Restores the project
npm run build:prod	#Builds on production environment. You can also use "ng build  --prod" if you have the angular CLI
docker build -f Dockerfile.local -t acme/bookstore-angular:latest . #Builds the image with "latest" tag

{{ end }}

{{ if UI == "Blazor" }}

Blazor

The Blazor application uses nginx:alpine-slim base image to host the blazor application. You can modify the base image based on your preference in the Dockerfile.local which provided under the Blazor folder of your solution as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS build
COPY bin/Release/net10.0/publish/ app/
  
FROM nginx:alpine-slim AS final
WORKDIR /usr/share/nginx/html
COPY --from=build /app/wwwroot .
COPY /nginx.conf  /etc/nginx/conf.d/default.conf

Other than the built Blazor application, there is also nginx.conf file is copied into the application image. The nginx.conf file:

server {
    listen       80;
    listen  [::]:80;
    server_name  _;
    
    #listen              443 ssl;
    #server_name         www.myapp.com;
    #ssl_certificate     www.myapp.com.crt;
    #ssl_certificate_key www.myapp.com.key;
    
	location / {
        root   /usr/share/nginx/html;        
        index  index.html index.htm;
        try_files $uri $uri/ /index.html =404;		
	}
    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html    
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to Blazor folder and run:

##Builds the projects in Release mode with the Trimming option disabled. You can enable or configure it as you like
dotnet publish -c Release -p:PublishTrimmed=false 
docker build -f Dockerfile.local -t acme/bookstore-blazor:latest . #Builds the image with "latest" tag

{{ end }}

{{ if Tiered == "No" }}

​ {{ if UI == "NG" }}

Http.Api.Host

This is the backend application that contains the openid-provider functionality as well. The dockerfile.local is located under the Http.Api.Host project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
RUN dotnet dev-certs https -v -ep authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED

FROM base AS final
WORKDIR /app
COPY --from=build /src .

ENTRYPOINT ["dotnet", "Acme.BookStore.HttpApi.Host.dll"]

You can come across an error when the image is being built. This occurs because of dotnet dev-certs command trying to list the existing certificates inside the container and unavailable to. This error is not important since we aim to generate the authserver.pfx file and discard the container it is built in.

auth-server-pfx-generation-error

Since it contains the OpenID-provider within, it also uses multi-stages to generate authserver.pfx file, which is used by OpenIddict as a signing and encryption certificate. This configuration is found under the PreConfigureServices method of the HttpApiHostModule:

if (!hostingEnvironment.IsDevelopment())
{
    PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
    {
        options.AddDevelopmentEncryptionAndSigningCertificate = false;
    });

    PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
    {
        serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
        serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
    });
}

This configuration disables the DevelopmentEncryptionAndSigningCertificate and uses a self-signed certificate called authserver.pfx. for signing and encrypting the tokens. This certificate is created when the docker image is built using the dotnet dev-certs tooling. It is a sample-generated certificate, and it is recommended to update it for the production environment. You can check the OpenIddict Encryption and signing credentials documentation for different options and customization.

You can always create any self-signed certificate using any other tooling outside the Dockerfile. You need to remember to set them as embedded resource.

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to Http.Api.Host folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-api:latest . #Builds the image with "latest" tag

​ {{ end }}

​ {{ if UI == "Blazor" }}

Http.Api.Host

This is the backend application that contains the OpenID-provider functionality as well. The dockerfile.local is located under the Http.Api.Host project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
RUN dotnet dev-certs https -v -ep authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED

FROM base AS final
WORKDIR /app
COPY --from=build /src .

ENTRYPOINT ["dotnet", "Acme.BookStore.HttpApi.Host.dll"]

You can come across an error when the image is being built. This occurs because of dotnet dev-certs command trying to list the existing certificates inside the container and unavailable to. This error is not important since we aim to generate the authserver.pfx file and discard the container it is built in.

auth-server-pfx-generation-error

Since it contains the openid-provider within, it also uses multi-stages to generate authserver.pfx file which is used by OpenIddict as a signing and encryption certificate. This configuration is found under the PreConfigureServices method of the HttpApiHostModule:

if (!hostingEnvironment.IsDevelopment())
{
    PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
    {
        options.AddDevelopmentEncryptionAndSigningCertificate = false;
    });

    PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
    {
        serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
        serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
    });
}

This configuration disables the DevelopmentEncryptionAndSigningCertificate and uses a self-signed certificate called authserver.pfx. for signing and encrypting the tokens. This certificate is created when the docker image is built using the dotnet dev-certs tooling. It is a sample-generated certificate, and it is recommended to update it for the production environment. You can check the OpenIddict Encryption and signing credentials documentation for different options and customization.

You can always create any self-signed certificate using any other tooling outside the Dockerfile. You need to remember to set them as embedded resource.

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to Http.Api.Host folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-api:latest . #Builds the image with "latest" tag

​ {{ end }}

{{ end }}

{{ if Tiered == "Yes" }}

AuthServer

This is the openid-provider application, the authentication server, which should be individually hosted compared to non-tiered application templates. The dockerfile.local is located under the AuthServer project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
RUN dotnet dev-certs https -v -ep authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED

FROM base AS final
WORKDIR /app
COPY --from=build /src .

ENTRYPOINT ["dotnet", "Acme.BookStore.AuthServer.dll"]

You can come across an error when the image is being built. This occurs because of dotnet dev-certs command trying to list the existing certificates inside the container and unavailable to. This is not an important error since we aim to generate the authserver.pfx file and discard the container it is built in.

auth-server-pfx-generation-error

The AuthServer docker image building process contains multi-stages to generate authserver.pfx file, which is used by OpenIddict as a signing and encryption certificate. This configuration is found under the PreConfigureServices method of the AuthServerModule:

if (!hostingEnvironment.IsDevelopment())
{
    PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
    {
        options.AddDevelopmentEncryptionAndSigningCertificate = false;
    });

    PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
    {
        serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
        serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
    });
}

This configuration disables the DevelopmentEncryptionAndSigningCertificate and uses a self-signed certificate called authserver.pfx. for signing and encrypting the tokens. This certificate is created when the docker image is built using the dotnet dev-certs tooling. It is a sample-generated certificate, and it is recommended to update it for the production environment. You can check the OpenIddict Encryption and signing credentials documentation for different options and customization.

You can always create any self-signed certificate using any other tooling outside the Dockerfile. You need to remember to set them as embedded resource.

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to the AuthServer folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-authserver:latest . #Builds the image with "latest" tag

Http.Api.Host

This is the backend application that exposes the endpoints and swagger UI. It is not a multi-stage dockerfile; hence you need to have already built this application in Release mode to use this dockerfile. The dockerfile.local is located under the Http.Api.Host project as below;

FROM mcr.microsoft.com/dotnet/aspnet:10.0
COPY bin/Release/net10.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "Acme.BookStore.HttpApi.Host.dll"]

If you don't want to use the build-images-locally.ps1 to build the images or to build this image individually and manually, navigate to Http.Api.Host folder and run:

dotnet publish -c Release #Builds the projects in Release mode
docker build -f Dockerfile.local -t acme/bookstore-api:latest . #Builds the image with "latest" tag

{{ end }}

Running Docker-Compose on Localhost

Under the etc/docker-compose folder, you can find the docker-compose.yml to run your application. To ease the running process, the template provides run-docker.ps1 (and run-docker.sh) scripts that handle the HTTPS certificate creation, which is used in environment variables;

$currentFolder = $PSScriptRoot

$slnFolder = Join-Path $currentFolder "../"
$certsFolder = Join-Path $currentFolder "certs"

If(!(Test-Path -Path $certsFolder))
{
    New-Item -ItemType Directory -Force -Path $certsFolder
    if(!(Test-Path -Path (Join-Path $certsFolder "localhost.pfx") -PathType Leaf)){
        Set-Location $certsFolder
        dotnet dev-certs https -v -ep localhost.pfx -p 91f91912-5ab0-49df-8166-23377efaf3cc -t        
    }
}

Set-Location $currentFolder
docker-compose up -d

run-docker.ps1 (or run-docker.sh) script will check if there is an existing dev-cert already under the etc/certs folder and generate a localhost.pfx file if it doesn't exist. Kestrel will use this file as an HTTPS certificate.

You can also manually create the localhost.pfx file in a different path with different name and a different password by using dotnet dev-certs https -v -ep myCert.pfx -p YOUR_PASSWORD_FOR_HTTPS_CERT -t or with using any other self-signed certificate generation tool.

You need to update the service environment variables Kestrel__Certificates__Default__Path with the path and filename you have created and the Kestrel__Certificates__Default__Password with your new password in the docker-compose.yml file.

Now lets break down each docker compose service under the docker-compose.yml file:

{{ if UI == "Blazor" }}

bookstore-blazor

services:
  bookstore-blazor:
    image: acme/bookstore-blazor:latest
    container_name: bookstore-blazor
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.Blazor/Dockerfile.local
    ports:
      - "44307:80"
    depends_on:
      - bookstore-api
    restart: on-failure
    volumes:
      - ./appsettings.json:/usr/share/nginx/html/appsettings.json
    networks:
      - abp-network

This is the Blazor application we deploy on http://localhost:44307 by default using the acme/bookstore-blazor:latest image that we have built using the build-images-locally.ps1 script. It is not running on HTTPS using the localhost.pfx since it is running on Nginx and it doesn't accept pfx files for SSL. You can check Nginx Configuring HTTPS Servers documentation for more information and apply the necessary configurations to nginx.conf file under the Blazor folder.

Don't forget to rebuild the acme/bookstore-blazor:latest image after updating the nginx.conf file.

On volumes, it mounts the appsettings.json file under the docker folder to achieve changing the environment variables without re-building the image. The overriding docker/appsettings.json file is as below:

{
  "App": {
    "SelfUrl": "http://localhost:44307"
  },
  "AuthServer": {	{{ if Tiered == "Yes" }}
    "Authority": "https://localhost:44334",	{{ end }}	{{ if Tiered == "No" }}
    "Authority": "https://localhost:44354",	{{ end }}
    "ClientId": "BookStore_Blazor",
    "ResponseType": "code"
  },
  "RemoteServices": {
    "Default": {
      "BaseUrl": "https://localhost:44354"
    },
    "AbpAccountPublic": {	{{ if Tiered == "Yes" }}
      "BaseUrl": "https://localhost:44334"	{{ end }}	{{ if Tiered == "No" }}
      "BaseUrl": "https://localhost:44354"	{{ end }}
    }
  },
  "AbpCli": {
    "Bundle": {
      "Mode": "BundleAndMinify", 
      "Name": "global",
      "Parameters": {
              "LeptonXTheme.Layout": "side-menu"
      }
    }
  }
}

This service runs in Docker network called abp-network, awaits for the the bookstore-api to start up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

bookstore-api

bookstore-api:
    image: acme/bookstore-api:latest
    container_name: bookstore-api
    hostname: bookstore-api
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.HttpApi.Host/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44354
	  - App__CorsOrigins=http://localhost:44307
      - App__HealthCheckUrl=http://bookstore-api/health-status  {{ if Tiered == "Yes" }}
	  - AuthServer__Authority=http://bookstore-authserver  {{ end }}  {{ if Tiered == "No" }}
	  - AuthServer__Authority=http://bookstore-api  {{ end }}
      - AuthServer__RequireHttpsMetadata=false  {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;  {{ end }}  {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore   {{ end }}  {{ if Tiered == "Yes" }}
      - Redis__Configuration=redis  {{ end }}
    ports:
      - "44354:443"
    depends_on: {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy {{ end }}       {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy {{ end }} {{ if Tiered == "Yes" }}
      redis:
        condition: service_healthy
    restart: on-failure {{ end }}    
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This service is the backend application of the Blazor application that uses the acme/bookstore-api:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44354 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44354. It must point to a real DNS when deploying to production.

  • App__CorsOrigins is the override configuration for CORS. We add the angular application URL here http://localhost:44307. It must point to a real DNS when deploying to production.

  • App__HealthCheckUrl is the override configuration for the health check URL. Since this request will be done internally, it points to the service name in containerized environment http://bookstore-api/health-status

  • AuthServer__Authority is the issuer URL. {{ if Tiered == "Yes" }} http://bookstore-authserver {{ end }}{{ if Tiered == "No" }} http://bookstore-api {{ end }} is the containerized issuer. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. {{ if Tiered == "Yes" }}Docker-compose is using an isolated internal docker network called abp-network. We want to use HTTP in the internal network communication without SSL overhead. Therefore, it is set to false by default. {{ end }}{{ if Tiered == "No" }} Since the backend itself is the OpenID-provider, we set it true by default.{{ end }}

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.{{ if Tiered == "Yes" }}

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

    {{ end }}

This service runs in a Docker network called abp-network, awaits for {{ if Tiered == "Yes" }}the redis service and {{ end }}the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ if Tiered == "Yes" }}

bookstore-authserver

bookstore-authserver:
    image: acme/bookstore-authserver:latest
    container_name: bookstore-authserver
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.AuthServer/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;      
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44334
      - App__CorsOrigins=http://localhost:44307
      - AuthServer__Authority=http://bookstore-authserver
      - AuthServer__RequireHttpsMetadata=false      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44334:443"
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}   
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This is the authentication server application that handles the authentication between applications using the OpenIddict library. It uses the acme/bookstore-authserver:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44334 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44334. It must point to a real DNS when deploying to production.

  • App__CorsOrigins is the override configuration for CORS. We add the angular and the Blazor application URLs here by default. It must point to a real DNS when deploying to production.

  • AuthServer__Authority is the issuer URL. http://bookstore-authserver is the endpoint for the authserver by default. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Docker-compose uses using isolated internal docker network called abp-network. We want to use HTTP in the internal network communication without SSL overhead. Therefore, it is set to false by default.

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in Docker network called abp-network, awaits for the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ end }}

db-migrator

db-migrator:
    image: acme/bookstore-db-migrator:latest
    container_name: db-migrator
    build:
      context: ../../
      dockerfile: src/BookStore.DbMigrator/Dockerfile.local
    environment:
      - OpenIddict__Applications__BookStore_Blazor__RootUrl=http://localhost:44307      {{ if Tiered == "Yes" }}
      - OpenIddict__Applications__BookStore_Swagger__RootUrl=https://localhost:44354      {{ end }}      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}    
    networks:
      - abp-network

The database migrator service migrates the database and seeds the initial data. OpenIddict data is one of your application's most important seeded data. On production environment, you need to override the root URL of your application (http://localhost:44307) {{ if Tiered == "Yes" }} and the swagger-ui client URL (https://localhost:44354){{ end }} so that the authentication can work properly.

{{ end }}

{{ if UI == "NG" }}

bookstore-angular

services:
  bookstore-angular:
    image: acme/bookstore-angular:latest
    container_name: bookstore-angular
    build:
      context: ../../../
      dockerfile: angular/Dockerfile.local
    ports:
      - "4200:80"
    depends_on:
      - bookstore-api
    volumes:
      - ./dynamic-env.json://usr/share/nginx/html/dynamic-env.json
    networks:
      - abp-network

This is the angular application we deploy on http://localhost:4200 by default using the image that we have built using the build-images-locally.ps1 script. It is not running on HTTPS using the localhost.pfx since it is running on Nginx and it doesn't accept pfx files for SSL. You can check Nginx Configuring HTTPS Servers documentation for more information and apply the necessary configurations to nginx.conf file under the angular folder.

Don't forget to rebuild the acme/bookstore-angular:latest image after updating the nginx.conf file.

The bookstore-angular service mounts the etc/docker-compose/dynamic-env.json file to change the existing dynamic-env.json file, which is copied during image creation, to change the environment variables on deployment time instead of re-creating the docker image after each environmental variable change. Do not forget to override the dynamic-env.json located under the aspnet-core/etc/docker-compose folder.

If you are not using Docker with WSL, you may have problems with the volume mount permissions. You need to grant docker to be able to use the local file system. See this SO answer for more information.

​ {{ if Tiered == "No" }}

{
  "production": true,
  "application": {
    "baseUrl":"http://localhost:4200",		// https://myapp.com
    "name": "BookStore",
    "logoUrl": ""
  },
  "oAuthConfig": {
    "issuer": "https://localhost:44354/", 	// https://myapi.com/
    "redirectUri": "http://localhost:4200", // https://myapp.com
    "clientId": "BookStore_App",
    "responseType": "code",
    "scope": "offline_access openid profile email phone BookStore"
  },
  "apis": {
    "default": {
      "url": "https://localhost:44354",		// https://myapi.com
      "rootNamespace": "BookStore"
    },
    "AbpAccountPublic": {
      "url": "https://localhost:44354",		// https://myapi.com
      "rootNamespace": "AbpAccountPublic"
    }
  }
}

​ {{ end }}

​ {{ if Tiered == "Yes" }}

{
  "production": true,
  "application": {
    "baseUrl":"http://localhost:4200",		// https://myapp.com
    "name": "BookStore",
    "logoUrl": ""
  },
  "oAuthConfig": {
    "issuer": "https://localhost:44334/",	// https://myauthserver.com/
    "redirectUri": "http://localhost:4200",	// https://myapp.com
    "clientId": "BookStore_App",
    "responseType": "code",
    "scope": "offline_access openid profile email phone BookStore"
  },
  "apis": {
    "default": {
      "url": "https://localhost:44354",		// https://myapi.com
      "rootNamespace": "BookStore"
    },
    "AbpAccountPublic": {
      "url": "https://localhost:44334",		// https://myauthserver.com
      "rootNamespace": "AbpAccountPublic"
    }
  }
}

​ {{ end }}

bookstore-api

bookstore-api:
    image: acme/bookstore-api:latest
    container_name: bookstore-api
    hostname: bookstore-api
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.HttpApi.Host/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44354
	  - App__AngularUrl=http://localhost:4200
	  - App__CorsOrigins=http://localhost:4200
      - App__HealthCheckUrl=http://bookstore-api/health-status  {{ if Tiered == "Yes" }}
	  - AuthServer__Authority=http://bookstore-authserver
      - AuthServer__RequireHttpsMetadata=false  {{ end }}  {{ if Tiered == "No" }}
	  - App__RedirectAllowedUrls=http://localhost:4200
	  - AuthServer__Authority=https://localhost:44354
      - AuthServer__RequireHttpsMetadata=true  {{ end }}  {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;  {{ end }}  {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore   {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44354:443"
    depends_on: {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy {{ end }}       {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy {{ end }}
      redis:
        condition: service_healthy
    restart: on-failure    
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This service is the backend application of the angular application that uses the acme/bookstore-api:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44354 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44354. It must point to a real DNS when deploying to production.

  • App__AngularUrl is the override configuration of URLs for account-related endpoints. It is http://localhost:4200 by default. It must point to a real DNS when deploying to production.

    {{ if Tiered == "No" }}

  • App__RedirectAllowedUrls is the override configuration of redirect URLs for the angular application. It is http://localhost:4200 by default. It must point to a real DNS when deploying to production.

    {{ end }}

  • App__CorsOrigins is the override configuration for CORS. It is http://localhost:4200 by default. It must point to a real DNS when deploying to production.

  • App__HealthCheckUrl is the override configuration for the health check URL. Since this request will be done internally, it points to the service name in the containerized environment http://bookstore-api/health-status.

  • AuthServer__Authority is the issuer URL. {{ if Tiered == "Yes" }} http://bookstore-authserver {{ end }}{{ if Tiered == "No" }} http://bookstore-api {{ end }} is the containerized issuer. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. {{ if Tiered == "Yes" }}Docker-compose is using an isolated internal docker network called abp-network. We want to use HTTP in the internal network communication without SSL overhead; therefore it is set to false by default. {{ end }}{{ if Tiered == "No" }} Since the backend itself is the openid-provider, we set it true by default.{{ end }}

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in a docker network called abp-network, and awaits the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ if Tiered == "Yes" }}

bookstore-authserver

bookstore-authserver:
    image: acme/bookstore-authserver:latest
    container_name: bookstore-authserver
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.AuthServer/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;      
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44334
      - App__CorsOrigins=http://localhost:4200
      - App__RedirectAllowedUrls=http://localhost:4200
      - AuthServer__Authority=https://localhost:44334/
      - AuthServer__RequireHttpsMetadata=false      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44334:443"
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy
    {{ end }}   
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This is the authentication server application that handles the authentication between applications using the OpenIddict library. It uses the acme/bookstore-authserver:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44334 by default, by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44334. It must point to a real DNS when deploying to production.
  • App__CorsOrigins is the override configuration for CORS. It is http://localhost:4200 by default. It must point to a real DNS when deploying to production.
  • App__RedirectAllowedUrls is the override configuration of redirect URLs for the angular application. It is http://localhost:4200 by default. It must point to a real DNS when deploying to production.
  • AuthServer__Authority is the issuer URL. https://localhost:44334/ is the endpoint for the authserver by default. It must point to a real DNS when deploying to production.
  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Docker-compose uses using isolated internal docker network called abp-network. It is set to false by default.
  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.
  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in Docker network called abp-network, awaits for the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ end }}

db-migrator

db-migrator:
    image: acme/bookstore-db-migrator:latest
    container_name: db-migrator
    build:
      context: ../../
      dockerfile: src/BookStore.DbMigrator/Dockerfile.local
    environment:
      - OpenIddict__Applications__BookStore_App__RootUrl=http://localhost:4200      {{ if Tiered == "Yes" }}
      - OpenIddict__Applications__BookStore_Swagger__RootUrl=https://localhost:44354      {{ end }}      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}    
    networks:
      - abp-network

This is the database migrator service that migrates the database and seeds the initial data. OpenIddict data is one of the most important seeded data for your application to run. On production environment, you need to override the root URL of your application (http://localhost:4200) and the swagger-ui client URL (https://localhost:44354) so that the authentication can work properly.

This service runs in Docker network called abp-network, awaits for the database container to start up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ end }}

{{ if UI == "MVC" }}

bookstore-web

bookstore-web:
    image: acme/bookstore-web:latest
    container_name: bookstore-web
    hostname: bookstore-web
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.Web/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44353
      - AuthServer__RequireHttpsMetadata=false        {{ if Tiered == "Yes" }}
  	  - AuthServer__IsOnK8s=true
	  - AuthServer__Authority=https://localhost:44334/
      - RemoteServices__Default__BaseUrl=http://bookstore-api
      - RemoteServices__AbpAccountPublic__BaseUrl=http://bookstore-authserver
      - AuthServer__MetaAddress=http://bookstore-authserver  {{ end }}  {{ if Tiered == "No" }}
	  - AuthServer__Authority=http://bookstore-web  {{ end }}
      - App__HealthCheckUrl=http://bookstore-web/health-status      	{{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;	{{ end }}	{{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore 	{{ end }}	{{ if Tiered == "Yes" }}
      - Redis__Configuration=redis  	{{ end }}
    ports:
      - "44353:443"
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This is the MVC/Razor Page application docker service is using the acme/bookstore-web:latest image that we have built using the build-images-locally.ps1 script. It runs on https://localhost:44353 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

​ {{ if Tiered == "Yes" }}

The MVC/Razor Page is a server-side rendering application that uses the hybrid flow. This flow uses browser to login/logout process to the OpenID-provider but issues the access_token from the back-channel (server-side). To achieve this functionality, the module class has extra OpenIdConnectOptions to override some of the events:

if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"]))
{
    context.Services.Configure<OpenIdConnectOptions>("oidc", options =>
    {
        options.TokenValidationParameters.ValidIssuers = new[]
        {
            configuration["AuthServer:MetaAddress"].EnsureEndsWith('/'), 
            configuration["AuthServer:Authority"].EnsureEndsWith('/')
        };

        options.MetadataAddress = configuration["AuthServer:MetaAddress"].EnsureEndsWith('/') +
                                ".well-known/openid-configuration";

        var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider;
        options.Events.OnRedirectToIdentityProvider = async ctx =>
        {
            // Intercept the redirection so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/authorize";

            if (previousOnRedirectToIdentityProvider != null)
            {
                await previousOnRedirectToIdentityProvider(ctx);
            }
        };
        var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut;
        options.Events.OnRedirectToIdentityProviderForSignOut = async ctx =>
        {
            // Intercept the redirection for signout so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/logout";

            if (previousOnRedirectToIdentityProviderForSignOut != null)
            {
                await previousOnRedirectToIdentityProviderForSignOut(ctx);
            }
        };
    });
}

​ {{ end }}

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44353. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Since we are using an isolated internal docker network. We want to use HTTP in the internal network communication without SSL overhead; therefore it is set to false by default.

    {{ if Tiered == "Yes" }}

  • AuthServer__IsOnK8s is the configuration to enable the OpenIdConnectOptions to provide a different endpoint for the MetaAddress of the OpenID-provider and intercepting the URLS for authorization and logout endpoints.

  • AuthServer__MetaAddress is the .well-known/openid-configuration endpoint for issuing access_token and internal token validation. It is the containerized http://bookstore-authserver by default.

  • AuthServer__Authority is the issuer URL. https://localhost:44334/ is the issuer that the application redirects to on authorization and logout process. It must point to a real DNS when deploying to production.

  • RemoteServices__Default__BaseUrl is the backend; API endpoint application uses the access_token to get the resources. It is the containerized http://bookstore-api by default.

  • RemoteServices__AbpAccountPublic__BaseUrl is the account URL used to get the profile picture of the user. Since account-related information is located in the authserver, it is the containerized http://bookstore-authserver by default.

    {{ end }}

    {{ if Tiered == "No" }}

  • App__HealthCheckUrl is the health check url. Since this request will be done internally, it points to the service name in the containerized environment http://bookstore-api/health-status.

  • AuthServer__Authority is the issuer URL. http://bookstore-web is the containerized issuer. It must point to a real DNS when deploying to production.

    {{ end }}

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.

    {{ if Tiered == "Yes" }}

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

    {{ end }}

This service runs in Docker network called abp-network, awaits for {{ if Tiered == "Yes" }}the redis service and{{ end }} the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

​ {{ if Tiered == "Yes" }}

bookstore-api

bookstore-api:
    image: acme/bookstore-api:latest
    container_name: bookstore-api
    hostname: bookstore-api
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.HttpApi.Host/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44354
      - App__HealthCheckUrl=http://bookstore-api/health-status
	  - AuthServer__Authority=http://bookstore-authserver
      - AuthServer__RequireHttpsMetadata=false  {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;  {{ end }}  {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore   {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44354:443"
    depends_on: {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy {{ end }}       {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy {{ end }}
      redis:
        condition: service_healthy
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This service is the backend application of the MVC/Razor Page application that uses the acme/bookstore-api:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44354 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44354. It must point to a real DNS when deploying to production.

  • App__HealthCheckUrl is the health check url. Since this request will be done internally, it points to the service name in containerized environment http://bookstore-api/health-status

  • AuthServer__Authority is the issuer URL. http://bookstore-authserver is the containerized issuer. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Since we are using an isolated internal docker network. We want to use HTTP in the internal network communication without SSL overhead, therefore, it is set to false by default.

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in Docker network called abp-network, awaits the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

bookstore-authserver

bookstore-authserver:
    image: acme/bookstore-authserver:latest
    container_name: bookstore-authserver
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.AuthServer/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;      
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44334
      - App__CorsOrigins=https://localhost:44353,https://localhost:44354
      - AuthServer__Authority=http://bookstore-authserver
      - AuthServer__RequireHttpsMetadata=false      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44334:443"
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}
      redis:
        condition: service_healthy
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This is the authentication server application that handles the authentication between applications using the OpenIddict library. It uses the acme/bookstore-authserver:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44334 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44334. It must point to a real DNS when deploying to production.
  • App__CorsOrigins is the override configuration for CORS. It is https://localhost:44353,https://localhost:44354 by default. It must point to a real DNS when deploying to production.
  • AuthServer__Authority is the issuer URL. http://bookstore-authserver is the endpoint for the authserver by default.
  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Docker-compose uses using isolated internal docker network called abp-network. It is set to false by default.
  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.
  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in Docker network called abp-network, awaits the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

​ {{ end }}

db-migrator

db-migrator:
    image: acme/bookstore-db-migrator:latest
    container_name: db-migrator
    build:
      context: ../../
      dockerfile: src/BookStore.DbMigrator/Dockerfile.local
    environment:
      - OpenIddict__Applications__BookStore_Web__RootUrl=https://localhost:44353      {{ if Tiered == "Yes" }}
      - OpenIddict__Applications__BookStore_Swagger__RootUrl=https://localhost:44354      {{ end }}      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}    
    networks:
      - abp-network

This is the database migrator service that migrates the database and seeds the initial data. OpenIddict data is one of the most important seeded data for your application to run. On production environment, you need to override the root URL of your application (https://localhost:44353) and the swagger-ui client URL (https://localhost:44354) so that the authentication can work properly.

This service runs in Docker network called abp-network, awaits for the database container to start up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ end }}

{{ if UI == "BlazorServer" }}

bookstore-blazor

bookstore-blazor:
    image: acme/bookstore-blazor:latest
    container_name: bookstore-blazor
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.Blazor/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44314
      - AuthServer__RequireHttpsMetadata=false  {{ if Tiered == "Yes" }}
  	  - AuthServer__IsOnK8s=true
	  - AuthServer__Authority=https://localhost:44334/
      - AuthServer__MetaAddress=http://bookstore-authserver
      - RemoteServices__Default__BaseUrl=http://bookstore-api
      - RemoteServices__AbpAccountPublic__BaseUrl=http://bookstore-authserver  {{ end }}  {{ if Tiered == "No" }}
	  - AuthServer__Authority=http://bookstore-blazor  {{ end }}  	{{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;	{{ end }}	{{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore 	{{ end }}	{{ if Tiered == "Yes" }}
      - Redis__Configuration=redis  	{{ end }}
    ports:
      - "44353:443"    {{ if Tiered == "Yes" }}
    depends_on:
      - bookstore-api  	{{ end }}
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This is the Blazor Server application Docker service is using the acme/bookstore-blazor:latest image that we have built using the build-images-locally.ps1 script. It runs on https://localhost:44314 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

{{ if Tiered == "Yes" }}

The Blazor Server is a server-side rendering application that uses the hybrid flow. This flow uses browser to login/logout process to the OpenID-provider but issues the access_token from the back-channel (server-side). To achieve this functionality, the module class has extra OpenIdConnectOptions to override some of the events:

if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"]))
{
    context.Services.Configure<OpenIdConnectOptions>("oidc", options =>
    {
        options.TokenValidationParameters.ValidIssuers = new[]
        {
            configuration["AuthServer:MetaAddress"].EnsureEndsWith('/'), 
            configuration["AuthServer:Authority"].EnsureEndsWith('/')
        };

        options.MetadataAddress = configuration["AuthServer:MetaAddress"].EnsureEndsWith('/') +
                                ".well-known/openid-configuration";

        var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider;
        options.Events.OnRedirectToIdentityProvider = async ctx =>
        {
            // Intercept the redirection so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/authorize";

            if (previousOnRedirectToIdentityProvider != null)
            {
                await previousOnRedirectToIdentityProvider(ctx);
            }
        };
        var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut;
        options.Events.OnRedirectToIdentityProviderForSignOut = async ctx =>
        {
            // Intercept the redirection for signout so the browser navigates to the right URL in your host
            ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/logout";

            if (previousOnRedirectToIdentityProviderForSignOut != null)
            {
                await previousOnRedirectToIdentityProviderForSignOut(ctx);
            }
        };
    });
}

{{ end }}

  • App__SelfUrl points to the localhost with the port we expose, https://localhost:44314. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Since we are using an isolated internal docker network. We want to use HTTP in the internal network communication without SSL overhead, therefore, it is set to false by default.

    {{ if Tiered == "Yes" }}

  • AuthServer__IsOnK8s is the configuration to enable the OpenIdConnectOptions to provide a different endpoint for the MetaAddress of the OpenID-provider and intercept the URLS for authorization and logout endpoints.

  • AuthServer__MetaAddress is the .well-known/openid-configuration endpoint for issuing the access_token and internal token validation. It is the containerized http://bookstore-authserver by default.

  • AuthServer__Authority is the issuer URL. https://localhost:44334/ is the issuer that the application redirects to on authorization and logout process. It must point to a real DNS when deploying to production.

  • RemoteServices__Default__BaseUrl is the backend; API endpoint application uses the access_token to get the resources. It is the containerized http://bookstore-api by default.

  • RemoteServices__AbpAccountPublic__BaseUrl is the account URL used to get the profile picture of the user. Since account-related information is located in the authserver, it is the containerized http://bookstore-authserver by default.

    {{ end }}

    {{ if Tiered == "No" }}

  • AuthServer__Authority is the issuer URL. http://bookstore-blazor is the containerized issuer. It must point to a real DNS when deploying to production.

    {{ end }}

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.

    {{ if Tiered == "Yes" }}

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

    {{ end }}

This service runs in docker network called abp-network. {{ if Tiered == "Yes" }}It awaits the Redis service and the bookstore-api containers for starting up.{{ end }} It also restarts when it fails. You can customize these orchestration behaviors as you prefer.

​ {{ if Tiered == "Yes" }}

bookstore-api

bookstore-api:
    image: acme/bookstore-api:latest
    container_name: bookstore-api
    hostname: bookstore-api
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.HttpApi.Host/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44354
      - App__HealthCheckUrl=http://bookstore-api/health-status
	  - AuthServer__Authority=http://bookstore-authserver
      - AuthServer__RequireHttpsMetadata=false  {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;  {{ end }}  {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore   {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44354:443"
    depends_on: {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy {{ end }}       {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy {{ end }}
      redis:
        condition: service_healthy
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This service is the backend application of the MVC/Razor Page application that uses the acme/bookstore-api:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44354 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44354. It must point to a real DNS when deploying to production.

  • App__HealthCheckUrl is the health check url. Since this request will be done internally, it points to the service name in containerized environment http://bookstore-api/health-status

  • AuthServer__Authority is the issuer URL. http://bookstore-authserver is the containerized issuer. It must point to a real DNS when deploying to production.

  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Since we are using an isolated internal docker network. We want to use HTTP in the internal network communication without SSL overhead, therefore, it is set to false by default.

  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.

  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in Docker network called abp-network, awaits the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

bookstore-authserver

bookstore-authserver:
    image: acme/bookstore-authserver:latest
    container_name: bookstore-authserver
    build:
      context: ../../
      dockerfile: src/Acme.BookStore.AuthServer/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;      
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44334
      - AuthServer__Authority=http://bookstore-authserver
      - AuthServer__RequireHttpsMetadata=false      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
      - Redis__Configuration=redis
    ports:
      - "44334:443"
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}
      redis:
        condition: service_healthy
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network

This is the authentication server application that handles the authentication between applications using the OpenIddict library. It is using the acme/bookstore-authserver:latest image we have built using the build-images-locally.ps1 script. It runs on https://localhost:44334 by default by mounting the self-signed certificate we've generated under the etc/certs folder.

  • App__SelfUrl points to the localhost with the port we expose https://localhost:44334. It must point to a real DNS when deploying to production.
  • AuthServer__Authority is the issuer URL. http://bookstore-authserver is the endpoint for the authserver by default.
  • AuthServer__RequireHttpsMetadata is the option for the openid-provider to enforce HTTPS. Docker-compose uses using isolated internal docker network called abp-network. It is set to false by default.
  • ConnectionStrings__Default is the overridden default connection string. It uses {{ if DB == "Mongo" }}the containerized mongodb service {{ end }}{{ if DB == "EF" }}the containerized sql-server with the sa user {{ end }} by default.
  • Redis__Configuration is the overridden Redis configuration. It uses the containerized redis service. If you are not using containerized Redis, update your Redis URL.

This service runs in Docker network called abp-network, awaits the Redis service and the database container for starting up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

​ {{ end }}

db-migrator

db-migrator:
    image: acme/bookstore-db-migrator:latest
    container_name: db-migrator
    build:
      context: ../../
      dockerfile: src/BookStore.DbMigrator/Dockerfile.local
    environment:
      - OpenIddict__Applications__BookStore_BlazorServerTiered__RootUrl=https://localhost:44314      {{ if Tiered == "Yes" }}
      - OpenIddict__Applications__BookStore_Swagger__RootUrl=https://localhost:44354      {{ end }}      {{ if DB == "EF" }}
      - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=BookStore;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True;      {{ end }}      {{ if DB == "Mongo" }}
      - ConnectionStrings__Default=mongodb://mongodb/BookStore       {{ end }}
    depends_on:     {{ if DB == "EF" }}
      sql-server:
        condition: service_healthy    {{ end }}          {{ if DB == "Mongo" }}
   	  mongo-db:
        condition: service_healthy    {{ end }}    
    networks:
      - abp-network

The database migrator service migrates the database and seeds the initial data. OpenIddict data is one of the most important seeded data for your application. On production environment, you need to override the root URL of your application (https://localhost:44353) and the swagger-ui client URL (https://localhost:44354) so that the authentication can work properly.

This service runs in Docker network called abp-network, awaits for the database container to start up and restarts when it fails. You can customize these orchestration behaviors as you prefer.

{{ end }}

What's next?