Site is served over https but not over http which cause letsencrypt to fail

I'm trying to set up some docker containers containing c# .net core api's to use https and certificates from Let's encrypt. I setup containers and when i try to go to route https://mydomain.rs/api1/WeatherForecast i get expected results and i see this request in logs.

When i try http://mydomain.rs/api1/WeatherForecast, result is 404 and request did not hit my container or even traefik container.

I suspect this behavior is reason for my certbot to fail with error Invalid response from http://mydomain.rs/.well-known/acme-challenge/2c_5O6sGZ9pegJ21vghKr1cW-sI0mt9Cq4hn0qFnbFo: 404

i have following docker-compose configuration:

version: '3.8'

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    command:
      - --entryPoints.web.address=:80
      - --entryPoints.websecure.address=:443
      - --entryPoints.dashboard.address=:9090  # Define dashboard entry point
      - --api.dashboard=true
      - --api.insecure=true
      - --providers.docker
      - --log.level=TRACE
      - --certificatesresolvers.myresolver.acme.httpChallenge.entryPoint=web
      - --certificatesresolvers.myresolver.acme.email=my@mail.rs
      - --certificatesresolvers.myresolver.acme.storage=/acme.json
      - --certificatesresolvers.myresolver.acme.httpChallenge=true
    labels:
      - "traefik.http.routers.acme-challenge.rule=PathPrefix(`/well-known/acme-challenge/`)"
      - "traefik.http.services.acme-challenge.loadbalancer.server.port=80"

    # Add an HTTP to HTTPS redirection rule
      - "traefik.http.routers.http-to-https.rule=Host(`mydomain.rs`)" # Match HTTP traffic
      - "traefik.http.routers.http-to-https.entryPoints=web"   # Listen on HTTP (port 80)
      - "traefik.http.routers.http-to-https.service=emptyService"  # Redirect, no backend service
      - "traefik.http.routers.http-to-https.middlewares=redirect-to-https"  # Middleware for redirection
      - "traefik.http.middlewares.redirect-to-https.redirectScheme.scheme=https"  # Redirect HTTP to HTTPS

    ports:
      - "80:80"
      - "443:443"
      - "9090:9090"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./acme.json:/acme.json
      - ./certs:/certs  # Store the certificates here
    networks:
      - web

  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certs/www/certbot:/var/www/certbot
      - ./certs:/etc/letsencrypt
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./certbot-logs:/var/log/letsencrypt  # Mount Certbot logs to the local path      
      - ./certbot-chalenges/.well-known/acme-challenge:/.well-known/acme-challenge/  # Mount Certbot logs to the local path      

    command: ["certonly", "--webroot", "--webroot-path=/var/www/certbot", "--email=my@mail.rs", "--agree-tos", "--no-eff-email", "-d mydomain.rs", "-v", "--staging"]
    networks:
      - web
    depends_on:
      - traefik
      # - nginx

  api1:
    build:
      context: ./DemoDockerAPI/DemoDockerAPI
      dockerfile: Dockerfile
    image: demo-docker-api
    container_name: demo-docker-api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api1.rule=Host(`mydomain.rs`) && PathPrefix(`/api1`)"
      - "traefik.http.routers.api1.entryPoints=web,websecure"
      - "traefik.http.services.api1.loadbalancer.server.port=8080"
      - "traefik.http.routers.api1.tls.certresolver=myresolver"
    networks:
      - web

  api2:
    build:
      context: ./DemoDockerAPI/DemoAnotherDockerApi
      dockerfile: Dockerfile
    image: demo-another-docker-api
    container_name: demo-another-docker-api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api2.rule=Host(`mydomain.rs`) && PathPrefix(`/api2`)"
      - "traefik.http.routers.api2.entryPoints=web,websecure"
      - "traefik.http.services.api2.loadbalancer.server.port=8080"
      - "traefik.http.routers.api2.tls.certresolver=myresolver"
    networks:
      - web

networks:
  web:
    name: web
    driver: bridge

What are you trying to do? Why use additional certbot? Why without any labels?

AFAIK Traefik will automatically create a special router for /.well-known/acme-challenge with high priority when using httpChallenge. Check Traefik Dashboard.

Why not simply switch to tlsChallenge for Traefik LetsEncrypt? Compare to simple Traefik example.

Why use emptyService? If it’s not defined, I am sure Traefik will show an error.

I'm at beginning of learning traefik and still trying to figure out how things work.
What i'm trying to do is to make Lets Encrypt certificates work with my .net core api's which run inside docker container. I managed to run this api's on http connection, but when i changed initial configuration file (which served http) to use https and self signed certificates, http ulrs stopped working and return only 404 without any registered requests in any logs.

Also, traefik dashboard for some reason won't show for me. When i access it, i get 404 error, also without any trace in any logs.

Remove the last line.

Think of the config as internal JSON. First you set

{ httpChallenge: { entryPoint: web }} 

and then overwrite it with

{ httpChallenge: true } 

It seems unclear what you want to do. You want Traefik to generate certs or certbot to generate certs?

Both is possible. Traefik is easiest used with tlsChallenge. A certbot instance should probably use httpChallenge when run behind Traefik. Note that the labels always need to go on the target service/container.

Traefik can also load certs from certbot.