When serving a website from a docker container, we usually create a multi staged Dockerfile using nginx as our web server. The Dockerfile probably looks something like this:

... left out for brevity...

FROM nginx:alpine AS deploy
WORKDIR /usr/share/nginx/html
COPY --from=build /app/dist .
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80 443

If your frontend application ever need to use environment variables passed into your docker container during runtime, you'll probably googled your way to several solutions suggesting that envsubst might help you out.

... left out for brevity...

FROM nginx:alpine AS deploy
WORKDIR /usr/share/nginx/html
COPY --from=build /app/dist .
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80 443

CMD ["/bin/bash",  "-c",  "envsubst < /usr/share/nginx/html/env.template.js > /usr/share/nginx/html/env.js && exec nginx -g 'daemon off;'"]

But, what if you want to swap out nginx and serve your frontend app using ASP.NET Core's web server, Kestrel?

Execute envsubst when running a ASP.NET Core containarized application

Initally our Dockerfile used the mcr.microsoft.com/dotnet/aspnet:7.0 as our runtime base image.

FROM mcr.microsoft.com/dotnet/sdk:7.0 as build-env
WORKDIR /app

# steps to build the application
# is left out..

FROM mcr.microsoft.com/dotnet/aspnet:7.0 as runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MyExecutingAssembly.dll"]

What happens if we just replace the ENTRYPOINT with

CMD ["/bin/sh",  "-c",  "envsubst < /some-path/env.template.js > /some-other-path/env.js && exec nginx -g 'daemon off;'"]

You're obviously able to build the image, but will fail when you try to run a container with this image

/bin/bash: line 1: envsubst: command not found

Okay, that makes sense given that the image we're using mcr.microsoft.com/dotnet/aspnet:7.0 doesnt support envsubst.

The solution to this problem is to replace the base image with the alpine version, in our case mcr.microsoft.com/dotnet/aspnet:7.0.2-alpine3.17-amd64.

The entrypoint for the container will now look something like this:

CMD ["/bin/sh", "-c", "apk add gettext && envsubst < /some-path/env.template.js > /some-path/env.js && dotnet MyExecutingAssembly.dll"]


Using envsubst is a powerful way to read environment variables passed into a docker container and replace the values served as a javascript file. This articled showed how we can use this command when serving our frontend as static files from ASP.NET Cores web server Kestrel.