Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deployed on Linux App Svc, -admin site works, but -portal docker logs: Hosting failed to start - Unable to configure HTTPS #789

Open
officemikedev opened this issue Dec 23, 2024 · 1 comment

Comments

@officemikedev
Copy link

officemikedev commented Dec 23, 2024

Describe the bug
Deployed on Linux App Svc, -admin site works, but -portal dockers logs: Hosting failed to start - Unable to configure HTTPS endpoint. No server certificate was specified

  • The Admin site works as expected both Locally and Deployed to Linux App Svc.
  • Running locally, the CustomerSite works as expected.
  • Deployed to a Linux App Svc, the CustomerSite fails to start, see error stack below
  • Deployed to a Windows App Svc, the CustomerSite works normally
    If there's a configuration difference between Admin and Customer sites, I am not seeing it.

After deployment, the scm site bash shell docker log contains:

2024-12-23T06:08:32.531339752Z Agent extension 
2024-12-23T06:08:32.531365452Z Before if loop >> DotNet Runtime 
2024-12-23T06:08:32.692417493Z DotNet Runtime 8.0Writing output script to '/opt/startup/startup.sh'
2024-12-23T06:08:32.794323496Z Trying to find the startup DLL name...
2024-12-23T06:08:32.802425779Z Found the startup D name: CustomerSite.dll
2024-12-23T06:08:32.803435702Z Running the command: dotnet "CustomerSite.dll"
2024-12-23T06:08:42.328899428Z fail: Microsoft.Extensions.Hosting.Internal.Host[11]
2024-12-23T06:08:42.328957929Z       Hosting failed to start
2024-12-23T06:08:42.336054484Z       System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
2024-12-23T06:08:42.336081485Z       To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
2024-12-23T06:08:42.336086085Z       For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
2024-12-23T06:08:42.336089485Z          at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions
 . . .
2024-12-23T06:08:42.527516576Z    at Marketplace.SaaS.Accelerator.CustomerSite.Program.Main(String[] args) in C:\mikesrc\github\officemikedev\Commercial-Marketplace-SaaS-Accelerator\src\CustomerSite\Program.cs:line 18
2024-12-23T06:08:49.022463278Z /opt/startup/startup.sh: line 20:    92 Aborted                 (core dumped) dotnet "CustomerSite.dll"

To Reproduce
Steps to reproduce the behavior:

  1. Modify Deploy.ps1 to create App Svc Plan with --is-linux, and App Services with --runtime DOTNETCORE:8.0
  2. Run deploy.ps1
  3. Deploy AdminSite from Visual Studio Publish Profile to Azure Linux App Svc -admin site.
  4. Wait for deployment to complete and see site comes up normally, can query Subscriptions and users, etc.
  5. Deploy CustomerSite from Visual Studio Publish Profile to Azure Linux App Svc -portal site.
  6. Wait for deployment to complete and site to come up, it displays ": ( Application Error"

Expected behavior
The CustomerSite Home/Index page should show

Screenshots
If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

  • Are you using the CloudShell? Yes, to execute Deploy.ps1 of a Fork

Additional context
Things I've checked:

  • both sites (-admin and -portal) have the default Custom Domains "MYPREFIX-admin.azurewebsites.net" and "MYPREFIX-portal.azurewebsites.net'
  • -portal appsvc is on the vnet same as -admin
  • -portal appsvc managed identity has KeyVault Access Policy, and the Managed Identity has more than it needs
  • -portal managed Identity is a DB External user with read and write roles
  • I've recreated several times running Deploy.ps1 with a different PREFIX, and consistently Admin site works, and Customer Portal site fails to start with the same error stack.
  • I tried making CustomerSite be self-contained deployment
  • The problem follows the code: Deploying Admin site to the Customer App Svc, Admin site runs normally on the MYPREFIX-portal site (so I think it is not the Portal App Service at fault).
  • The problem follows the code: Deploying CustomerSite to the Admin site causes -admin app svc to fail in the same way during startup. Re-deploying AdminSite to -admin App Svc restores functioning of the Admin Site to the -admin app svc.
  • I do not see any difference between the 2 sites (Admin and Customer) regarding use of HttpsRedirection or certificates or anything that would explain this.
  • It doesn't make sense Deployed Admin works and Customer site does not
  • It does not make sense that Local-running Customer site works and Deployed with same app settings.Development.json values in App Svc Environment it fails to start.
  • I've whittled down the project, removed HomeController and almost everything in Startup.cs, no services are registered, and still the site cannot start when deployed to App Svc. (see Startup.cs code in next comment).

