Traeffic, Docker and Let's Encrypt - docker

Final stage before my website can finally go live --> SSL.
I'm using a Jekyll site, with Traefic as a reverse proxy, Docker to prevent "it works on my machine" and Let's Encrypt for SSL. Looking at the docs this should be a walk in the park, but (as everything in software development) it is harder then it seems.
My current Traefic configuration:
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
permanent = true
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "johanvergeer.com"
watch = true
exposedByDefault = true
usebindportip = true
swarmMode = true
[acme]
email = "johanvergeer#gmail.com"
storage = "acme.json"
entryPoint = "https"
acmeLogging = true
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
[[acme.domains]]
main = "johanvergeer.com"
[acme.httpChallenge]
entryPoint = "http"
provider = "digitalocean"
And the docker-compose file
version: "3.6"
services:
site:
ports:
- 4000:4000
image: registry.gitlab.com/johanvergeer/redgyro/site:latest
deploy:
labels:
- traefik.site.port=4000
- traefik.enable=true
- traefik.frontend.rule=Host:johanvergeer.com
- traefik.frontend.entryPoints=http,https
- traefik.docker.network=traefik-net
- traefik.backend.loadbalancer.method=drr
networks:
- traefik-net
reverse-proxy:
image: traefik # The official Traefik docker image
ports:
- "80:80" # The HTTP port
- "8080:8080" # The Web UI (enabled by --api)
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
- $PWD/traefik.toml:/etc/traefik/traefik.toml
- $PWD/acme.json:/etc/traefik/acme.json
deploy:
labels:
- traefik.site.port=80
- traefik.logLevel=DEBUG
- traefik.docker.network=traefik-net
- traefik.backend.loadbalancer.method=drr
placement:
constraints:
- node.role == manager
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
networks:
- traefik-net
networks:
traefik-net:
name: traefik-net
At this moment I don't even receive anything in the Traefic logs, while it is set on DEBUG.
The browser shows an error Your connection is not private and NET::ERR_CERT_AUTHORITY_INVALID.
Does anyone know how to solve this?

httpChallenge does not accept a provider param. You could try removing that.
If that doesn't work and you're running on DigitalOcean try doing a dnsChallenge instead of an httpChallenge. To do so modify your traefik.toml from this:
[acme.httpChallenge]
entryPoint = "http"
provider = "digitalocean"
To this:
[acme.dnsChallenge]
provider = "digitalocean"
delayBeforeCheck = 0
And pass in the DO_AUTH_TOKEN environment variable as specified here. If you anticipate adding subdomains later DNS challenge with wildcard domains is the way to go.
Also consider removing caServer from your config so you default to production in case you've hit the Let's Encrypto Rate Limit for staging.
You could also try asking for help on the Let's Encrypt Community Support forum if you haven't yet.

Related

Traefik websocket secure ( wss ) and https on the same domain with docker

I struggled on this for at least the last day and didn't found a solution. I want to connect Websocket and https on the same docker. I have tried many thing.
Here is my configuration:
Traefik V2 first :
here is the docker container
version: '3'
services:
reverse-proxy:
image: traefik:v2.7.1
container_name: traefik
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/traefik.toml:/etc/traefik/traefik.toml
- $PWD/acme.json:/acme.json
restart: always
networks:
- web
networks:
web:
external:
name: web
~
here is my toml file
[accessLog]
[api]
dashboard = true
insecure = true
[log]
level = 'ERROR'
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http]
[entryPoints.web.http.redirections]
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
permanent = true
[entryPoints.websecure]
address = ":443"
[entryPoints.websecure.http.tls]
certResolver = "default"
[entryPoints.wss]
address = ":8000"
[providers]
[providers.docker]
watch = true
exposedByDefault = false
network = "web"
[certificatesResolvers]
[certificatesResolvers.default]
[certificatesResolvers.default.acme]
email = "contact#queel.io"
storage = "acme.json"
caServer = "https://acme-v01.api.letsencrypt.org/directory"
[certificatesResolvers.default.acme.tlsChallenge]
I want to connect on https and wss on the same node container exposing two ports
here is my docker-compose for this
node:
build: ./docker/node_api
volumes:
- ./node:/src
tty: true
networks:
- web
ports:
- ":8000"
- ":8081"
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.http.routers.node.rule=Host(`api.${HOST}`)"
- "traefik.http.routers.node.entrypoints=websecure"
- "traefik.tcp.services.node.loadbalancer.server.port=8000"
- "traefik.http.routers.wss.rule=Host(`ws.${HOST}`)"
- "traefik.tcp.services.wss.loadbalancer.server.port=8081"
#- "traefik.http.services.wss.loadBalancer.sticky.cookie=true"
# - "traefik.http.routers.wss.tls=true"
#- "traefik.http.routers.wss.tls.certResolver=default"
#- "traefik.http.routers.wss.entrypoints=wss"
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
#- "traefik.http.routers.wss.tls.certresolver=default"
depends_on:
- elastic
- neo
working_dir: /src
Has you can see I tried many solutions, but none is working, maybe you should help me find the combination of the goog ones. It seems has I have seen elsewhere that the X-Forwarded-Proto is the solution. For new the wss connection is not working
Could you help me with that
The anwser is quite simple, my socket server was not started. The config stay the same for the main part and I have only to have :
- "traefik.http.routers.wss.rule=Host(`ws.${HOST}`)"
- "traefik.tcp.services.wss.loadbalancer.server.port=8081"
- "traefik.http.routers.wss.entrypoints=websecure"
entrypoint=websecure is enought for wss since it's over http.
I didn't manage to use the two service in a single container so i swapped the container in two container.

