Create a new ASP.NET Core Web API
project.
Give a name to the project and put it Github repo root folder.
Select .Net version.
The version you choose here will reflect in dockerfile, so be free to change .net version but remember to adapt your dockerfile.
Select webapi
option to run.
Run the project, make a GET resquet at /weatherforecast
endpoint just to test if everthing its fine.
Program.cs
Change your Program.cs
to be like this code:
csharp
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace webapi
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
var port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
if (environment == "Development")
{
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
else
{
var url = new[]
{
string.Concat("http://0.0.0.0:", port)
};
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>().UseUrls(url); });
}
}
}
}
In this code, its importante to set up 0.0.0.0
IP when its running in a container, because when we use Google Cloud Run, we are running or code inside a container. In my case, I put it for every environment except the Delopment environment.
Dockerfile
Create the Dockerfile
file in the root folder of your repo. Check if all your project files are in the root, if not, move to the root folder.
Edit your Dockerfile with the following code:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build-env /app/out .
ENV ASPNETCORE_ENVIRONMENT Production
ENTRYPOINT ["dotnet", "webapi.dll"]
Remember to change de DLL file name in the last line, this name must be exactilly the name of your project main .dll file.
If your project you another folder structure, maybe you'll need make changes in your dockerfile.
Save all files and commit.
GCP Cloud Run
If you like, create a new project.
Search for Cloud Run
, open Cloud Run product. Create a new service.
If you created a new project or is your first time using Cloud Build, maybe its necessary to Enable Cloud Build API, like me.
Select Continuously deploy new revisions from a source repository
and click Setup With Cluod Build
Important: I connected my Github account previously, therefore, I couldn't take prints in this step, but if its your first time, you need to connect your Github and GCP accounts.
Select your Github repository to be published.
Proceed to the second step and check Dockerfile option. In Branch
field, keep the standard value ^main$
, this way every commit at branch main will trigger a new build at Cloud Build to be published in Cloud Run. Keep in mind that its possible to change to another branch.
Fill the Service name
, I just kept default value. Choose a region, again I kept default.
At Autoscaling option I choose zero as minimum instances, because this reduces costs, but if you wish reduce latence and improve response time, keep in mind that probabily you will need at least one instance.
As well as minimum instances, to limit the cost I choose just 1 instance at maximum. If you wish improve availabillity and reliabillity, consider increase this number according with your traffic volume
Lastly, select Ingress and Authentication settings, for this tutorial I choose Allow all traffic
and Allow unauthenticated invocations
. But, for production applications, consider restrict your traffic and unauthenticated request.
Optional: Open Container, Connections, Security
menu and ajust your container capacity.
For this deploy its not necessary to be concerned about this, and you can change this latter.
Save and create your service. Wait.
With everything done, you must get a result like bellow image:
The highlighted URL is provided by GCP and is the public URL to access your service. Try to access your /weatherforecast
endpoint.
URL: https://democsharpgcpcloudrun-lwy2plkqfa-uc.a.run.app/weatherforecast
Conclusion
With this configuration, every new commit in your branch main in Github repository will trigger a new build at Google Cloud Build and if the build success, a new version of your application will be deployed in Google Cloud Run.
The Cloud Run has a resource called Reviews that allow us to rollback a version if the new one breaks our API.
In addition to allowing us to manage the traffic between version, witch allow us to deploy using canary method. Unfortunately, until now, I couldn't configure that canary to be automated with deploy, If you know how to automate traffic management during the deploy, please put in the comments.
Thank you for reading and I hold this was useful.
Top comments (6)
What would be the cost for basic/hobby project (like the above) hosting in the Google Cloud?
I'll share with you one of my projects cost. Its a personal project using Google Cloud Run for an API. The database is hosted in another cloud provider called Scaleway and I pay €10/month.
This is my billing from august/2021 to august/2022. The prices are in brazilian real (today R$ 1 = US$ 0.20).
This price is because my project has little traffic and stay inside of free tier.
Thank you. That is very helpful. There are many posts how to use Azure, AWS and so on but I always miss example pricing for hobby/small projects for a developer and I am not familiar with the pricing complexity of each cloud provider.
It's really complex, I don't understand 100% how pricing is calculated, because involve traffic to and from internet, storage, compute time, compute capacity, memory usage etc etc. What I already learned in the worst way is that database's cost can grow up fast 🤣
Most of the time I try on product and keep up checking my billing every day, when price grow fast I delete the project 🤷
Both Cloud Run and Cloud Build have a recurring free tier that is tied to your usage. You can check the pricing page:
Thanks for sharing !