How can I enable HTTPS in docker for my minimal API container

120 views Asked by At

I have already containerized my minimal api written in c# in docker and instead of accessing the api with http://localhost:7113, I want to enable https://localhost:7114 (over HTTPS).

I have already exported a selfsigned certificate ('MinimalApi.pfx') and placed in the root of my application.

I have used this command to make a selfsigned certificate and exporting the certificate in *.pfx format:

$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=MinimalApiRootCert" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign

In my appsettings.json I have allowed Urls for both http and https:

 {
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Urls": "http://*;https://*"
}

My dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["MinimalApi/MinimalApi.csproj", "MinimalApi/"]
RUN dotnet restore "MinimalApi/MinimalApi.csproj"
COPY . .
WORKDIR "/src/MinimalApi"
COPY ["MinimalApi/MinimalApi.pfx", "/etc/ssl/certs/"]
RUN dotnet build "MinimalApi.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./MinimalApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MinimalApi.dll"]

I am also copying my 'MinimalApi.pfx' into "/etc/ssl/certs/" in my dockerfile.

My docker-compose.yml file:

networks:
  default:
    ipam:
      driver: default
services:
  minimalapi-app:
    image: minimalapi-image
    ports:
      - '7113:7113'
      - '7114:7114'
    networks:
      - default
volumes:
  minimalapi-app:
    driver: local

However my docker container listens to port 8080 and only on HTTP. How can I enable HTTPS with my selfsigned certificate? Preferably on port '7114:7114' or '7114:443'?

I tried messing with a reversed proxy approach with Nginx, but I am really just looking for a simple solution with a selfsigned certificate only running locally on my machine.

1

There are 1 answers

2
datawookie On

You might find that using NGINX is the easiest approach. I don't claim to be an expert, but I think that something like this should work.

docker-compose.yml

version: "3"

services:
  nginx:
    container_name: nginx
    image: nginx
    ports:
      - "7113:80"
      - "7114:443"
    depends_on:
      - api
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./certificates:/etc/ssl/certs/self-signed
    networks:
      - default

  api:
    container_name: api
    build:
      context: .
    networks:
      - default

networks:
  default:
    ipam:
      driver: default

I've got self-signed certificates in certificates/. These are volume mounted to /etc/ssl/certs/self-signed on the NGINX container.

nginx.conf

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://api:8080/;
    }
}

server {
    listen 443;
    server_name localhost;

    ssl_certificate /etc/ssl/certs/self-signed/server.crt;
    ssl_certificate_key /etc/ssl/certs/self-signed/server.key;

    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://api:8080/;
    }
}

This configuration will look in etc/ssl/certs/self-signed/ for the certificates.

It will serve both HTTP and HTTPS separately. If you want to redirect HTTP to HTTPS then you'd use something like this:

server {
    listen 80;
    server_name localhost;

    return 301 https://$host$request_uri;
}
  • The API is listening on port 8080.
  • NGINX will proxy port 8080 to port 80 (for HTTP) and port 443 (for HTTPS).
  • Docker Compose will map port 80 to port 7113 (as specified in your question).
  • Docker Compose will map port 443 to port 7114 (as specified in your question).