Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run .NET Core 2 application in Docker on Linux as non-root

I'm successfully running a simple dotnet core 2.1 web API application in docker but want to run it under a custom account instead of under root as this is supposedly best practice.

I can add an account and change to that account, but then Kestral throws an error on startup.

I've searched the web repeatedly and can't find any solutions.

Here's the Docker file.

FROM sel-docker.artifactory.metro.ad.selinc.com/microsoft/dotnet:2.1.500-sdk-    
alpine3.7 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 sel-docker.artifactory.metro.ad.selinc.com/microsoft/dotnet:2.1.6- 
aspnetcore-runtime-alpine3.7

# Create a group and user
RUN addgroup -S -g 1000 customgroup \
&& adduser -S -u 1000 -G customgroup -s /bin/sh customuser

WORKDIR /app
RUN mkdir -p /local/
COPY --from=build-env /app/out .

RUN chown customuser:customgroup /local
RUN chown customuser:customgroup /app

# Tell docker that all future commands should run as the appuser user
USER 1000
ENTRYPOINT ["dotnet", "ConfigApi.dll"]

And here is the Kestral error when I run the resultant image.

crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.Net.Sockets.SocketException (13): Permission denied
...

Has anyone solved this?

like image 659
David L. Sargent Avatar asked Nov 29 '18 17:11

David L. Sargent


4 Answers

Because this gets so much traffic, I'm adding the fully detailed code that you need to get this done.

# Create a group and user so we are not running our container and application as root and thus user 0 which is a security issue.
RUN addgroup --system --gid 1000 customgroup \
    && adduser --system --uid 1000 --ingroup customgroup --shell /bin/sh customuser
  
# Serve on port 8080, we cannot serve on port 80 with a custom user that is not root.
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
  
# Tell docker that all future commands should run as the appuser user, must use the user number
USER 1000
like image 197
David L. Sargent Avatar answered Nov 15 '22 14:11

David L. Sargent


To enable ASP.NET core to bind to a higher port, I set this environment variable in my dockerfile

ENV ASPNETCORE_URLS=http://*:8080

Sources: https://github.com/dotnet/aspnetcore/issues/4699#issuecomment-454818058

like image 34
nedstark179 Avatar answered Nov 15 '22 16:11

nedstark179


In linux, binding to a port less than 1024 requires the user to be superuser. You can just use the default port 5000 and then publish to port 80 on your host (if you don't have any reverse proxy).

like image 11
Siyu Avatar answered Nov 15 '22 15:11

Siyu


Has anyone got this working. I have tired this as well with using port 5000 and still haven't been able to get this working with a custom user

like image 3
jmsahearn Avatar answered Nov 15 '22 14:11

jmsahearn