Since the above, I did 2 things:
A. Deployed to a Windows App Svc, and the deployment starts and works normally.
B. Deployed to a completely new Linux App Service on it's own Plan, and starup fails with same Error stack
Therefore:

  • There must be some configuration in the project. I am not seeing it.
  • Having commented most of CustomerSite/Startup.cs in an experiment (see comment below) and it still failed startup in the same way, it's hard to put a finger on what was left in that deployment to trigger this error when deployed to Linux App Svc ,Net 8 runtime.
  • Noting again, the Admin site works on Linux APp Svc, so what is different (thinking outloud).

Later: Trying a NEW ASPNET MVC PROJECT: WORKS!

I created a new Mvc Project on .Net8 (LTS), and copied in the HomeController from CustomerSite, and setup all the project dependencies and updated program.cs to register classes and DbContext. It is using useHsts() and useHttsRedirection() as created by the VStudio New Project template.

  • It runs locally and works normally
  • Deployed to Linux App Svc, it works, no startup problems, I can bring up Home page with my SAAS Offer Token and it finds the SubscriptionId and connects to database to get current status, and I see the "Subscription Details" page. It is https and the cert is trusted by the browser.

It is working fine deployed to Linux App Svc from a new AspNet .csproject.

Therefore:

There has to be some small configuration in the CustomerSite that if gone through with a fine-toothed comb it be discoverable. , fixable and lead to a PR. I am not seeing it.

@officemikedev officemikedev changed the title Deployed on Linux App Svc, -admin site works, but -portal dockers logs: Hosting failed to start - Unable to configure HTTPS Deployed on Linux App Svc, -admin site works, but -portal docker logs: Hosting failed to start - Unable to configure HTTPS Dec 23, 2024
@officemikedev
Copy link
Author

officemikedev commented Dec 23, 2024

While working on this issued I tried commenting out virtually everything in Startup to see if it would stop the error. Following is the Startup.cs as it is in this test. Later I found if I create a new Asp.Net 8 project and copied the CustomerSite/HomeController into ithe new Mvc project (along with dependencies) then it deploys to Linux App Svc and runs just fine.

I have commented out most of Startup.cs a,d replaced HomeController with a simple TestController that has no Dependencies injected. There is so little happening in startup.cs now, I've eliminated just about everything that could be trying to use a certificate that doesn't exist.

I have other App Svc Plans that are Linux and have more than one App on them and they both work , I don't think this is an App Svc Linux limit.

Here's what remains in Startup.cs:


namespace Marketplace.SaaS.Accelerator.CustomerSite;

/// <summary>
/// Defines the <see cref="Startup" />.
/// </summary>
public class Startup
{
    /// <summary>
    /// Initializes a new instance of the <see cref="Startup"/> class.
    /// </summary>
    /// <param name="configuration">The configuration<see cref="IConfiguration"/>.</param>
    public Startup(IConfiguration configuration)
    {
        this.Configuration = configuration;
    }

    /// <summary>
    /// Gets the Configuration.
    /// </summary>
    public IConfiguration Configuration { get; }

    /// <summary>
    /// The ConfigureServices.
    /// </summary>
    /// <param name="services">The services<see cref="IServiceCollection"/>.</param>
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        //var config = new SaaSApiClientConfiguration()
        //{
        //    AdAuthenticationEndPoint = this.Configuration["SaaSApiConfiguration:AdAuthenticationEndPoint"],
        //    ClientId = this.Configuration["SaaSApiConfiguration:ClientId"],
        //    ClientSecret = this.Configuration["SaaSApiConfiguration:ClientSecret"],
        //    MTClientId = this.Configuration["SaaSApiConfiguration:MTClientId"],
        //    FulFillmentAPIBaseURL = this.Configuration["SaaSApiConfiguration:FulFillmentAPIBaseURL"],
        //    FulFillmentAPIVersion = this.Configuration["SaaSApiConfiguration:FulFillmentAPIVersion"],
        //    GrantType = this.Configuration["SaaSApiConfiguration:GrantType"],
        //    Resource = this.Configuration["SaaSApiConfiguration:Resource"],
        //    SaaSAppUrl = this.Configuration["SaaSApiConfiguration:SaaSAppUrl"],
        //    SignedOutRedirectUri = this.Configuration["SaaSApiConfiguration:SignedOutRedirectUri"],
        //    TenantId = this.Configuration["SaaSApiConfiguration:TenantId"],
        //    Environment = this.Configuration["SaaSApiConfiguration:Environment"]
        //};
        //var creds = new ClientSecretCredential(config.TenantId.ToString(), config.ClientId.ToString(), config.ClientSecret);

