Public Sector

We've had the pleasure of working with UK and overseas central and local government departments, including Healthcare (NHS and Foundation Trusts), Defence, Education (Universities and colleges), many of the main Civil Service departments, Emergency Services; also public-owned corporations including the BBC, Bank of England, Ordnance Survey, and regulatory bodies such as Ofgem.

We are registered on Crown Commercial Service’s (CCS) Dynamic Purchasing System (RM6219 Training and Learning) and also with numerous tender portals such as Ariba, Coupa and Delta E-Sourcing.

Read more...

Graduate Training Schemes

Framework Training has a strong track record of providing a solid introduction into the working world for technical graduates across myriad industries. We provide the opportunity to learn and gain valuable hands-on experience in a supportive, friendly and sociable training environment.

Attract & retain the brightest new starters

We know it is vital for our clients to invest in the future of their talented grads; not only to provide them with high-quality, professional training essential for their roles, but to embed them within the organisation’s culture and guide them on the right path to a successful career.

After all, your new hires could well be the next leaders and their creative ideas and unique insights are invaluable to your business.

Read more ...

Learning & Development

Our unique portfolio of high-quality technical courses and training programmes are industry-respected. They’re carefully designed so that delegates can seamlessly apply what they’ve learnt back in the workplace. Our team of domain experts, trainers, and support teams know our field — and all things tech — inside out, and we work hard to keep ourselves up to speed with the latest innovations. 

We’re proud to develop and deliver innovative learning solutions that actually work and make a tangible difference to your people and your business, driving through positive lasting change. Our training courses and programmes are human-centred. Everything we do is underpinned by our commitment to continuous improvement and learning and generally making things much better.

Read more...

Corporate & Volume Pricing

Whether you are looking to book multiple places on public scheduled courses (attended remotely or in our training centres in London) or planning private courses for a team within your organisation, we will be happy to discuss preferential pricing which maximise your staff education budget.

Enquire today about:

  • Training programme pricing models  

  • Multi-course voucher schemes

Read more...

Custom Learning Paths

We understand that your team training needs don't always fit into a "one size fits all" mould, and we're very happy to explore ways in which we can tailor a bespoke learning path to fit your learning needs.

Find out about how we can customise everything from short overviews, intensive workshops, and wider training programmes that give you coverage of the most relevant topics based on what your staff need to excel in their roles.

Read more...

Simplifying Docker with .NET 8

Create Docker images without a Dockerfile? Madness! Let's take a look at how to do it in .NET 8 - and why it's well worth it.

May 20th, 2024

.NET expert Wolfgang delves into one of the new features in .NET 8 - the ability to create Docker images without a Dockerfile. 

While this might seem like a minor change, it has significant implications for developers who prefer using the console for creating and building .NET applications. Whether you are a seasoned developer or a novice exploring the .NET ecosystem, this post will guide you through the nuances of this new feature, its potential use cases, and its impact on your development workflow.

So, let’s dive in and explore what .NET 8 has in store for us when working with containers.

Prerequisites

Before you start creating container images using dotnet publish, make sure you have the following tools installed:

  • .NET 8 SDK (While it is possible in .NET 7, it lacks support for certain parameters. Given its end-of-life status in November 2024, I suggest using .NET 8.)

  • Docker Desktop

Building a Sample Application and Docker Container with .NET 8 SDK

You can’t miss the rapid growth in systems labelled A|I over the last couple of years. Ai is everywhere now. But what programming languages are actually 

No matter what your platform is (Windows, Linux, or Mac), you can use the dotnet CLI to create a new .NET application. Let’s begin by creating a new API application with the following command:

dotnet new webapi -n DotNetContainerWithoutDocker

view rawCreateNewDotnetApp.ps1 hosted with ❤ by GitHub

This command creates a new web API application in a folder named DotNetContainerWithoutDocker. Navigate into the DotNetContainerWithoutDocker folder and run dotnet run to start the app.

cd .\DotNetContainerWithoutDocker\
dotnet run

view rawDotnetRun.ps1 hosted with ❤ by GitHub

You will see the console output that shows the API is running and the port it’s using. Don’t forget to append /weatherforecast to the endpoint when calling it via localhost to avoid an HTTP 404 error.

Screenshot of Powershell running a Docker port testTo create a Docker image using the .NET SDK, you first need to enable IsPublishable and EnableSdkContainerSupport in the .csproj file:

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <Nullable>enable</Nullable>
  <ImplicitUsings>enable</ImplicitUsings>
  <IsPublishable>true</IsPublishable>
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>

view rawEnablePublish.xml hosted with ❤ by GitHub

That’s all you need to set up the .NET SDK to create a Docker image from your .NET application. Let’s build the container image with the following command:

dotnet publish --os linux --arch x64 -p:PublishProfile=DefaultContainer -c Releases

view rawDotnetPublish.ps1 hosted with ❤ by GitHub

