DEV Community

loading...

Dockerising .NET Core & Svelte

cainux profile image Cain Voong ・3 min read

The previous post covered how to set up a web application with a .NET Core backend and Svelte frontend.

In this post we'll package it up into a single Docker image ready to be deployed somewhere.

Prerequisites

Approach

We'll be taking advantage of Docker's multi-stage builds to:

  • build the frontend using Node
  • then the backend using .NET Core SDK
  • copy the results to an image containing only the ASP.NET Core runtime

Dockerfile

Create a file named Dockerfile. I usually do this with:

touch Dockerfile
Enter fullscreen mode Exit fullscreen mode

Frontend Build Stage

We'll start the file off with the below snippet. I've added comments to describe each step:

# Use Node.js 14, name this stage 'frontend'
FROM node:14 AS frontend

# Our working directory within the image
WORKDIR /build

# Copy package and lock files then install dependencies
COPY package.json .             
COPY package-lock.json .
RUN npm install

# Copy the rest of the files for the frontend
COPY rollup.config.js .
COPY svelte-app ./svelte-app

# Build - this'll output files to /build/wwwroot
RUN npm run build
Enter fullscreen mode Exit fullscreen mode

If you're wondering "why copy the package and lock files first?": it's so Docker creates and caches an intermediate layer containing your dependencies (in node_modules). This gets reused in subsequent builds if those files remain unchanged and saves having to redownload dependencies on each build.

Backend Build Stage

Now add:

# Use .NET Core SDK, name this stage 'backend'
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS backend
WORKDIR /build

# Copy the csproj file then install dependencies
COPY dotnet-svelte.csproj .
RUN dotnet restore dotnet-svelte.csproj

# Copy everything else
COPY . .

# Publish, and output the results to /publish
RUN dotnet publish -c Release -o /publish
Enter fullscreen mode Exit fullscreen mode

Similar to the frontend stage, we copy the csproj file first and restore dependencies to create an intermediate layer.

Combine the Results

We named our stages in the earlier snippets with AS frontend and AS backend. In our final stage we can reference the earlier stages and copy files from them. Add to the file:

# ASP.NET Core Runtime
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine

# Where our application will live
WORKDIR /app

# Copy the build results of the frontend stage
COPY --from=frontend /build/wwwroot ./wwwroot

# Copy the build results of the backend stage
COPY --from=backend /publish .

# Run our web application on startup (will listen on port 80 by default)
ENTRYPOINT /app/dotnet-svelte
Enter fullscreen mode Exit fullscreen mode

Final Dockerfile

Should look like this (comments omitted):

FROM node:14 AS frontend
WORKDIR /build
COPY package.json .             
COPY package-lock.json .
RUN npm install
COPY rollup.config.js .
COPY svelte-app ./svelte-app
RUN npm run build

FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS backend
WORKDIR /build
COPY dotnet-svelte.csproj .
RUN dotnet restore dotnet-svelte.csproj
COPY . .
RUN dotnet publish -c Release -o /publish

FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine
WORKDIR /app
COPY --from=frontend /build/wwwroot ./wwwroot
COPY --from=backend /publish .
ENTRYPOINT /app/dotnet-svelte
Enter fullscreen mode Exit fullscreen mode

Building & Running

Builds an image from the Dockerfile, and name it dotnet-svelte:

docker build -t dotnet-svelte .
Enter fullscreen mode Exit fullscreen mode

Then run with:

docker run --rm -p 5000:80 dotnet-svelte
Enter fullscreen mode Exit fullscreen mode
  • --rm tells docker to automatically remove the container once stopped
  • -p 5000:80 maps your local port 5000 to the container's port 80

Finally, browse to http://localhost:5000 and once again you will see:

xh38glfcl8lh8za52im9

Congratulations! You now have an image ready to be deployed somewhere.

Summary

This post was really more about Docker and multi-stage builds than anything else. We:

  • Used a Node image to build the Svelte application
  • Used a .NET Core SDK image to build the ASP.NET application
  • Copied the results of both to an ASP.NET runtime image

The resulting image contains only the parts we need: static files for the frontend, binary files for the backend and the runtime required to run it.

Discussion (2)

pic
Editor guide
Collapse
mileswatson profile image
Miles Watson

This is perfect timing! Perhaps you could cover deploying to AWS or a similar cloud provider?

Collapse
cainux profile image
Cain Voong Author

Hi Miles, Thanks for reading!

This is something that's probably covered a lot by others. For AWS I'd have a look at their documentation first: aws.amazon.com/getting-started/han...