Skip to content

Getting Started with ASP.NET

A live example is available at https://aspnet.nullstone.dev.

This quickstart launches an ASP.NET web application to AWS via Nullstone. It also configures a local development environment using Docker that works identical to production, but with debugging enabled.

This quickstart contains a walkthrough for generating an ASP.NET app. A working example is available to fork at nullstone-io/aspnet-quickstart.

TIP

This quickstart is based off the official ASP.NET Core get started tutorial.

Create ASP.NET app

Generate app

In this example, we are going to create an ASP.NET app named aspnet-quickstart in the current directory. In your repository root, run these commands.

shell
dotnet new webapp --no-https -o .
dotnet new gitignore
dotnet new webapp --no-https -o .
dotnet new gitignore

This will create the following files and directories:

shell
.
├── .vscode
├── Pages
├── Properties
├── wwwroot
├── .gitignore
├── appsettings.Development.json
├── appsettings.json
├── aspnet-quickstart.csproj
└── Program.cs
.
├── .vscode
├── Pages
├── Properties
├── wwwroot
├── .gitignore
├── appsettings.Development.json
├── appsettings.json
├── aspnet-quickstart.csproj
└── Program.cs

Prepare for Local

Configure docker locally

TIP

Nullstone provides a docker image nullstone/dotnet:local that is configured for local development. The source for the docker image is on GitHub at nullstone-io/docker-dotnet.

Create a docker-compose.yml to run locally using Docker.

yaml
version: '3.8'

services:
   db:
      image: mcr.microsoft.com/mssql/server
      environment:
         SA_PASSWORD: "Password1234%^&*"
         ACCEPT_EULA: "Y"
   app:
      image: nullstone/dotnet:local
      depends_on:
         - db
      environment:
         SQLSERVER_DSN: "Data Source=db;Initial Catalog=master;User ID=sa;Password=Password1234%^&*"
      ports:
         - "5001:5001"
      volumes:
         - .:/app
         - ~/.vsdbg:/remote_debugger:rw
version: '3.8'

services:
   db:
      image: mcr.microsoft.com/mssql/server
      environment:
         SA_PASSWORD: "Password1234%^&*"
         ACCEPT_EULA: "Y"
   app:
      image: nullstone/dotnet:local
      depends_on:
         - db
      environment:
         SQLSERVER_DSN: "Data Source=db;Initial Catalog=master;User ID=sa;Password=Password1234%^&*"
      ports:
         - "5001:5001"
      volumes:
         - .:/app
         - ~/.vsdbg:/remote_debugger:rw

Let's start our app locally.

shell
docker compose up
docker compose up

Visit http://localhost:5001.

Update dependencies

Add your dependencies with dotnet add .... Then, restart your docker container with docker compose up or docker compose restart. The local docker image will install dependencies on boot using dotnet restore.

Prepare for Production

Before deploying an ASP.NET app to production, we need to dockerize your app.

Create Dockerfile

Create Dockerfile with the following contents. This will build your app inside a build image and transfer the app into a production-optimized image.

WARNING

If you named your project differently, make sure to change CMD in the Dockerfile to reflect your project name.

docker
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build
WORKDIR /src
# Install packages
COPY *.csproj .
RUN dotnet restore
# Copy the rest of app and publish
COPY . .
RUN dotnet publish -c Release -o /app/publish --no-restore

FROM nullstone/dotnet
COPY --from=build /app/publish .
CMD ["dotnet", "aspnet-quickstart.dll"]
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build
WORKDIR /src
# Install packages
COPY *.csproj .
RUN dotnet restore
# Copy the rest of app and publish
COPY . .
RUN dotnet publish -c Release -o /app/publish --no-restore

FROM nullstone/dotnet
COPY --from=build /app/publish .
CMD ["dotnet", "aspnet-quickstart.dll"]

Launch to Nullstone

Create app

When launching to Nullstone, we're going to create an app in the Nullstone UI and attach capabilities that automatically configure our app. Follow these steps in the Nullstone UI.

  1. Create an application.
    • Name: In this example, we're naming our app aspnet-quickstart
    • Framework: c#
    • App Type: Container
  2. From the Domains tab for the application, add a subdomain. (This will automatically attach a load balancer capability)

Create sqlserver datastore

  1. Create a datastore - RDS SqlServer Cluster
  2. Visit your application created in the previous step.
  3. From the Datastores tab, add the datastore you just created.

Provision

Our application is ready to launch. Click "Launch" through the UI or issue up through the CLI.

shell
nullstone up --wait --app=aspnet-quickstart --env=dev
nullstone up --wait --app=aspnet-quickstart --env=dev

WARNING

The current SQL Server Access capability does not automatically set up and inject credentials.

In this quickstart, we are injecting the master db credentials manually.

In production, you should establish a user with specific permissions and inject that user's credentials.

To connect to the database in our app we need to add an environment variable with the database connection string.

  1. Login to your AWS console to find the master username and password. The name of the secret in the Secrets Manager will be named with the datastore reference followed by /master.
yaml
e.g. raspberry-herring-tnsqn/master
e.g. raspberry-herring-tnsqn/master
  1. Add the following environment variable to your application in Nullstone.
yaml
SQLSERVER_DSN
Data Source=`db_endpoint`;Initial Catalog=master;User ID=`username`;Password=`password`
SQLSERVER_DSN
Data Source=`db_endpoint`;Initial Catalog=master;User ID=`username`;Password=`password`

The db_endpoint value can be found on the configuration tab for the datastore under Module Outputs.

Build

Once your application is provisioned, you may build and deploy your app.

You can name your image whatever you want, just remember this image name for the deploy step. In this example, we are using an image name of aspnet-app.

shell
docker build -t aspnet-app .
docker build -t aspnet-app .

Deploy

Now, issue launch to push your docker image and deploy the service with a new version.

shell
nullstone launch --source=aspnet-app --app=aspnet-quickstart --env=dev
nullstone launch --source=aspnet-app --app=aspnet-quickstart --env=dev

Troubleshooting

Auto-versioning

When pushing your image, Nullstone performs auto-versioning if you are in a git-tracked directory. Nullstone selects the short commit SHA (a unique 8-character token) from the git repository to tag the docker image.

To use a manual version, issue launch with --version (this example uses 1.0.0).

shell
nullstone launch --source=aspnet-app --app=aspnet-quickstart --env=dev --version=1.0.0
nullstone launch --source=aspnet-app --app=aspnet-quickstart --env=dev --version=1.0.0

Version conflicts

Nullstone enforces version/image tag immutability for security reasons.

If you repeatedly push a new docker image without committing anything to git, you will receive an error message like this:

shell
error pushing artifact: error pushing image: tag invalid: The image tag 'c3c7cd83' already exists in the 'periwinkle-louse-fkslv' repository and cannot be overwritten because the repository is immutable.
error pushing artifact: error pushing image: tag invalid: The image tag 'c3c7cd83' already exists in the 'periwinkle-louse-fkslv' repository and cannot be overwritten because the repository is immutable.

The easiest way to resolve this is to launch with an indexed version. The following uses the same commit sha, but with a -2 suffix to distinguish the image tag.

shell
nullstone launch --source=aspnet-app --app=aspnet-quickstart --env=dev --version=c3c7cd83-2
nullstone launch --source=aspnet-app --app=aspnet-quickstart --env=dev --version=c3c7cd83-2