The parameters are the same ones you would use for a regular dotnet publish.

  • The --os linux and --arch x64 parameters target Linux with the x64 architecture.

  • -c Releases specifies the release configuration.

  • -p:PublishProfile=DefaultContainer tells MSBuild to create a container image. If you’re using a non-web application, like a console app, replace this parameter with /t:PublishContainer.

The image will have the same name as your project file (in lowercase).

Screenshot of Powershell window titled "Creating a Docker image with the project name"Additional Configuration Options

When running dotnet publish, you may encounter an error message if your project name is not a valid Docker tag. The tag must adhere to the following rules:

  • Be valid ASCII.

  • Contain lowercase and uppercase letters, digits, underscores, periods, and hyphens.

  • Not start with a period or hyphen.

  • Not exceed 128 characters in length.

To resolve this, add the ContainerRepository parameter to your .csproj file and set your preferred image name.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <Nullable>enable</Nullable>
  <ImplicitUsings>enable</ImplicitUsings>
  <IsPublishable>true</IsPublishable>
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
  <ContainerRepository>myNewImageName</ContainerRepository>
</PropertyGroup>

view rawAddContainerRepository.xml hosted with ❤ by GitHub

Save the file and rerun the dotnet publish command. The publishing process should now complete successfully, and the new image name will be displayed in the console.

Powershell screenshot - "Creating a Docker image with a customized name"If you have been following this demonstration, you should now have two Docker images: dotnetcontainerwithoutdocker and myNewImageName. Let’s initiate one of them using the docker run command and test if we can access the API.

docker run -p 12345:80 -it dotnetcontainerwithoutdocker

view rawDockerRun.ps1 hosted with ❤ by GitHub

After executing this command, the .NET application within the container should start. However, when you attempt to access it, you will encounter an HTTP 404 error.

PowerShell screenshot: "The container listens on port 8080"The HTTP 404 error is due to a change in .NET 8. The default port is now 8080, not 80. The console output also indicates Now listening on: http://[::]:8080 when the application starts. There are two ways to address this issue. The first is to simply change the port mapping in the docker run command from 80 to 8080.

The second option is to set the ASPNETCORE_HTTP_PORTS environment variable, which .NET applications read at startup and use if set. You can provide this environment variable when using docker run or you can add it to the .csproj file to have it included in the Docker image. To add it to the .csproj file, add the ContainerEnvironmentVariable parameter.

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.2" />
  <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  <ContainerEnvironmentVariable Include="ASPNETCORE_HTTP_PORTS" Value="22334" />
</ItemGroup>

view rawContainerEnvironmentVariable.xml hosted with ❤ by GitHub

The above code snippet configures the .NET application to listen at port 22334. Now let’s modify the docker run command to point to this port and test the application again. Don’t forget to run the dotnet publish command first, otherwise, you will use the old image that doesn’t have the added environment variable.

docker run -p 12345:22334 -it dotnetcontainerwithoutdocker

view rawDockerRun.ps1 hosted with ❤ by GitHub

PowerShell screenshot: Testing the port provided from the environment variableThe final parameter I want to discuss is the ContainerUser parameter, which can be used to configure the user that should run the container. Before .NET 8, all images ran by default under the root user. This is not ideal from a security perspective, and it’s recommended to use a non-root user to run the container. Since .NET 8, all images come with a non-root user named app. You can configure the user in the .csproj file with the ContainerUser parameter.

Use app as non-root user on Linux and ContainerUser on Windows.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <Nullable>enable</Nullable>
  <ImplicitUsings>enable</ImplicitUsings>
  <IsPublishable>true</IsPublishable>
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
  <ContainerRepository>myNewImageName</ContainerRepository>
  <ContainerUser>app</ContainerUser>
</PropertyGroup>

view rawContainerUser.xml hosted with ❤ by GitHub

If you try to use a user that doesn’t exist in the container, you will get an error message. For instance, I tried to use the user wolfgang, which doesn’t exist, and therefore, I was unable to publish the .NET application.

Conclusion

The ability of .NET 8 to create Docker images without a Dockerfile is indeed a remarkable technological advancement. However, I understand your perspective. If you are accustomed to using Visual Studio, which automatically generates the Dockerfile for you, and you run your tests within the Dockerfile along with everything else your application requires, this feature might not seem as appealing.

Nonetheless, it’s undeniable that this is a valuable addition to the .NET SDK’s capabilities. For those who use the console to create and build .NET applications and simply want to package a basic app in a container, this feature could be extremely useful. It’s all about finding the right tools and features that work best for your specific needs and workflow.


Would you like to know more?

If you're interested in containerisation and / or the latest and greatest .NET features, these instructor-led training courses might just be right up your street - all available for private / custom in-house and online delivery:

Share this post on:

We would love to hear from you

Get in touch

or call us on +44 (0) 20 3137 3920