        //services
        //    .AddAuthentication(options =>
        //    {
        //        options.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme;
        //        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //        options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //    })
        //    .AddCookie(options =>
        //    {
        //        options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
        //        options.Cookie.MaxAge = options.ExpireTimeSpan;
        //        options.SlidingExpiration = true;
        //    })
        //    .AddOpenIdConnect(options =>
        //    {
        //        options.Authority = $"{config.AdAuthenticationEndPoint}/common/v2.0";
        //        options.ClientId = config.MTClientId;
        //        options.ResponseType = OpenIdConnectResponseType.IdToken;
        //        options.CallbackPath = "/Home/Index";
        //        options.SignedOutRedirectUri = config.SignedOutRedirectUri;
        //        options.TokenValidationParameters.NameClaimType = ClaimConstants.CLAIM_SHORT_NAME;
        //        options.TokenValidationParameters.ValidateIssuer = false;
        //    });
        //services
        //    .AddTransient<IClaimsTransformation, CustomClaimsTransformation>()
        //    .AddScoped<ExceptionHandlerAttribute>()
        //    .AddScoped<RequestLoggerActionFilter>();

        //if (!Uri.TryCreate(config.FulFillmentAPIBaseURL, UriKind.Absolute, out var fulfillmentBaseApi)) 
        //{
        //    fulfillmentBaseApi = new Uri("https://marketplaceapi.microsoft.com/api");
        //}

        //services
        //    .AddSingleton<IFulfillmentApiService>(new FulfillmentApiService(new MarketplaceSaaSClient(fulfillmentBaseApi, creds), config, new FulfillmentApiClientLogger()))
        //    .AddSingleton<SaaSApiClientConfiguration>(config)
        //    .AddSingleton<ValidateJwtToken>();

        // Add the assembly version
        //services.AddSingleton<IAppVersionService>(new AppVersionService(Assembly.GetExecutingAssembly()?.GetName()?.Version));

        //services
        //    .AddDbContext<SaasKitContext>(options => options.UseSqlServer(this.Configuration.GetConnectionString("DefaultConnection")));

        //InitializeRepositoryServices(services);

        services.AddMvc(option => {
            option.EnableEndpointRouting = false;
            option.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        });
    }

    /// <summary>
    /// The Configure.
    /// </summary>
    /// <param name="app">The app<see cref="IApplicationBuilder" />.</param>
    /// <param name="env">The env<see cref="IWebHostEnvironment" />.</param>
    /// <param name="loggerFactory">The loggerFactory<see cref="ILoggerFactory" />.</param>
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            //app.UseHsts();
        }

        //app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();
        //app.UseAuthentication();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Test}/{action=Index}/{id?}");
        });
    }

    //private static void InitializeRepositoryServices(IServiceCollection services)
    //{
    //    services.AddScoped<ISubscriptionsRepository, SubscriptionsRepository>();
    //    services.AddScoped<IPlansRepository, PlansRepository>();
    //    services.AddScoped<IUsersRepository, UsersRepository>();
    //    services.AddScoped<ISubscriptionLogRepository, SubscriptionLogRepository>();
    //    services.AddScoped<IApplicationLogRepository, ApplicationLogRepository>();
    //    services.AddScoped<IWebhookProcessor, WebhookProcessor>();
    //    services.AddScoped<IWebhookHandler, WebHookHandler>();
    //    services.AddScoped<IApplicationConfigRepository, ApplicationConfigRepository>();
    //    services.AddScoped<IEmailTemplateRepository, EmailTemplateRepository>();
    //    services.AddScoped<IOffersRepository, OffersRepository>();
    //    services.AddScoped<IOfferAttributesRepository, OfferAttributesRepository>();
    //    services.AddScoped<IPlanEventsMappingRepository, PlanEventsMappingRepository>();
    //    services.AddScoped<IEventsRepository, EventsRepository>();
    //    services.AddScoped<IEmailService, SMTPEmailService>();
    //    services.AddScoped<SaaSClientLogger<HomeController>>();
    //    services.AddScoped<IWebNotificationService, WebNotificationService>();
    //}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant