I am trying to host a HTTPS Web API in a docker on ubuntu 22.04 VM. I am following the documentation as per : https://learn.microsoft.com/en-us/aspnet/core/security/docker-https?view=aspnetcore-8.0
Here is my docker-compose.yml
version: '3.6'
services:
docker-demo:
image:
webapi-docker-demo-https-jammy:v3
ports:
- 8081:8080
- 8082:8081
environment:
- Logging__LogLevel__Default=Debug
- Logging__Loglevel__Microsoft.AspNetCore=Debug
# - ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:8081;http://+:8080
- ASPNETCORE_HTTP_PORTS=8080
- ASPNETCORE_HTTPS_PORTS=8081
# - ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password= password
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/webapi-docker-demo.pfx
volumes:
- /home/.aspnet/https/webapi-docker-demo.pfx:/https/webapi-docker-demo.pfx:ro
On my host Ubuntu VM, I have pfx certificate in the folder
/home/.aspnet/https/webapi-docker-demo.pfx
My Dockerfile is
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
FROM mcr.microsoft.com/dotnet/sdk:8.0-jammy AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["webapi-docker-demo/webapi-docker-demo.csproj", "webapi-docker-demo/"]
RUN dotnet restore "./webapi-docker-demo/webapi-docker-demo.csproj"
COPY . .
WORKDIR "/src/webapi-docker-demo"
RUN dotnet build "./webapi-docker-demo.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./webapi-docker-demo.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
#ENV ASPNETCORE_URLS="https://+;http://+"
#ENV ASPNETCORE_HTTPS_PORT=8081
#ENV ASPNETCORE_Kestrel__Certificates__Default__Password="password"
#ENV ASPNETCORE_Kestrel__Certificates__Default__Path="https://webapi-docker-demo.pfx"
USER $APP_UID
ENTRYPOINT ["dotnet", "webapi-docker-demo.dll"]
When I run my docker compose file I am seeing the following error
dbug: Microsoft.Extensions.Hosting.Internal.Host[1]
docker-demo-1 | Hosting starting
docker-demo-1 | warn: Microsoft.AspNetCore.Hosting.Diagnostics[15]
docker-demo-1 | Overriding HTTP_PORTS '8080' and HTTPS_PORTS '8081'. Binding to values defined by URLS instead 'https://+:8081;http://+:8080'.
docker-demo-1 | fail: Microsoft.Extensions.Hosting.Internal.Host[11]
docker-demo-1 | Hosting failed to start
docker-demo-1 | System.UnauthorizedAccessException: Access to the path '/https/webapi-docker-demo.pfx' is denied.
docker-demo-1 | ---> System.IO.IOException: Permission denied
docker-demo-1 | --- End of inner exception stack trace ---
Full error text:
ubuntu@ubuntu2204-vm:~$ sudo docker compose -f webapi-docker-demo/docker-compose-https.yaml up
WARN[0000] /home/ubuntu/webapi-docker-demo/docker-compose-https.yaml: `version` is obsolete
[+] Running 1/1
✔ Container webapi-docker-demo-docker-demo-1 Recreated 0.2s
Attaching to docker-demo-1
docker-demo-1 | dbug: Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderFactory[12]
docker-demo-1 | Registered model binder providers, in the following order: Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ServicesModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.HeaderModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FloatingPointTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.EnumTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DateTimeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.SimpleTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.TryParseModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CancellationTokenModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ByteArrayModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormCollectionModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.KeyValuePairModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DictionaryModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ArrayModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CollectionModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinderProvider
docker-demo-1 | dbug: Microsoft.Extensions.Hosting.Internal.Host[1]
docker-demo-1 | Hosting starting
docker-demo-1 | warn: Microsoft.AspNetCore.Hosting.Diagnostics[15]
docker-demo-1 | Overriding HTTP_PORTS '8080' and HTTPS_PORTS '8081'. Binding to values defined by URLS instead 'https://+:8081;http://+:8080'.
docker-demo-1 | fail: Microsoft.Extensions.Hosting.Internal.Host[11]
docker-demo-1 | Hosting failed to start
docker-demo-1 | System.UnauthorizedAccessException: Access to the path '/https/webapi-docker-demo.pfx' is denied.
docker-demo-1 | ---> System.IO.IOException: Permission denied
docker-demo-1 | --- End of inner exception stack trace ---
docker-demo-1 | at Microsoft.Win32.SafeHandles.SafeFileHandle.Init(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Int64& fileLength, UnixFileMode& filePermissions)
docker-demo-1 | at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
docker-demo-1 | at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
docker-demo-1 | at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)
docker-demo-1 | at System.IO.File.ReadAllText(String path, Encoding encoding)
docker-demo-1 | at System.Security.Cryptography.X509Certificates.X509Certificate2Collection.ImportFromPemFile(String certPemFilePath)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Certificates.CertificateConfigLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.TlsConfigurationLoader.LoadDefaultCertificate(ConfigurationReader configurationReader)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Reload()
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadInternal()
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
docker-demo-1 | at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
docker-demo-1 | Unhandled exception. System.UnauthorizedAccessException: Access to the path '/https/webapi-docker-demo.pfx' is denied.
docker-demo-1 | ---> System.IO.IOException: Permission denied
docker-demo-1 | --- End of inner exception stack trace ---
docker-demo-1 | at Microsoft.Win32.SafeHandles.SafeFileHandle.Init(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Int64& fileLength, UnixFileMode& filePermissions)
docker-demo-1 | at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
docker-demo-1 | at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
docker-demo-1 | at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)
docker-demo-1 | at System.IO.File.ReadAllText(String path, Encoding encoding)
docker-demo-1 | at System.Security.Cryptography.X509Certificates.X509Certificate2Collection.ImportFromPemFile(String certPemFilePath)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Certificates.CertificateConfigLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.TlsConfigurationLoader.LoadDefaultCertificate(ConfigurationReader configurationReader)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Reload()
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadInternal()
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
docker-demo-1 | at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
docker-demo-1 | at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
docker-demo-1 | at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
docker-demo-1 | at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
docker-demo-1 | at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
docker-demo-1 | at webapi_docker_demo.Program.Main(String[] args) in /src/webapi-docker-demo/Program.cs:line 33
I tried giving read permission to others to my cert folder but I am still getting the error.
file permisions – readonly
Can someone tell me what I am doing incorrect here or direct me in the right direction.
Thanks
2
Answers
If you’re encountering permission issues with the .pfx file, consider overriding the Docker container’s default entrypoint with a shell for troubleshooting. You can adjust the docker-compose.yml or use docker-compose run with an interactive bash session to inspect and verify file permissions. Once inside the container, attempt to read the .pfx file with standard commands like cat to ensure it’s accessible and intact. This direct inspection can provide insights that help resolve the access denied error you’re encountering.
It is the path "inside the container". So what you need is make sure the Container inside user have the permission to access path.
You could change your Dockerfile like below it will work.