关于将网络核心应用程序部署到Heroku服务器

问题描述:

我正在尝试使用docker将.net核心WEB API部署到Heroku服务器.我构建并发布了我的应用程序,构建了我的docker映像,然后将其部署到Heroku服务器.我已经运行了以下命令:

I am trying to deploy .net core WEB API to Heroku servers with docker. I build and publish my App, I build my docker image and after I deploy to Heroku servers. I have run the following commands:

  1. heroku登录
  2. heroku container:登录
  3. dotnet恢复
  4. dotnet发布-c版本
  5. docker build -t pdx-ys-backend.(在docker文件文件夹"bin \ Release \ netcoreapp2.2 \ publish"中)
  6. docker标记pdx-ys-backend Registry.heroku.com/pdx-ys-backend/web
  7. docker push Registry.heroku.com/pdx-ys-backend/web
  8. heroku容器:发布网络--app pdx-ys-backend

我的docker文件是:

My docker File is:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
COPY . .
CMD ASPNETCORE_URLS=http://*$PORT dotnet YangSoft.2.WebAPI.dll

我的startup.cs:

My startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Application;
using Application.AutoMapper;
using Application.Exceptions;
using Infrastructure;
using Infrastructure.Seed;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Swagger;


namespace YangSoft._2.WebAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Use a PostgreSQL database
            var sqlConnectionString = Configuration.GetConnectionString("DataAccessPostgreSqlProvider");

            services.RegisterInfrastructureServices(sqlConnectionString, Configuration);
            services.AddAutoMapperSetup();
            services.RegisterApplicationServices();

            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder.WithOrigins("https://localhost:3000", "http://localhost:3000")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);


            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v2.0", new Info { Title = "YS API v2.0", Version = "v2.0" });

                // Swagger 2.+ support
                var security = new Dictionary<string, IEnumerable<string>>
                {
                    {"Bearer", new string[] { }},
                };

                c.AddSecurityDefinition("Bearer", new ApiKeyScheme() { In = "header", Description = "Please insert JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
                c.AddSecurityRequirement(security);
                c.SwaggerDoc("v1", new Info { Title = "YangSoft API", Version = "v1" });
                c.CustomSchemaIds(s => s.FullName);
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IDbinitializer dbinitializer)
        {

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                dbinitializer.Initialize();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseSwagger();
            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "YangSoft API");
                c.RoutePrefix = string.Empty;
                c.DocumentTitle = "YangSoftAPI Swagger Documentation";
            });

            app.UseCors(builder => builder.AllowAnyHeader().AllowAnyOrigin().WithMethods("GET", "POST", "OPTIONS", "DELETE", "PUT"));
            app.UseHttpsRedirection();
            app.UseAuthentication();
            app.UseMiddleware(typeof(ErrorHandlingMiddleware));
            app.UseMvcWithDefaultRoute();
        }
    }
}

还有我的program.cs

And my program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace YangSoft._2.WebAPI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

平台向我显示以下错误

The platform shows me the following error

这是Heroku的日志:

And here are the Heroku's logs:

