I am trying to setup a certificate for a locally running react app on a virtual host local.example.com. This has to just work locally on docker setup. After going through some articles, I came up with this docker-compose.yml:
version: "3"
services:
mongo:
image: mongo
restart: always
ports:
- "27017:27017"
volumes:
- mongodbdata:/data/db
networks:
- proxy
mongo-express:
image: mongo-express
restart: always
ports:
- "8081:8081"
networks:
- proxy
react:
build:
context: ./client
dockerfile: ./Dockerfile
ports:
- "3001:3001"
stdin_open: true
volumes:
- ./client:/client
- /client/node_modules
labels:
# this enables traefik for your service
- "traefik.enable=true"
# this defines the url, traefik will get the ssl certificate for
- "traefik.http.routers.myapplication.rule=Host(`local.example.com`)"
# this tells traefik to use https to access the website
- "traefik.http.routers.myapplication.entrypoints=websecure"
# this tells traefik to use the certresolver, that we defined above for resolving tls (in our case letsencrypt)
- "traefik.http.routers.myapplication.tls.certresolver=myresolver"
# this let's us forward the port we set above. Change this to the port you expose in your application (3000, 4000, ...) or remove the line, if your application already exposes port 80/443
- "traefik.http.services.myapplication.loadbalancer.server.port=3000"
depends_on:
- "server"
networks:
- proxy
server:
build:
context: ./server
dockerfile: ./Dockerfile
ports:
- "5001:5001"
volumes:
- traefik.toml:/traefik.toml
- acme.json:/acme.json
- ./server:/server
- /server/node_modules
labels:
# this enables traefik for your service
- "traefik.enable=true"
# this defines the url, traefik will get the ssl certificate for
- "traefik.http.routers.myapplication.rule=Host(`local.example.com`)"
# this tells traefik to use https to access the website
- "traefik.http.routers.myapplication.entrypoints=websecure"
# this tells traefik to use the certresolver, that we defined above for resolving tls (in our case letsencrypt)
- "traefik.http.routers.myapplication.tls.certresolver=myresolver"
# this let's us forward the port we set above. Change this to the port you expose in your application (3000, 4000, ...) or remove the line, if your application already exposes port 80/443
- "traefik.http.services.myapplication.loadbalancer.server.port=5001"
depends_on:
- "mongo"
networks:
- proxy
whoami:
image: "containous/whoami"
container_name: "myapplication"
restart: unless-stopped
ports:
- "4000:4000"
networks:
- proxy
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
# this can be uncommented to get more information, in case something doesn't work
- "--log.level=DEBUG"
# set this to true to get access to the traefik web interface unter http://YOURIP:8080
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # uncomment this line to only test ssl generation first (to make sure you don't run into letsencrypt limits)
- "--certificatesresolvers.myresolver.acme.email=kamlekar.venkatesh@gmail.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080" # this is used for the web interface, that let's you check and monitor traefik and your configuration. It's very nice for debugging your config - only available if "api.insecure" above is set to true
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- proxy
# The following is only necessary if you want to enforce https!
# if you don't need that, you can just remove the labels here
labels:
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
networks:
proxy:
external: true
volumes:
mongodbdata:
traefik.toml:
acme.json:
On doing docker-compose up, I am seeing the following error in traefik service. Also, though the react app service is running in docker but I hit https://local.example.com:3001, is unreachable
time="2022-01-23T08:30:52Z" level=error msg="Unable to obtain ACME certificate for domains "local.example.com": unable to generate a certificate for the domains [local.example.com]: error: one or more domains had a problem:\n[local.example.com] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: NXDOMAIN looking up A for local.example.com - check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for local.example.com - check that a DNS record exists for this domain, url: \n" providerName=myresolver.acme routerName=myapplication@docker rule="Host(
local.example.com)"
Here are the research notes which I tried till now (These notes for only my personal understanding so could be not in detail)
You can start from this fiddle: https://github.com/kamlekar/react-docker-ssl-virtualhost