skoruba / IdentityServer4.Admin

The administration for the IdentityServer4 and Asp.Net Core Identity
MIT License
3.57k stars 1.15k forks source link

Accessing Admin UI running on docker #402

Open sathoril opened 5 years ago

sathoril commented 5 years ago

Hello guys.

I've been trying to make this application to run inside multiple docker containers. I have already managed to do it but only with the Admin.Api project and the STS.Identity project, but I'm having problems with the Admin.UI project.

Everytime I try to access the url (http://localhost:9000) it shows this error:

OException: IDX20804: Unable to retrieve document from: 'identity-server-sts:5000/.well-known/openid-configuration'. Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel) InvalidOperationException:` IDX20803: Unable to obtain configuration from: 'identity-server-sts:5000/.well-known/openid-configuration'. Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel)

I read that is possibly something related to the way I configure my network containers, but I tried everything I found on the internet and nothing worked.

I tried to instead using http://localhost:5000, I changed the url to connect to the following:

I dont know what should I do, do guys have any idea what this error is about.

Here is my Dockerfiles of each project and my docker-compose file:

Dockerfile - Admin.UI Project

Dockerfile.txt

Dockerfile - Admin.API Project

Dockerfile.txt

Dockerfile - STS.Identity Project

Dockerfile.txt

docker-compose file

docker-compose.txt

skoruba commented 5 years ago

Could you please check dev branch - https://github.com/skoruba/IdentityServer4.Admin/tree/dev?files=1 - there is prepared working version with docker. Give me please feedback :-) Thanks

sathoril commented 5 years ago

Hey!

Thanks for the reply, I've already tried to run the application using that branch, mas I got the same error, here is a screenshot:

image

Is it that branch really working?

skoruba commented 5 years ago

@bravecobra - any idea with this issue?

sathoril commented 5 years ago

Just to update the issue, now I'm having this error page:

image

But, when I try to make the same request, from inside the container, it works.

image

skoruba commented 5 years ago

I will test it at the weekend. 😊

skoruba commented 4 years ago

STS works correctly, but I can not run MSSQL Server, so I need explore more details around docker in general. I have prepared a few changes regarding to db providers, wich will be possible to change the provider from appsettings.json. Does SqlServer work for you? Thanks

bravecobra commented 4 years ago

I think we have a case here of misunderstanding how docker and docker-compose works on a network level, together with the working of xip.io DNS resolving. Docker-compose basically starts up a mini virtual network.

networks:
 identity-host:
  driver: bridge

Each container can be considered as a tiny machine with its own IP address inside that network. If you want those little machine to work together you can refer to them by the name in the docker -compose. Look at the connection string of the database for instance. The connection string has the server db which matches the name of the docker container running SQL server. Note how each machine has a container name specified, for instance

container_name: skoruba-identityserver4-admin

Now, what does "localhost" mean from the perspective of a container? Well, as they can be considered as a little machine, then to each machine, localhost resolves to itself, not the localhost of your host machine (on which you run docker). Further, any address of xip.io resolves to localhost, thus depending on where you run that command, the machine responding will be the machine you run the command on. In our case here, the API and Admin UI, run on different "machines", thus while http://127.0.0.1.xip.io:9000 resolves perfectly on Admin UI, it will not find http://127.0.0.1.xip.io:5000, because API is not running on the "machine" of the Admin UI. If you want to resolve from one docker image to another, you need to refer to them with their docker name. Each container may expose a port to the outside network and make it accessible to the "localhost" of your host machine. If you then call http://127.0.0.1.xip.io:5000 and http://127.0.0.1.xip.io:9000 on your host machine, each will resolve the correct machine, which is something that will not work if you try to resolve these on the individual containers themselves, since their localhost is their own "localhost", not the "localhost" of the host.

Unfortunately, OAuth requires a fqdn (fully qualified domain name) for the issuer. That means we cannot use the container names (as they are not fqdn) hence the usage of xip.io instead of the docker name resolving.

If you ran the seeding of the database, based on localhost instead of 127.0.0.1.xip.io, then that configuration will not work inside a docker-compose env as the resolving will be incorrect when called from the docker host.

So, basically this is likely a case of incorrect configuration of both the seeding and the docker-compose file.

To confirm, could you try out the example of the dev branch? But keep in mind that you need create the migrations before building and running as the migrations as not part of the source code, you need to generate that yourself. Start from a fresh database and use thedocker-compose.yml as provided in the branch. There are a lot of env variables configured in each container which are ALL required to have the whole thing work correctly.

That all being said, how would you get rid of that xip.io configuration?

  1. You cannot use a simple edit of the hosts file. You would also need to add the extra_hosts option of docker-compose.
  2. Another option would be to have a DNS server proxy running as an extra container, which would allow to redirect dns queries to a DNS server outside the mini docker network together with the dns option of docker-compose
  3. Run the docker images on an orchestrator like kubernetes, which would allow scaling etc. but that's a different beast to tackle.

We choose the xip.io configuration together with proper env variables as it would not require extra network configuration outside docker and thus just work out of the box for development purposes. This configuration is not meant to be used in production. Then again, you would not use docker-compose in a production environment anyway.

skoruba commented 4 years ago

Thanks for your explanation, maybe what do you think about my use case, I've used your configuration of docker-compose (from dev branch), but I always get following error:

An unhandled exception occurred while processing the request. ExtendedSocketException: Name or service not known System.Net.Dns.InternalGetHostByName(string hostName)

SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught)

I cannot figure out, how to connect to sql server. I have the ef migrations in my project as well.

Any idea? :-) Thanks

bravecobra commented 4 years ago

Do you have a sql server running on your host machine as well? In the docker-compose.yml file the sql server is exposed on the host machine on port 1433. That might conflict with an existing sql server. You could choose a different port by changing that port and expose it differently like this:

db:
    image: "mcr.microsoft.com/mssql/server"
    ports:
      - 1434:1433

Now you should be able to connect to the sql server instance with SSMS on localhost:1434 on your host machine, even though it's running inside a docker image. This is a security issue of course. What you want to do is to not expose the port to the host machine but only to the other services running in the same mini-network like this:

db:
    image: "mcr.microsoft.com/mssql/server"
    ports:
      - 1433

but that would make debugging harder as you cannot connect to the database from your host machine. Try the following to see what docker-compose has running and how port are being forwarded

docker-compose ps

With the current configuration you should something like this:

λ  docker-compose ps
                Name                              Command               State                     Ports
--------------------------------------------------------------------------------------------------------------------------
skoruba-identityserver4-admin          dotnet Skoruba.IdentitySer ...   Up      0.0.0.0:32773->80/tcp,0.0.0.0:9000->80/tcp
skoruba-identityserver4-admin-api      dotnet Skoruba.IdentitySer ...   Up      0.0.0.0:32771->80/tcp,0.0.0.0:5000->80/tcp
skoruba-identityserver4-db             /opt/mssql/bin/permissions ...   Up      0.0.0.0:1433->1433/tcp
skoruba-identityserver4-sts-identity   dotnet Skoruba.IdentitySer ...   Up      0.0.0.0:32772->80/tcp,0.0.0.0:80->80/tcp

If you change the exposed port as suggested you should get something like this:

λ  docker-compose ps
                Name                              Command               State                     Ports
--------------------------------------------------------------------------------------------------------------------------
skoruba-identityserver4-admin          dotnet Skoruba.IdentitySer ...   Up      0.0.0.0:32773->80/tcp,0.0.0.0:9000->80/tcp
skoruba-identityserver4-admin-api      dotnet Skoruba.IdentitySer ...   Up      0.0.0.0:32771->80/tcp,0.0.0.0:5000->80/tcp
skoruba-identityserver4-db             /opt/mssql/bin/permissions ...   Up      0.0.0.0:1434->1433/tcp
skoruba-identityserver4-sts-identity   dotnet Skoruba.IdentitySer ...   Up      0.0.0.0:32772->80/tcp,0.0.0.0:80->80/tcp

Notice how the port of sql server is now exposed differently to the outside world (being your host machine). In SSMS you can then connect to that instance as localhost,1434. (<- that a comma there to specify the port).

image

Also note that, since we don't specify the sql server version of the docker image, we use the latest sql server, currently being developer edition of 15.0 on Ubuntu.

image

If all that fails, it's likely to be a firewall issue.

bravecobra commented 4 years ago

@skoruba btw, if you want, I might do a live stream on twitch demonstrating the docker-compose setup as well a kubernetes configuration. Hit me up if you want to part of that stream.

skoruba commented 4 years ago

@bravecobra Thanks for your tips, I will test it and report back the result. For sure, I want to watch your stream about these topics. Please let me know. 😊👍🏼

skoruba commented 4 years ago

I am getting stil same error:

Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught)

I did these steps: 1) Clone dev branch 2) Generate migrations 3) Change port 1433 to another, because I already have SQL Server 4) Exec command docker-compose up 5) I am able to show web site on http://127.0.0.1.xip.io but without access to DB.

I use this on my computer with Windows 10 Enterprise. I am able to connect to SQL Server from SSMS.

I tried some proccess on another computer with same issue.

@bravecobra - Any idea?

bravecobra commented 4 years ago

So sql server is up and running as you are able to connect the changed port instance, right? Apart from the port no changes to the docker-compose file. What's the output of docker-compose ps? Internally there should no firewalls.

sathoril commented 4 years ago

@bravecobra Thanks for the explanation about how the docker-compose works, that helped a lot.

I tried at home using the dev branch configuration and everything works fine!! BUT, at work unfortunately I get the same error that I mentioned above (The "Connection Refused" error). And I did everything the same way.

Now, I'm thinking that is some configuration on the company's network or the computer that I use at work. I'm out of solutions now, does anyone have any idea what could it be?

bravecobra commented 4 years ago

Try adding network_mode: bridge to each of the containers in docker-compose.yml. One thing I can think of is that docker-compose does not place the containers in the same "network", because another container already exists with the name name and it restarts that one instead of booting up a new one. https://docs.docker.com/compose/compose-file/#network_mode We use the default network here, maybe we need to be explicit about it.

skoruba commented 4 years ago

I finally figure out, where it was problem in my case, the file docker-compose.override.yml - loaded the connectionstrings from my secrets. If I use - docker-compose -f docker-compose.yml up - and change port of MSSQL from 1433 to another, it works. 👍 @bravecobra - Now I am considering how to use docker-compose.override and docker-compose.vs.debug in Visual Studio. Is it necessary to have these files in source control? (BTW: When do you plan - live stream about docker-compose and kubernetes ?) 😊 Thanks

bravecobra commented 4 years ago

It had to be something like that. No there is no absolute need to have them in source control, however they do provide a works-out-of-the-box experience without any negative impact. I'd leave them in. No fixed date planned yet for a stream. I suggest we talk about that somewhere else than in github issues.

skoruba commented 4 years ago

For sure @bravecobra - can you mail/send me some contact? Thx

ImaginaryDevelopment commented 4 years ago

I've been using

networks:
  idbackend:
    name: idbackend

at the top of the docker-compose

then each container that needs db access has to be in that network (and possibly more for other container-container direct contact outside of this compose.

services
  postgres:
    # other setup for that container    
    networks:
      - idbackend
  identity:
     # other setup for that container
    networks:
      - idbackend

no fqdn, and other docker containers outside that network have been able to ID4 interop. This is a private docker network, putting the skoruba stuff in a private network with the backend. The connection string used then (postgres example) uses Host=postgres in the connection string. Then we add the container names to the hosts file as 127.0.0.1 and (http://identity:5004 for example) works. we do have another network (docker external) that all the other containers expecting to see the identity server are a part of. This hasn't gone to production yet, but it is working locally in containers.

bravecobra commented 4 years ago

@ImaginaryDevelopment yep, that can work perfectly!

terah commented 4 years ago

Hi guys,

I've been trying to get this working for a couple of days now and I'm out of ideas. I think the issue is the same as that experienced in this issue and I think it's a simple configuration issue. I'm setting this up on my mac with the plan to move it to a linux server once I've got it working.

I've replaced my FQD with example.com and I created a real DNS entry for that domain name resolving to public IP of my mac. Once deployed I'll move the FQD to the public IP of my VPS.

When running the application in this exact configuration without TLS/HTTPS set in the Caddyfile (and changing the URLs everywhere to http) the whole stack works beautifully.

After changing the Caddy config to use HTTPS and setting the URLs everwhere (including the db) to HTTPS the STS application, API and swagger seems to be working fine.

There is a problem with the admin app where it throws the following exception anytime it's accessed:

System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)

System.Net.Http.HttpRequestException: Connection refused
 ---> System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)

System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
 ---> System.Net.Http.HttpRequestException: Connection refused
 ---> System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
 ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
 ---> System.Net.Http.HttpRequestException: Connection refused
 ---> System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsyncInternal(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at NWebsec.AspNetCore.Middleware.Middleware.CspMiddleware.Invoke(HttpContext context)
   at NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
   at NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
   at NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
   at NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
   at NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

My hunch is that there is missing or incorrect configuration in the skoruba.identityserver4.admin container that doesn't know how to work with the HTTPS configuration.

URLs:

Caddyfile:

# Redirect HTTP to HTTPS
http://auth.example.com:80 {
    redir https://{host}{uri}
}

# STS TLS Proxy to internal docker container
https://auth.example.com:443 {

    tls /data/certs/all-domains.crt /data/certs/all-domains.key

    log /data/log/prod-access.log
    errors /data/log/prod-error.log

    proxy / http://skoruba-identityserver4-sts-identity:80 {
        transparent
    }
}

# API TLS Proxy to internal docker container
https://auth.example.com:5000 {

    tls /data/certs/all-domains.crt /data/certs/all-domains.key

    log /data/log/prod-access.log
    errors /data/log/prod-error.log

    proxy / http://skoruba-identityserver4-admin-api:80 {
        transparent
    }
}

# ADMIN TLS Proxy to internal docker container
https://auth.example.com:9000 {

    tls /data/certs/all-domains.crt /data/certs/all-domains.key

    log /data/log/prod-access.log
    errors /data/log/prod-error.log

    proxy / http://skoruba-identityserver4-admin:80 {
        transparent
    }
}

Docker compose file:

version: '3.4'

services:
  skoruba.identityserver4.admin:
    image: ${DOCKER_REGISTRY-}skoruba-identityserver4-admin
#    ports:
#      - 9000:80
    build:
      context: .
      dockerfile: src/Skoruba.IdentityServer4.Admin/Dockerfile
    container_name: skoruba-identityserver4-admin
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - "ConnectionStrings__ConfigurationDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__PersistedGrantDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__IdentityDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__AdminLogDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__AdminAuditLogDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "AdminConfiguration__IdentityAdminBaseUrl=https://auth.example.com:9000"
      - "AdminConfiguration__IdentityAdminRedirectUri=https://auth.example.com:9000/signin-oidc"
      - "AdminConfiguration__IdentityServerBaseUrl=https://auth.example.com"
      - "AdminConfiguration__RequireHttpsMetadata=false"
      - "IdentityServerData__Clients__0__ClientUri=https://auth.example.com:9000"
      - "IdentityServerData__Clients__0__RedirectUris__0=https://auth.example.com:9000/signin-oidc"
      - "IdentityServerData__Clients__0__FrontChannelLogoutUri=https://auth.example.com:9000/signin-oidc"
      - "IdentityServerData__Clients__0__PostLogoutRedirectUris__0=https://auth.example.com:9000/signout-callback-oidc"
      - "IdentityServerData__Clients__0__AllowedCorsOrigins__0=https://auth.example.com:9000"
      - "IdentityServerData__Clients__1__RedirectUris__0=https://auth.example.com:5000/swagger/oauth2-redirect.html"
      - "Serilog__WriteTo__1__Args__connectionString=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
    command: dotnet Skoruba.IdentityServer4.Admin.dll /seed
    depends_on:
      - db
      - skoruba.identityserver4.sts.identity
    volumes:
      - "./shared/serilog.json:/app/serilog.json"
      - "./shared/identitydata.json:/app/identitydata.json"
      - "./shared/identityserverdata.json:/app/identityserverdata.json"
      - "./admin.appsettings.json:/app/appsettings.json"

  skoruba.identityserver4.admin.api:
    image: ${DOCKER_REGISTRY-}skoruba-identityserver4-admin-api
    build:
      context: .
      dockerfile: src/Skoruba.IdentityServer4.Admin.Api/Dockerfile
#    ports:
#      - 5000:80
    environment:
      - "AdminApiConfiguration__RequireHttpsMetadata=false"
      - "AdminApiConfiguration__ApiBaseUrl=https://auth.example.com:5000"
      - "AdminApiConfiguration__IdentityServerBaseUrl=https://auth.example.com"
      - "ConnectionStrings__ConfigurationDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__PersistedGrantDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__IdentityDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__AdminLogDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__AdminAuditLogDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
    container_name: skoruba-identityserver4-admin-api
    volumes:
      - "./shared/serilog.json:/app/serilog.json"
      - "./api.appsettings.json:/app/appsettings.json"

  skoruba.identityserver4.sts.identity:
    image: ${DOCKER_REGISTRY-}skoruba-identityserver4-sts-identity
#    ports:
#      - 80:80
    build:
      context: .
      dockerfile: src/Skoruba.IdentityServer4.STS.Identity/Dockerfile
    container_name: skoruba-identityserver4-sts-identity
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - "ConnectionStrings__ConfigurationDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__PersistedGrantDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "ConnectionStrings__IdentityDbConnection=Server=db;Port=5432;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123}"
      - "AdminConfiguration__IdentityAdminBaseUrl=https://auth.example.com:9000"
    depends_on:
      - db
    volumes:
      - "./shared/serilog.json:/app/serilog.json"
      - "./sts.appsettings.json:/app/appsettings.json"
      - "./auth.example.com.pfx:/app/certificate.pfx"

    # Don't know if this is needed..
    networks:
      default:
        aliases:
          - auth.example.com

  db:
    image: postgres:11
    ports:
      - 5432:5432
    container_name: skoruba-identityserver4-db
    environment:
      POSTGRES_USER: sa
      POSTGRES_PASSWORD: "${DB_PASSWORD:-Password_123}"
      POSTGRES_DB: IdentityServer4Admin
    volumes:
      - ./postgres:/var/lib/postgresql/data

  caddy:
    image: abiosoft/caddy:latest
    container_name: auth_proxy_caddy
    ports:
      - 80:80
      - 443:443
      - 5000:5000
      - 9000:9000
    volumes:
      - ./Caddyfile:/etc/Caddyfile
      - ./_letsencrypt/fullchain.pem:/data/certs/all-domains.crt
      - ./_letsencrypt/privkey.pem:/data/certs/all-domains.key
      - ./log:/data/log
    restart: unless-stopped

volumes:
  dbdata:
    driver: local

networks:
  default:
    driver: bridge

App Settings & Certificates:

{
    "ConnectionStrings": {
        "ConfigurationDbConnection": "Server=localhost; User Id=postgres; Database=is4admin; Port=5432; Password=postgres; SSL Mode=Prefer; Trust Server Certificate=true",
        "PersistedGrantDbConnection": "Server=localhost; User Id=postgres; Database=is4admin; Port=5432; Password=postgres; SSL Mode=Prefer; Trust Server Certificate=true",
        "IdentityDbConnection": "Server=localhost; User Id=postgres; Database=is4admin; Port=5432; Password=postgres; SSL Mode=Prefer; Trust Server Certificate=true"
    },
    "DatabaseProviderConfiguration": {
        "ProviderType": "PostgreSQL"
    },
    "CertificateConfiguration": {

        "UseTemporarySigningKeyForDevelopment": false,

        "CertificateStoreLocation": "LocalMachine",
        "CertificateValidOnly": true,

        "UseSigningCertificateThumbprint": false,
        "SigningCertificateThumbprint": "",

        "UseSigningCertificatePfxFile": true,
        "SigningCertificatePfxFilePath": "/app/certificate.pfx",
        "SigningCertificatePfxFilePassword": "my-cert-pass",

        "UseValidationCertificatePfxFile": true,
        "ValidationCertificatePfxFilePath": "/app/certificate.pfx",
        "ValidationCertificatePfxFilePassword": "my-cert-pass",

        "UseValidationCertificateThumbprint": false,
        "ValidationCertificateThumbprint": ""
    },
    "RegisterConfiguration": {
        "Enabled": true
    },
    "ExternalProvidersConfiguration": {
        "UseGitHubProvider": false,
        "GitHubClientId": "",
        "GitHubClientSecret": ""
    },
    "SmtpConfiguration": {
        "Host": "",
        "Login": "",
        "Password": ""
    },
    "SendgridConfiguration": {
        "ApiKey": "",
        "SourceEmail": "",
        "SourceName": ""
    },
    "LoginConfiguration": {
        "ResolutionPolicy": "Username"
    },
    "AdminConfiguration": {
        "PageTitle": "Skoruba IdentityServer4",
        "HomePageLogoUri": "/images/skoruba-icon.png",
        "FaviconUri": "/favicon.ico",
        "IdentityAdminBaseUrl": "http://localhost:9000",
        "AdministrationRole": "SkorubaIdentityAdminAdministrator"
    },
  "CultureConfiguration": {
    "Cultures": [],
    "DefaultCulture": null
  }
}

URLs in seeded data:

update "PersistedGrants" set "Data" = REPLACE("Data", 'http://127.0.0.1.xip.io', 'https://auth.example.com');
update "ClientCorsOrigins" set "Origin"  = REPLACE("Origin", 'http://127.0.0.1.xip.io', 'https://auth.example.com');
update "ClientPostLogoutRedirectUris" SET "PostLogoutRedirectUri" = REPLACE("PostLogoutRedirectUri", 'http://127.0.0.1.xip.io', 'https://auth.example.com');
update "ClientRedirectUris" SET "RedirectUri" = REPLACE("RedirectUri", 'http://127.0.0.1.xip.io', 'https://auth.example.com');
xirami commented 4 years ago

Just to give you proper solution...I am using PostgreSQL...works as expected. Someone has nicely described xip.io concept of DNS. Analogically, you have to declare all other dependant compose services using the same concept, especially database:

networks:
      adminUiNetwork:
          aliases:
              - db.127.0.0.1.xip.io