I am using traefik as reverse proxy for cryptpad. Traefik is running in a docker container. I used this docs to solve this issue: https://github.com/xwiki-labs/cryptpad/wiki/Docker-(with-Nginx-and-Traefik)#configuring-traefik
That's what I did:
$ mkdir traefik && cd traefik
$ wget https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml
$ mv traefik.sample.toml traefik.toml
$ touch acme.json && chmod 600 acme.json
I added this to traefik.toml:
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[acme]
email = "me#example.org"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"
Created docker-compose.yml
version: '3'
services:
traefik:
image: traefik
command: --docker
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik/traefik.toml:/traefik.toml
- ./traefik/acme.json:/acme.json
ports:
- 80:80
- 443:443
networks:
- proxy
container_name: traefik
networks:
proxy:
external: true
And created/started traefik with docker-compose up -dll .
Well - for http it works fine so far - but I am not being redirected to https. And if I would, the connection would be reset (https://cryptpad.mydomain.org -> connection refused).
I checked if something is listening for http/https:
tcp LISTEN 0 128 :::http :::*
tcp LISTEN 0 128 :::https :::*
And tried to telnet it:
[root#cryptpad ~]# telnet localhost 443
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
What did I miss?
Related
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.
I have two services as shown below:
version: '3'
services:
# reverse proxy
traefik:
image: traefik:1.7-alpine
ports:
- 8080:8080 # Access through port 8080 e.g. localhost:8080 -> traefik dashboard
- 9000:80 # Access through port 9000 e.g. localhost:9000 -> actual service (flask and any others)
- 9001:80 # Access through port 9001 e.g. localhost:9001 -> actual service (flask and any others)
- 443:443 # Access through port 443 e.g. localhost:443 -> unused until we get https going
networks:
- traefik
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# - ./acme.json:/acme.json # ignored for production version
# - ./traefik.toml:/traefik.toml # ignored for production version
container_name: traefik
command: --docker --api --docker.domain=local.docker
restart: unless-stopped
# flask app 1
flaskapp1:
# build the Dockerfile
build:
context: ./flaskapp1
dockerfile: Dockerfile
container_name: flaskapp1
restart: always
command: >
gunicorn -b 0.0.0.0:5000
--access-logfile -
--timeout=1200
--reload
"flaskapp1.app:create_app()"
volumes:
- '.:/flaskapp1'
networks:
- traefik
# exposing a port to the other services (note, this is not publishing the port to the world)
expose: ['5000']
# these labels override the traefik configure file so we can setup traefik here, and not deal with a .toml file
labels:
- traefik.enable=true
- traefik.backend=flaskapp1
- traefik.docker.network=traefik
- traefik.frontend.rule=Host:localhost
- traefik.flaskapp1.port=5000
# flask app 2
flaskapp2:
# build the Dockerfile
build:
context: ./flaskapp2
dockerfile: Dockerfile
container_name: flaskapp2
restart: always
command: >
gunicorn -b 0.0.0.0:5000
--access-logfile -
--timeout=600
--reload
"hairByElli.app:create_app()"
volumes:
- '.:/flaskapp2'
networks:
- traefik
# exposing a port to the other docker services (note, this is not publishing the port to the world)
expose: ['5000']
# these labels override the traefik config file so we can setup traefik here, and not deal with a .toml file
labels:
- traefik.enable=true
- traefik.backend=flaskapp2
- traefik.docker.network=traefik
- traefik.frontend.rule=Host:localhost:9001
# - traefik.frontend.rule=Host:localhost;PathPrefixStrip:/app2
- traefik.flaskapp2.port=5000
networks:
traefik:
external: false
As you can see, this is my localhost testing machine. Ubuntu 18.04. So I'm currently trying to get to localhost:9000 and localhost:9001 as my entry points whilst I get this working properly.
My flaskapp1 works perfectly. My flaskapp2 is giving a 404 error.
Here is my toml:
defaultEntryPoints = ["http", "https"]
logLevel = "error"
debug = false
# WEB interface of Traefik - it will show web page with overview of frontend and backend configurations
[api]
dashboard = false
address = ":8080"
# Connection to docker host system (docker.sock)
[docker]
domain = "local.docker"
watch = true
# This will hide all docker containers that don't have explicitly
# set label to "enable"
exposedbydefault = false
# Force HTTPS
[entryPoints]
[entryPoints.http]
address = ":9000"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.http]
address = ":9001"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
What am I doing wrong here? I mean, I don't mind if it comes in at 9000 / 9001 or some other entry point. It's just so I can test them on the same machine until going live. At which point I'll have separate domains pointing to them.
Any help would be greatly appreciated.
My PC is a Windows 10 PRO with Docker Desktop CE Version 2.0.0.3 (31259) (Engine 18.09.2).
I'm building a docker-compose.yml file which runs Traefik, Portainer, GitLab, Jenkins and Registry containers.
Traefik is configured with SSL (self-signed certificate).
I've achieved to run the containers in their domains:
Traefik: https://traefik.localhost
Portainer: https://portainer.localhost
Gitlab: https://gitlab.localhost
Jenkins: https://jenkins.localhost
Registry: https://registry.localhost
When I run these URLs in a browser it returns me certificate error but I access web clients without problems.
If I access the URL https://registry.localhost/v2/_catalog from the browser I can read: {"repositories":[]} This is good. I just started my Registry and it's empty.
I generated the self-signed certificate with:
"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" req -x509 -nodes -days 365 -newkey rsa:2048 -keyout traefik.key -out traefik.crt
I attach the configuration files. I omit part of the docker-compose.yml for short.
docker-compose.yml
version: '3.7'
services:
traefik:
image: traefik
container_name: traefik
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- D:\docker-vols\paas\traefik\traefik.toml:/traefik.toml
- D:\docker-vols\paas\traefik\certs:/certs/
labels:
traefik.enable: true
traefik.frontend.rule: "Host:traefik.localhost"
traefik.port: 8080
# Escapar $ con otro $
traefik.frontend.auth.basic: "root:$$apr1$$3sEZB9aF$$y8ii5P4E8/KAhCiyQoS8I0"
# portainer:
# ...
# gitlab:
# ...
# jenkins:
# ...
registry:
image: registry:2
container_name: registry
volumes:
- D:\docker-vols\paas\registry\registry:/var/lib/registry
labels:
traefik.enable: true
traefik.frontend.rule: "Host:registry.localhost"
traefik.port: 5000
traefik.toml
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "/certs/traefik.crt"
keyFile = "/certs/traefik.key"
[api]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "docker.localhost"
watch = true
exposedbydefault = false
I run it: docker-compose up
My problem comes when I want to push an image to my Registry from the host (my Windows PC) to test that it works perfectly. I follow the next steps:
docker pull hello-world
docker tag hello-world registry.localhost/my-hello-world
docker push registry.localhost/my-hello-world
Then it returns
The push refers to repository [registry.localhost/my-hello-world]
Get https://registry.localhost/v2/: dial tcp: lookup registry.localhost on 192.168.65.1:53: no such host
Where's my mistake? Thank you.
SOLUTION:
I forgot to add to /etc/hosts:
127.0.0.1 registry.localhost
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.
When using Traefik and Docker-compose, I would like to get the container IP to perform IP-based filtering but instead get the docker network gateway IP.
Here is the results of a curl request from the curl-client container:
docker-compose exec curl-client curl https://whoami.domain.name
Hostname: 608f3dcaf7d9
IP: 127.0.0.1
IP: 172.18.0.2
GET / HTTP/1.1
Host: whoami.domain.name
User-Agent: curl/7.58.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.domain.name
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: 88756553599b
X-Real-Ip: 172.18.0.1
Here, 172.18.0.1 is the gateway for the traefik_net network. Instead, I would expect to see 172.18.0.9 in the X-Forwarded-For field, as it is the IP of the curl-client container:
docker-compose exec curl-client cat /etc/hosts
172.18.0.9 34f7b6e5472f
I've also tried using the 'traefik.frontend.whiteList.useXForwardedFor=true' option without success.
traefik.toml
logLevel = "ERROR"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.dashboard]
address = ":8080"
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[api]
entrypoint="dashboard"
[acme]
email = "something#aaa.com"
storage = "acme.json"
entryPoint = "https"
[acme.dnsChallenge]
provider = "ovh"
delayBeforeCheck = 0
[[acme.domains]]
main = "*.domain.name"
[docker]
domain = "domain.name"
watch = true
network = "traefik_net"
docker-compose.yml
version: '3'
services:
traefik_proxy:
image: traefik:alpine
container_name: traefik
networks:
- traefik_net
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
- ./acme.json:/acme.json
restart: unless-stopped
environment:
- OVH_ENDPOINT=ovh-eu
- OVH_APPLICATION_KEY=secretsecret
- OVH_APPLICATION_SECRET=secretsecret
- OVH_CONSUMER_KEY=secretsecret
labels:
- 'traefik.frontend.rule=Host:traefik.domain.name'
- 'traefik.port=8080'
- 'traefik.backend=traefik'
whoami:
image: containous/whoami
container_name: whoami
networks:
- traefik_net
labels:
- 'traefik.frontend.rule=Host:whoami.domain.name'
curl-client:
image: ubuntu
networks:
- traefik_net
command: sleep infinity
networks:
traefik_net:
external: true
Edit: The domain name is resolved using the following dnsmasq.conf:
domain-needed
expand-hosts
bogus-priv
interface=eno1
domain=domain.name
cache-size=1024
listen-address=127.0.0.1
bind-interfaces
dhcp-range=10.0.10.10,10.0.10.100,24h
dhcp-option=3,10.0.10.1
dhcp-authoritative
server=208.67.222.222
server=208.67.220.220
address=/domain.name/10.0.10.3
After some investigation it seems that Traefik is not the problem here, the inability to access the container IP is due to the way Docker manages its internal network (see the following comments: https://github.com/containous/traefik/issues/4352 and https://github.com/docker/for-mac/issues/180).
I was able to achieve my goal of whitelisting internal connections by running my openvpn container in nework_host mode, this way the client is assigned an IP by the system directly.
Setting the ports configuration of the docker-compose file as follows should work:
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
This ports capability is only available for docker-compose file format =>3.2