Deploy a .Net Core API to Google Cloud Run


Learning how to Set up and deploy a .Net core API to Google Cloud Run seems daunting at first, but once you go through it you realize it's not too bad. I'll show you how to utilize docker containers, Cloud Build, and Cloud Run to get your API up and running in no time.
Setup for .Net Core API
In one of my previous posts I showed how to set up an Angular app to run in Cloud Run. The basic set up of the Cloud Run instance is the same, so if you need help getting your Cloud Run Service started, go here to check it out.
I also did a YouTube video talking about deploying to Cloud Run. This isn’t the exact same as this post, but pretty close. Check it out!
If you would like to jump straight to the code, you can view it in my Github. The code for this example is in a branch named 'deployCloudRun'.
Two of the main items you need to get Cloud Run and Cloud Build to work are a dockerfile and a cloudbuild.yaml file. The cloudbuild file is actually the exact same as what we used for our Angular app. That is one of the nice things about Cloud Build and utilizing docker. Cloud Build allows you to set parameters for properties specific to your build, and since we are using docker, all it cares about is that we are preparing a container. Here is the contents of the cloudbuild.yaml file.
Cloudbuild.yaml for our .Net Core API
Docker Setup
The dockerfile is what describes how our container is built. For a .Net app, the main parts of our docker file are:
- Copy the csproj files and do a ‘dotnet restore’
- Copy the rest of the files and run a ‘dotnet build’
- Tell the dotnet runtime how to run our app.
Here is the dockerfile that I’m using:
The dockerfile for our .Net core 6 API
Cloud Run Environment Variables
I like to set up my connection strings as environment variables. You can also set them up as a secret in GCP’s Secret Manager, but I’ll go over that in another post. When I set up my API’s context to use Postgres, this is how I do it:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(
Environment.GetEnvironmentVariable(
_config.GetValue<string>("EnvKeys:DbUserConn")));
}
Then in my appsettings.json file, I have a section called EnvKeys that has the name of the Environment Variable containing my connection string:
"EnvKeys": {
"DbUserConn": "TodoUserConnGCP"
}
When setting up the Revision for your Cloud Run instance, simply add an Environment variable with the name you use, in my case TodoUserConnGCP, with the value of the connection string:
One very important note that took me a while to figure out. When connecting to a Postgres instance on Cloud SQL from your local machine, the connection string is in the format:
Host=IPAddress;Port=5432;Database=dbName;Username=uName;Password=password
However when connecting from the deployed instance, it changes and uses the connection name from your Cloud Sql Overview page:
Server=/cloudsql/projectid:region:instance;Database=dbName;Uid=uName;Pwd=password
You will also need to set up the connection between Cloud Run and Cloud SQL on the Connections tab of the Revisions section. Select your database from the dropdown, and if necessary, enable the Cloud SQL Admin API.
You also want to set the ASPNETCORE_ENVIRONMENT variable. Whichever name you use here will correspond to the appsettings.json file with the same name. For example with Production it will use the appsettings.Production.json file.
Conclusion
With all that done you should be all set to go to Deploy a .Net Core API to Cloud Run. If you set up your Cloud Build to build on Github pushes like in my previous Angular post, pushing your code will trigger a build and you'll be all set.