Introducción
.NET es relativamente nuevo en el mundo del código abierto, y su popularidad no se acerca a las plataformas principales como Node.js. Así que puedes imaginar que hay pocos tutoriales que tratan con .NET y frameworks como ASP.NET en Heroku. Y aquellos que lo hacen, probablemente no usarán contenedores.

¿Ves C # /. NET aquí? Si yo tampoco.
Empezando
Este tutorial asumirá que tiene instaladas las herramientas Docker, .NET Core y Heroku. Usaré Linux (Ubuntu), pero AFAIK esas herramientas son multiplataforma, por lo que los pasos serán los mismos para cualquier sistema operativo compatible.
Tomemos el caso más fácil: la aplicación MVC simple. Si no tiene uno, solo créelo ejecutando
dotnet new mvc --name mymvc
También supondré que tienes un dockerfile listo, tal vez algo como lo propuesto en este tutorial :
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS builder WORKDIR /sources COPY *.csproj . RUN dotnet restore COPY . . RUN dotnet publish --output /app/ --configuration Release FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 WORKDIR /app COPY --from=builder /app . CMD ["dotnet", "MyMvc.dll"]
Observe cómo ENTRYPOINT fue sustituido por CMD, más sobre eso más adelante.
Entonces, cd a la carpeta de su aplicación y comencemos.
Inicie sesión en el registro de contenedores Heroku.
heroku container:login
Si no tiene un repositorio git existente, git init
uno nuevo
Ejecute heroku create
para crear una nueva aplicación, tenga en cuenta la dirección de repositorio de git proporcionada, por ejemplo
Creating salty-fortress-4191... done, stack is heroku-16 https://salty-fortress-4191.herokuapp.com/ | https://git.heroku.com/salty-fortress-4191.git
(Opcional) Comprueba que tienes heroku remote ejecutando git remote -v
Dile a Heroku que use contenedores:
heroku stack:set container
Crea el archivo heroku.yml. La versión minimalista es algo así como:
build: docker: web: Dockerfile
Por defecto, ASP.NET core se ejecuta en el puerto 5000 y 5001 (https). Heroku no lo permitirá. Si intentas ejecutarlo como está, Kestrel no se iniciará, lanzando una excepción:
System.Net.Sockets.SocketException (13): Permission denied
Heroku parece permitir que su aplicación escuche en el puerto especificado en la variable de entorno $PORT
. Por lo tanto, debe asegurarse de que su aplicación escuche eso, en lugar de la predeterminada. En caso de que esté utilizando la aplicación predeterminada, simplemente sustituya CreateWebHostBuilder
con la siguiente en Program.cs
:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) { var port = Environment.GetEnvironmentVariable("PORT"); return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls("http://*:"+port); }
Compromete todo:
git add . && git commit -m 'Meaningful commit message'
Ahora presione el código para construir y liberar el contenedor (dedos cruzados):
git push heroku master
¿Ahora recuerda cuándo ENTRYPOINT fue sustituido por CMD en dockerfile? No pasamos ningún argumento al contenedor, por lo que ENTRYPOINT ["dotnet", "MyMvc.dll"]
y CMD ["dotnet", "MyMvc.dll"]
deberían comportarse de manera similar. Pero si deja ENTRYPOINT, obtendrá un error:

¡Qué gran error - "Estado inesperado de respuesta de actualización de fomation"! Realmente te dice la raíz del problema.
El verdadero problema es que al usar heroku.yml
minimalista que mostré arriba, Heroku esperará instrucciones CMD en su dockerfile. Cuando lo agregue, todo debería funcionar bien.
Conclusión
Ahora debería tener alguna idea de cómo implementar aplicaciones simples ASP.NET Core en Heroku. ¿Es intuitivo? Absolutamente no ¿Es Heroku la mejor plataforma para alojar sus aplicaciones .NET? Probablemente no. Pero como es fácil registrarse allí y el plan más básico es gratuito, tal vez desee hospedar algo allí, solo por diversión.
Referencias
- https://devcenter.heroku.com/articles/container-registry-and-runtime
- https://devcenter.heroku.com/articles/build-docker-images-heroku-yml
- https://docs.docker.com/engine/examples/dotnetcore/ (Dockerfile)