2020-02-24T12:54:28.086049+00:00 app[api]: Deployed web (f48d9fbff2f7) by user pdxdevelop@gmail.com
2020-02-24T12:54:28.086049+00:00 app[api]: Release v3 created by user pdxdevelop@gmail.com
2020-02-24T12:54:28.108716+00:00 app[api]: Scaled to web@1:Free by user pdxdevelop@gmail.com
2020-02-24T12:54:33.158551+00:00 heroku[web.1]: Starting process with command `/bin/sh -c ASPNETCORE_URLS\=http://\*\31326\ dotnet\ YangSoft.2.WebAPI.dll`
2020-02-24T12:54:37.592379+00:00 heroku[web.1]: State changed from starting to crashed
2020-02-24T12:54:36.964344+00:00 app[web.1]: : Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
2020-02-24T12:54:36.964370+00:00 app[web.1]: User profile is available. Using '/app/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
2020-02-24T12:54:36.975068+00:00 app[web.1]: info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
2020-02-24T12:54:36.975077+00:00 app[web.1]: Creating key {d658c8a4-f9be-49c5-aa59-f05c80a0cf75} with creation date 2020-02-24 12:54:36Z, activation date 2020-02-24 12:54:36Z, and expiration date 2020-05-24 12:54:36Z.
2020-02-24T12:54:36.985908+00:00 app[web.1]: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
2020-02-24T12:54:36.985909+00:00 app[web.1]: No XML encryptor configured. Key {d658c8a4-f9be-49c5-aa59-f05c80a0cf75} may be persisted to storage in unencrypted form.
2020-02-24T12:54:36.990050+00:00 app[web.1]: info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
2020-02-24T12:54:36.990052+00:00 app[web.1]: Writing data to file '/app/.aspnet/DataProtection-Keys/key-d658c8a4-f9be-49c5-aa59-f05c80a0cf75.xml'.
2020-02-24T12:54:37.665340+00:00 heroku[web.1]: State changed from crashed to starting
2020-02-24T12:54:37.487934+00:00 app[web.1]: crit: Microsoft.AspNetCore.Server.Kestrel[0]
2020-02-24T12:54:37.487974+00:00 app[web.1]: Unable to start Kestrel.
2020-02-24T12:54:37.487975+00:00 app[web.1]: System.Net.Sockets.SocketException (13): Permission denied
2020-02-24T12:54:37.487975+00:00 app[web.1]: at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
2020-02-24T12:54:37.487976+00:00 app[web.1]: at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
2020-02-24T12:54:37.487977+00:00 app[web.1]: at System.Net.Sockets.Socket.Bind(EndPoint localEP)
2020-02-24T12:54:37.487977+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
2020-02-24T12:54:37.487978+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
2020-02-24T12:54:37.487978+00:00 app[web.1]: --- End of stack trace from previous location where exception was thrown ---
2020-02-24T12:54:37.487979+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
2020-02-24T12:54:37.487980+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:37.487987+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:37.487988+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
2020-02-24T12:54:37.487989+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
2020-02-24T12:54:37.487990+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
2020-02-24T12:54:37.499101+00:00 app[web.1]:
2020-02-24T12:54:37.502608+00:00 app[web.1]: Unhandled Exception: System.Net.Sockets.SocketException: Permission denied
2020-02-24T12:54:37.502611+00:00 app[web.1]: at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
2020-02-24T12:54:37.502612+00:00 app[web.1]: at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
2020-02-24T12:54:37.502612+00:00 app[web.1]: at System.Net.Sockets.Socket.Bind(EndPoint localEP)
2020-02-24T12:54:37.502613+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
2020-02-24T12:54:37.502613+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
2020-02-24T12:54:37.502614+00:00 app[web.1]: --- End of stack trace from previous location where exception was thrown ---
2020-02-24T12:54:37.502615+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
2020-02-24T12:54:37.502615+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:37.502616+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:37.502617+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
2020-02-24T12:54:37.502618+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
2020-02-24T12:54:37.502619+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
2020-02-24T12:54:37.502620+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
2020-02-24T12:54:37.502620+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
2020-02-24T12:54:37.502620+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
2020-02-24T12:54:37.502621+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
2020-02-24T12:54:37.502621+00:00 app[web.1]: at YangSoft._2.WebAPI.Program.Main(String[] args) in C:\Users\Mathias\Documents\YangSoft\YangSoft\Backend\YangSoft.2.WebAPI\Program.cs:line 18
2020-02-24T12:54:37.521106+00:00 app[web.1]: Aborted
2020-02-24T12:54:37.575022+00:00 heroku[web.1]: Process exited with status 134
2020-02-24T12:54:43.370035+00:00 heroku[web.1]: Starting process with command `/bin/sh -c ASPNETCORE_URLS\=http://\*\7013\ dotnet\ YangSoft.2.WebAPI.dll`
2020-02-24T12:54:47.431294+00:00 app[web.1]: info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
2020-02-24T12:54:47.431338+00:00 app[web.1]: User profile is available. Using '/app/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
2020-02-24T12:54:47.446767+00:00 app[web.1]: info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
2020-02-24T12:54:47.452185+00:00 app[web.1]: Creating key {9beba187-065b-462d-9ef5-1d1c25993ec4} with creation date 2020-02-24 12:54:47Z, activation date 2020-02-24 12:54:47Z, and expiration date 2020-05-24 12:54:47Z.
2020-02-24T12:54:47.471368+00:00 app[web.1]: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
2020-02-24T12:54:47.471403+00:00 app[web.1]: No XML encryptor configured. Key {9beba187-065b-462d-9ef5-1d1c25993ec4} may be persisted to storage in unencrypted form.
2020-02-24T12:54:47.477442+00:00 app[web.1]: info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
2020-02-24T12:54:47.477443+00:00 app[web.1]: Writing data to file '/app/.aspnet/DataProtection-Keys/key-9beba187-065b-462d-9ef5-1d1c25993ec4.xml'.
2020-02-24T12:54:48.263004+00:00 heroku[web.1]: State changed from starting to crashed
2020-02-24T12:54:48.244318+00:00 heroku[web.1]: Process exited with status 134
2020-02-24T12:54:48.156913+00:00 app[web.1]: crit: Microsoft.AspNetCore.Server.Kestrel[0]
2020-02-24T12:54:48.156944+00:00 app[web.1]: Unable to start Kestrel.
2020-02-24T12:54:48.156946+00:00 app[web.1]: System.Net.Sockets.SocketException (13): Permission denied
2020-02-24T12:54:48.156947+00:00 app[web.1]: at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
2020-02-24T12:54:48.156948+00:00 app[web.1]: at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
2020-02-24T12:54:48.156948+00:00 app[web.1]: at System.Net.Sockets.Socket.Bind(EndPoint localEP)
2020-02-24T12:54:48.156954+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
2020-02-24T12:54:48.156955+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
2020-02-24T12:54:48.156955+00:00 app[web.1]: --- End of stack trace from previous location where exception was thrown ---
2020-02-24T12:54:48.156957+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
2020-02-24T12:54:48.156958+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:48.156958+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:48.156958+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
2020-02-24T12:54:48.156959+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
2020-02-24T12:54:48.156961+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
2020-02-24T12:54:48.168253+00:00 app[web.1]:
2020-02-24T12:54:48.171374+00:00 app[web.1]: Unhandled Exception: System.Net.Sockets.SocketException: Permission denied
2020-02-24T12:54:48.171376+00:00 app[web.1]: at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
2020-02-24T12:54:48.171376+00:00 app[web.1]: at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
2020-02-24T12:54:48.171377+00:00 app[web.1]: at System.Net.Sockets.Socket.Bind(EndPoint localEP)
2020-02-24T12:54:48.171377+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
2020-02-24T12:54:48.171377+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
2020-02-24T12:54:48.171378+00:00 app[web.1]: --- End of stack trace from previous location where exception was thrown ---
2020-02-24T12:54:48.171379+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
2020-02-24T12:54:48.171379+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:48.171380+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context)
2020-02-24T12:54:48.171380+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
2020-02-24T12:54:48.171381+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
2020-02-24T12:54:48.171383+00:00 app[web.1]: at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
2020-02-24T12:54:48.171383+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
2020-02-24T12:54:48.171384+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
2020-02-24T12:54:48.171384+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
2020-02-24T12:54:48.171384+00:00 app[web.1]: at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
2020-02-24T12:54:48.171385+00:00 app[web.1]: at YangSoft._2.WebAPI.Program.Main(String[] args) in C:\Users\Mathias\Documents\YangSoft\YangSoft\Backend\YangSoft.2.WebAPI\Program.cs:line 18
2020-02-24T12:54:48.205641+00:00 app[web.1]: Aborted

我尝试使用各种docker文件,将端口更改为8080,但我在启动时一直在寻找问题,但没有找到解决方案.

I have tried with various docker files, changing the port to 8080, and I was looking for issues in my startup but I didn't find the solution.

https://devcenter.heroku.com/articles/setting-the-http-port-for-java-applications

这是为Java应用程序编写的,但它适用于Heroku上托管的任何Web应用程序.当您运行Web Worker时,必须将端口绑定到环境变量 $ PORT .您无法指定自定义端口.

this is written for java application but it applies to any web application hosted on Heroku. When you are running a web worker you have to bind the port to the environment variable $PORT. You cannot specify a custom port.

绑定到正确的端口后,这些错误应消失:

Once you bound to the proper port these error should vanish:

Unhandled Exception: System.Net.Sockets.SocketException: Permission denied

然后您的应用程序可能会运行,或者您可能遇到其他错误.如果您以后遇到其他问题,请创建一个新问题.

Your application might then work or you might be experiencing different errors. If you are experiencing later a different issue please create a new question.