In an empty folder (eg, hello_world
), run the following:
dotnet new web
dotnet add package Nancy --version 2.0.0-clinteastwood
dotnet add package Microsoft.AspNetCore.Owin
Why 2.0.0-clinteastwood? The latest Nancy module is incompatible with the .NET core ecosystem (at present), which will hopefully be resolved in a future release.
If you encounter conflict errors running dotnet restore
, you may need to add the following:
dotnet add package Microsoft.AspNetCore.Http
dotnet add package Microsoft.AspNetCore.Http.Abstractions
dotnet add package Microsoft.AspNetCore.Http.Features
dotnet add package Microsoft.AspNetCore.WebUtilities
dotnet add package Microsoft.Extensions.DependencyInjection.Abstractions
dotnet add package Microsoft.Extensions.ObjectPool
dotnet add package Microsoft.Extensions.Options
dotnet add package Microsoft.Extensions.Primitives
dotnet add package Microsoft.Net.Http.Headers
Helpful other libraries:
dotnet add package FaunaDB.Client --version 2.5.0
Modify Startup.cs
to look like the following:
...
using Nancy.Owin;
namespace hello_world {
public class Startup {
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
// Development Errors
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
// Use Nancy via Owin
// Not working? Make sure you've imported Nancy.Owin as above.
app.UseOwin(b => b.UseNancy());
}
}
}
Modify Program.cs
to look like the following:
namespace hello_world {
public class Program {
public static void Main(string[] args) {
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) {
// Use port settings expected by Google Cloud Run
string port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
string url = String.Concat("http://0.0.0.0:", port);
// Return WebHostBuilder
return WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().UseUrls(url);
}
}
}
Finally, create a default route class under api\MainModule.cs
(note: location or name don't actually matter, anything works as long as your classes inherit NancyModule
)
using Nancy;
namespace hello_world {
public class MainModule : NancyModule {
public MainModule() {
Get("/", args => "Hello World, it's Nancy on .NET Core");
}
}
}
In the root directory of your project, run
dotnet run
to compile and run your application. It should be visible at http://localhost:8080/
Create a Dockerfile
at root level with the following:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
# IMPORTANT!
# Remember to update 'hello_world' below to the name of your app.
ENTRYPOINT ["dotnet", "hello_world.dll"]
and a .dockerignore
with the following:
Dockerfile
**/obj/
**/bin/
In the root directory of your project, run the following to build your application image.
docker build -t hello_world .
if you run into errors with dotnet restore
within the docker build, try:
docker build --network=host -t backend .
Once completed, run
docker run -d -p 8080:8080 --name hw_demo hello_world
to test your image inside a container. It should be visible at http://localhost:8080/. Once you are done, be sure to clear up the container with:
docker kill hw_demo
In the root directory of your project, run
gcloud builds submit --tag gcr.io/PROJECT-ID/hello_world
Note that PROJECT-ID
is the name of your GCP project that you are deploying to. Make sure that you have enabled Google Cloud Run and Container Registry.
To deploy:
gcloud beta run deploy --image gcr.io/PROJECT-ID/hello_world --platform managed
Be sure to choose us-central1
as your region (for now), and choose y
when allowing unauthenticated invocations if you are building an external API.
TBC.