Why doesn't traefik find the project?

I have a laravel project running through docker containers. One of the docker containers is a traefik, but when I try to run the docker-compose up command, it returns a single log: msg="Failed to read new account, ACME data conversion is not available : permissions 755 for acme.json are too open, please use 600". I tried to change permissions for asme.json on my ssh, but even after chmod 600 acme.json it returns this log again. On top of that, when I try to connect to the site via https, there is an error 404 page not found, I got a similar error when I set up the nginx container, because I incorrectly specified the path to the project, but I don’t know what to do now. There are my
1)traefik.tom
logLevel = "ERROR"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[api]
[ping]
# Enable Docker configuration backend
[docker]
network = "nginx-proxy"
domain = "mysite"
watch = true
exposedByDefault = false
[acme]
email = "my#gmail.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
caServer = "https://acme-v02.api.letsencrypt.org/directory"
[acme.httpChallenge]
entryPoint = "http"
[acme.dnsChallenge]
provider = "cloudflare"
delayBeforeCheck = 0```
And 2) docker-compose.traefik.yml
---
version: "3.6"
networks:
default:
name: nginx-proxy
external: true
services:
traefik:
image: "traefik:v1.7.14"
container_name: ${COMPOSE_PROJECT_NAME}.traefik
restart: unless-stopped
ports:
- 80:80
- 443:443
expose:
# traefik dashboard port
- 8080
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=https"
- "traefik.http.routers.traefik.rule=Host(`mysite`)"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=cloudflare"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
- "traefik.port=8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./docker/traefik/traefik.toml:/etc/traefik/traefik.toml
- ./docker/traefik/:/acme.json
environment:
- CF_API_EMAIL=myapifemail
- CF_API_KEY=myapikey
based on what I see, you are using a volume to store the acme certificates as described here. But it seems you misread the volume binding and wrote
- ./docker/traefik/:/acme.json
instead of
- ./docker/traefik/acme.json:/acme.json
Doing so the folder is mounted as a file and end up with wrong permissions. Correcting the line should make it works.

Bad gateway on traefik docker

I build traefik with cloudflare CDN. I used docker container run command to execute my docker container execute by Drone CI. I have an issue when I successfully built docker container which leads to bad gateway on subdomain.
docker-compose.yml
version: '3'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: always
domainname: ${DOMAINNAME}
networks:
- traefik_proxy
ports:
- "80:80"
- "443:443"
- "8080:8080"
environment:
- CF_API_EMAIL=${CLOUDFLARE_EMAIL}
- CF_API_KEY=${CLOUDFLARE_API_KEY}
labels:
- "traefik.enable=true"
- "traefik.backend=traefik"
- "traefik.frontend.rule=Host:monitor.${DOMAINNAME}"
- "traefik.port=8080"
- "traefik.docker.network=traefik_proxy"
- "traefik.frontend.headers.SSLRedirect=true"
- "traefik.frontend.headers.STSSeconds=315360000"
- "traefik.frontend.headers.browserXSSFilter=true"
- "traefik.frontend.headers.contentTypeNosniff=true"
- "traefik.frontend.headers.forceSTSHeader=true"
- "traefik.frontend.headers.SSLHost=example.com"
- "traefik.frontend.headers.STSIncludeSubdomains=true"
- "traefik.frontend.headers.STSPreload=true"
- "traefik.frontend.headers.frameDeny=true"
- "traefik.frontend.auth.basic.users:${HTTP_USERNAME}:${HTTP_PASSWORD}"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/traefik:/etc/traefik
- /etc/docker/shared:/shared
networks:
traefik_proxy:
external:
name: traefik_proxy
Traefik.toml
nsecureSkipVerify = true
defaultEntryPoints = ["https", "http"]
# WEB interface of Traefik - it will show web page with overview of frontend and backend configurations
[api]
entryPoint = "traefik"
dashboard = true
address = ":8080"
# Force HTTPS
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
# Let's encrypt configuration
[acme]
email = "example#gmail.com" #any email id will work
storage="acme.json"
entryPoint = "https"
acmeLogging=true
onDemand = false #create certificate when container is created
[acme.dnsChallenge]
provider = "cloudflare"
delayBeforeCheck = 300
[[acme.domains]]
main = "example.com"
[[acme.domains]]
main = "*.example.com"
# Connection to docker host system (docker.sock)
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "example.com"
watch = true
# This will hide all docker containers that don't have explicitly
# set label to "enable"
exposedbydefault = false
Command I used to run the docker container execute by Drone:
docker container run -d --name example-development --restart=unless-
stopped --label "traefik.backend=example-development" --label
"traefik.frontend.rule=Host:subdomain.example.com" --label
"traefik.enable=false" --label "traefik.port=6611" --expose 6611
cloud.canister.io:5000/username/repo
My docker container is listening to http://127.0.0.1:6611
Above codes examples lead to Error 504 Gateway Timeout.
Traefik needs to have a common network with the containers it is connecting to. In this case, you need to run containers with --net=traefik_proxy.
If you're container is on multiple networks, you'll also need the label traefik.docker.network=traefik_proxy to tell traefik which of those networks to use.

Using a domain name without a subdomain causes routing to fail

I'm trying to create a simple app using traefik to handling routing and SSL, but I'm running into issues when I want to use 'example.com' instead of 'subdomain.example.com'
If I try to include a service with a frontend rule of just 'example.com' the only rule that works is 'monitor.example.com'. 'api.example.com' won't work and returns a 404. If I comment out the frontend rule for 'example.com' then 'api.example.com' works again. But, no matter what, 'monitor.example.com' works fine. Additionally, 'example.com' always returns a 404 no matter what as well.
Here's my docker-compose file:
version: '3'
services:
reverse-proxy:
image: traefik
restart: always
command: --docker
ports:
- 80:80
- 443:443
networks:
- web
labels:
- "traefik.frontend.rule=Host:monitor.example.com"
- "traefik.port=8080"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.backend=traefik"
environment:
- CLOUDFLARE_EMAIL=###
- CLOUDFLARE_API_KEY=###
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/project/traefik/traefik.toml:/traefik.toml
- /home/project/traefik/acme.json:/acme.json
container_name: traefik
api:
image: api
expose:
- 5080
restart: always
networks:
- web
container_name: api
labels:
- "traefik.frontend.rule=Host:api.example.com"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.port=5080"
- "traefik.backend=api"
app:
image: app
restart: always
networks:
- web
container_name: app
labels:
- "traefik.frontend.rule=Host:example.com"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.backend=app"
- "traefik.port=80"
networks:
web:
external: true
And here's my traefik configuration:
defaultEntryPoints = ["https", "http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[entryPoints.trdash]
address = ":8080"
[entryPoints.trdash.auth]
[entryPoints.trdash.auth.basic]
users = [
"admin:###",
]
[api]
entryPoint = "trdash"
[acme]
email = "###"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
onDemand = false
[[acme.domains]]
main = "example.com"
[[acme.domains]]
main = "*.example.com"
[acme.dnsChallenge]
provider = "cloudflare"
Any help would be appreciated, thanks!
EDIT:
Okay, I seem to have solved my own problem by disabling the 'orange cloud' on the domains I'm using on Cloudflare. Additionally I had to remove my http to https redirect rules inside of the traefik.toml file. I don't understand why this is a problem, so I'm going to leave the question open. This really seems to negate much of the value which Cloudflare provides.
It turns out the issue was enabling the Cloudflare proxy (orange cloud) without enabling the backend SSL. So long as I have SSL certs on the server (which I do via Let's Encrypt) I can turn Cloudflare SSL to 'Full (strict)' and it appears that the routing works fine now.
Thanks to Daniel Tomcej on the Traefik Slack for helping me find this answer.

Traefik + Nextcloud results in bad gateway

I have 3 services up and running.
A mariadb & nextcloud instance:
version: '2.1'
volumes:
nextcloud:
db:
services:
db:
image: mariadb
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=my_root_password
- MYSQL_PASSWORD=my_password
- MYSQL_DATABASE=my_database
- MYSQL_USER=my_user
app:
image: nextcloud
restart: always
networks:
- web
- default
ports:
- 9000
labels:
- "traefik.backend=app"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:my_host"
- "traefik.enable=true"
- "traefik.port=9000"
- "traefik.default.protocol=http"
networks:
web:
external: true
And a traefik service:
version: '2'
services:
traefik:
image: traefik:1.5.4
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.toml:/traefik.toml
- /opt/traefik/acme.json:/acme.json
container_name: traefik
networks:
web:
external: true
This traefik instance is using this config file:
debug = false
logLevel = "ERROR"
defaultEntryPoints = ["https","http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "my_host"
watch = true
exposedByDefault = false
[acme]
email = "my_email"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"
Now when I goto my host, it redirects to HTTPS but then it just displays bad gateway and nothing else. It should display the nextcloud web application. Anyone know why this is happening? I am running the compose files using the docker-compose up -d command.
It might be too late now but I also ran into this issue myself, so posting an answer to what resolved it for me.
Nextcloud exposes port 80 on the container's IP address which Traefik is trying to connect to. So you incorrectly specified the port for 'traefik.port' label. Change it from 9000 to 80.

Resources