I'm setting up a docker swarm and try to get working traefik reverse and portainer+agent on docker manager. But the container isnt public available.
I'm new to docker and reverse proxys so i dont tried more than the code showing up.
Starting with:
docker stack deploy -c stack.yml stack0
stack.yml
version: "3.3"
services:
traefik:
image: traefik
command: --docker.swarmmode
networks:
- traefik-net
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefikdata:/etc/traefik
deploy:
placement:
constraints: [node.role==manager]
portainer-agent:
image: portainer/agent
environment:
AGENT_CLISTER_ADDR: tasks.agent
AGENT_PORT: 9001
LOG_LEVEL: debug
ports:
- target: 9001
published: 9001
protocol: tcp
mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks:
- portainer-agent_network
- traefik-net
deploy:
mode: global
placement:
constraints: [node.platform.os == linux]
portainer:
image: portainer/portainer
command: -H tcp://tasks.agent:9001 --tlsskipverify
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "./portainerdata:/data"
networks:
- portainer-agent_network
- traefik-net
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
labels:
- "traefik.enable=true"
- "traefik.port=9000"
- "traefik.docker.network=stack0_traefik-net"
- "traefik.frontend.rule=Host:portainer.intern.domain.tld"
networks:
traefik-net:
portainer-agent_network:
driver: overlay
attachable: true
traefikdata/traefik.toml
logLevel = "INFO"
defaultEntryPoints = ["http", "https"]
[web]
address = ":8080"
[docker]
domain = "traefik.intern.domain.tld"
watch = true
exposedbydefault = false
# 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="network#techgods.biz"
storage="/etc/traefik/acme/acme.json"
entryPoint="https"
acmeLogging=true
OnHostRule=true
[acme.httpChallenge]
entryPoint = "http"
I expect a running Traefik reverse Proxy, UI reachable over traefik.intern.domain.tld and portainer reachable over portainer.intern.domain.tld
For complete explicitness, I would also put the entryPoints definition:
- "traefik.frontend.entryPoints=https"
Are you positive that this part is correct?
- "traefik.docker.network=stack0_traefik-net"
It doesn't seem to align with your network definitions:
networks:
traefik-net:
portainer-agent_network:
driver: overlay
attachable: true
I'd highly recommend getting this working without the network definitions and then later adding these one at a time.
After hours of trying to revive my stack.yml i started from beginning, read a bit more of documentation and found much helpful stackoverflow posts.
At the end, I'm actually having this:
version: "3"
services:
traefik:
image: traefik:latest
command: --web --docker --docker.swarmmode --docker.watch --docker.domain=intern.domain.tld --logLevel=DEBUG
deploy:
placement:
constraints: [node.role==manager]
restart_policy:
condition: on-failure
labels:
- "traefik.port=8080"
- "traefik.docker.network=proxy"
- "traefik.frontend.rule=Host:traefik.intern.domain.tld"
ports:
- "80:80"
- "5003:8080"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
networks:
- proxy
portainer:
image: portainer/portainer:latest
command: --no-auth -H unix:///var/run/docker.sock
deploy:
placement:
constraints: [node.role == manager]
labels:
- "traefik.portainer.port=9000"
- "traefik.docker.network=proxy"
- "traefik.frontend.rule=Host:portainer.intern.domain.tld"
ports:
- "5001:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- proxy
networks:
proxy:
Now i would need to get the portainer agent working. I'll work on it. On the first view portainer and traefik reachable on the right ports. SSL not yet, but for this my questions below.
Actually portainer.intern.domain.tld:5001 and traefik.intern.domain.tld:5001 both still portainer, but traefik.intern.domain.tld:5001 should not be reachable - just :5003 with traefik - Also the other way round.
In the documentation, I've read that for cluster operation, kv storage is needed to use acme certificates across multiple hosts. Nevertheless, I found configurations with the acme.json configuration in the network (for the swarm operation). Is kv storages obligatory or not?
I would really appreciate if their is a basic auth for the first in front of portainer and traefik - later wanna edit this to certificates. I know a bit about configuration in the traefik.toml - but is it the right way, if i done anything else over the compose file?
Same for SSL - i know a bit about configuration over traefik.toml, but is it the right way? What about storing all this in the compose file?
thank u in advance.
Related
My first attempt to start and use Swagger UI and Swagger Editor in the same time.
My approach is to define two services using Docker Compose and hiding them behind a reverse proxy, in this case Traefik.
But, something is wrong with my compose file and I can't figure out.
version: '3'
services:
traefik:
image: traefik:v2.5
restart: always
command:
- --accesslog
- --api.insecure=true
- --providers.docker
- --providers.docker.exposedbydefault=false
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
- "8080:8080"
swaggerui:
image: swaggerapi/swagger-ui
restart: always
environment:
- PORT=8081
expose:
- 8081
labels:
- traefik.enable=true
- traefik.http.routers.swaggerui.rule=Host(`swaggerui`) && Path(`/ui`)
swaggereditor:
image: swaggerapi/swagger-editor
restart: always
environment:
- PORT=8082
expose:
- 8082
labels:
- traefik.enable=true
- traefik.http.routers.swaggereditor.rule=Host(`swaggereditor`) && Path(`/editor`)
Any suggestion?
KI
You have to specify named entrypoint address (actually port number in container) in Traefik configuration at first
command:
...
- "--entrypoints.swaggerui.address=:8081"
At the second step you should add label for swaggerui container, just like this
labels:
- "traefik.enable=true"
- "traefik.http.routers.swaggerui.entrypoints=swaggerui"
...
After the above steps, everything should work
So I have the following docker-compose.yml
version: "3.7"
services:
roundclinic-mysql:
image: mysql:5.7
networks:
- spring-boot-mysql-network
environment:
- MYSQL_DATABASE=
- MYSQL_USER=
- MYSQL_PASSWORD=
- MYSQL_ROOT_PASSWORD=
volumes:
- ./mysqldata:/var/lib/mysql:rw,delegated
ports:
- "3306:3306"
web-service:
image: roundclinic/roundclinic:latest
networks:
- spring-boot-mysql-network
- traefik-network
depends_on:
- roundclinic-mysql
ports:
- 8080:8080
environment:
- "SPRING_PROFILES_ACTIVE=dev"
links:
- roundclinic-mysql
labels:
- "--providers.docker.network=traefik_default"
- "traefik.enable=true"
- "traefik.http.routers.roundclinic.rule=Host(`api-dev.roundclinic.app`)"
- "traefik.http.routers.roundclinic.entrypoints=web"
- "traefik.http.services.cal.loadbalancer.server.port=8080"
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "traefik.docker.network=traefik-network"
ports:
- "80:80"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
traefik-network:
driver: bridge
external: true
spring-boot-mysql-network:
driver: bridge
volumes:
my-db:
Spring boot starts up fine and can connect to mysql.
When I connect to http://api-dev.roundclinic.app:8080/../ I can hit my application just fine
When I connect to http://api-dev.roundclinic.app/../ I get a gateway timeout. I can see in the traefik logs that it's forwarding the request to what seems to be the correct IP and port, but nothing hits the actual application. I'm not sure what's going on here. Any help?
When accessing port 8080 you are bypassing Traefik and directly access your application, correct?
Generally speaking the Traefik labels look good. Entrypoint, Port and Host are defined, router and service port are present. These are usually all the requirements for Docker-based setups.
One thing that I noticed is that the traefik container uses "traefik.docker.network=traefik-network", but your web app uses:
"--providers.docker.network=traefik_default".
I am not sure if traefik_default is something that traefik provides but that mismatch in network names might be the issue.
I can't test if that is the problem but that would be the first thing to check.
One way would be to simplify your config but just always using the networks key from docker compose instead of mixing it with labels and arguments.
Started learning about docker, traefik for playing in home.
Aim: Put everything all together in docker-compose.yml and .env files, understand basics, comment accordingly.
Want to get dashboard from traefik.test.local/dashboard rather test.local:8080, similarly api should be accessed from traefik.test.local/api. So that don't have to think about port numbers.
added lines to /etc/hosts
127.0.0.1 test.local
127.0.0.1 traefik.test.local
docker-compose.yml
version: "3.7"
services:
traefik:
# The official v2 Traefik docker image
image: traefik:v2.2
# Lets name the container
container_name: traefik
command:
# Enables the web UI
- "--api.insecure=true"
# Tells Traefik to listen to docker
- "--providers.docker"
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
#labels:
#- "traefik.http.routers.router.rule=Host(`traefik.test.local/dashboard`)"
#- "traefik.http.routers.router.rule=Host(`traefik.test.local/api`)"
restart:
always
Not able to understand how to connect from router to services. Also correct me if I am wrong anywhere. Thank you.
PS: OS: kde-neon
you can achieve this using the following definition, you need to add labels for the routers and service and not only the router
proxy:
image: traefik:v2.1
command:
- '--providers.docker=true'
- '--entryPoints.web.address=:80'
- '--entryPoints.metrics.address=:8082'
- '--providers.providersThrottleDuration=2s'
- '--providers.docker.watch=true'
- '--providers.docker.swarmMode=true'
- '--providers.docker.swarmModeRefreshSeconds=15s'
- '--providers.docker.exposedbydefault=false'
- '--providers.docker.defaultRule=Host("traefik.lvh.me")'
- '--accessLog.bufferingSize=0'
- '--api=true'
- '--api.dashboard=true'
- '--api.insecure=true'
- '--ping.entryPoint=web'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
ports:
- '80:80'
- '8080:8080'
restart:
always
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=monitoring
- traefik.http.services.traefik-dashboard.loadbalancer.server.port=8080
- traefik.http.routers.traefik-dashboard.rule=Host(`dashboard.traefik.lvh.me`)
- traefik.http.routers.traefik-dashboard.service=traefik-dashboard
- traefik.http.routers.traefik-dashboard.entrypoints=web
- traefik.http.services.traefik-api.loadbalancer.server.port=80
- traefik.http.routers.traefik-api.rule=Host(`api.traefik.lvh.me`)
- traefik.http.routers.traefik-api.service=traefik-api
- traefik.http.routers.traefik-api.entrypoints=web
logging:
driver: json-file
options:
'max-size': '10m'
'max-file': '5'
also if you use lvh.me domain you not need to edit /etc/hosts
I'm a beginner with Traefik v2.1.4. I'm using in a docker container. I'm trying to set up a static route. I found some examples using the toml configuration file.
[providers]
[providers.file]
[http]
[http.routers]
[http.routers.netdata]
rule = "Host(`netdata.my-domain.com`)"
service = "netdata"
entrypoint=["http"]
[http.services]
[http.services.netdata.loadbalancer]
[[http.services.netdata.loadbalancer.servers]]
url = "https://192.168.0.2:19999"
Following this example I would like to convert it to docker labels of my docker-compose.
My docker-compose file:
version: "3.7"
services:
traefik:
image: traefik:v2.1.4
container_name: traefik
restart: always
command:
- "--log.level=DEBUG"
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsresolver.acme.tlschallenge=true"
- "--certificatesresolvers.letsresolver.acme.email=my-email#domain.com"
- "--certificatesresolvers.letsresolver.acme.storage=/letsencrypt/acme.json"
labels:
- "traefik.enable=true"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# global redirect to https
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=web"
- "traefik.http.routers.redirs.middlewares=redirect-to-https"
# dashboard
- "traefik.http.routers.traefik.rule=Host(`traefik.my-domain.com`)"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.middlewares=admin"
- "traefik.http.routers.traefik.tls.certresolver=letsresolver"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.middlewares.admin.basicauth.users=user:hash-passwordXXX"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
default:
external:
name: network
It is possible to use 2 providers together: file and docker.
Your docker-compose.yml:
services:
traefik:
image: traefik:2.2.1
command: traefik --configFile=/etc/traefik/traefik.yml
ports:
- "80:80"
- "8080:8080"
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml
- ./routes.yml:/etc/traefik/routes.yml
- /var/run/docker.sock:/var/run/docker.sock
# your services go here ...
Your traefik.yml:
api:
dashboard: true
insecure: true
entryPoints:
web:
address: :80
providers:
docker: {}
file:
filename: /etc/traefik/routes.yml
watch: true
Your routes.yml:
http:
routers:
hello:
rule: PathPrefix(`/hello`)
service: hello#docker
rule: PathPrefix(`/world`)"
service: world#docker
These are only examples, don't use them in production environment directly, of course.
There is no docker label mentioned to specify url (in https://docs.traefik.io/v2.1/routing/providers/docker/#routers). And I tried to use url instead of port, but it does not work.
So I suggest to use the file provider (https://docs.traefik.io/v2.1/providers/file/).
suggeston for implementation:
update your config with:
services:
...
traefik:
...
command:
...
- "--providers.file.directory=/path/to/dynamic/conf"
config:
- source: redirect.toml
target: /path/to/dynamic/conf/redirect.toml
...
...
configs:
redirect.toml:
file: redirect.toml
and create redirect.toml with your redirection (as in your example).
Of course you can also bindmount the config into the container, or create your own traefik image containing the config, or ...
In case you want to work with labels, you can start a service which redirects with socat
services:
...
netdata:
image: alpine/socat
command: tcp-listen:80,fork,reuseaddr tcp-connect:192.168.0.2:19999
deploy:
labels:
traefik.enable: "true"
traefik.http.routers.netdata.rule: Host(`netdata.my-domain.com`)
traefik.http.services.netdata_srv.loadbalancer.server.port: 80
# hm, and probably tell to forward as https, ...
My config is a simple Docker Swarm (on Docker for Windows) with a Treafik container and a very simple Spring Boot 'echo' container.
I would like to forward a browser request for 'localhost/traefik' to the Traefik dashboard and 'localhost/echo/something' to a simple Sprint Boot echo application.
Expected to work:
localhost/treafik => gives a "Gateway timeout"
localhost/echo/something => gives a "Gateway timeout"
Expected not to work, but bypass Traefik (incorrectly):
localhost:8080 => shows the Traefik dashboard
localhost:8082/echo/something => { "status":"something" }
How can I improve the docker-compose.yml file to get the expected result? Can this have to do with 'networking'? When creating any network, even an overlay, gave error messages.
version: '3.7'
services:
traefik:
image: traefik:latest
command: --api --docker
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- //k/data/slackbot/traefik.toml:/traefik.toml
ports:
- "80:80"
- "8080:8080"
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Host:localhost;PathPrefixStrip:/traefik"
- "traefik.port=8080"
- "traefik.protocol=http"
- "traefik.backend=traefik"
slackbotsimple:
image: solvedshared/slackbotsimple:latest
ports:
- 8082:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Host:localhost;PathPrefix:/echo"
- "traefik.port=8082"
- "traefik.protocol=http"
- "traefik.backend=slackbotsimple
The first issue was a networking issue. Solved, thanks to clever Jim.
The other issue was that I used the wrong port number. To route from the frontend '/echo' to the backend, the 'ports' section is NOT used. I could route directly to the exposed port of the slackbot application!
Take a look at the ports config: only 80 is available.
version: '3.7'
services:
traefik:
image: traefik:latest
command: --api --docker
restart: always
networks:
- slackbotnet
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- //k/data/slackbot/traefik.toml:/traefik.toml
ports:
- "80:80"
labels:
- "traefik.enable=true"
- "traefik.docker.network=slackbotnet"
- "traefik.frontend.rule=Host:localhost;PathPrefixStrip:/traefik"
- "traefik.port=8080"
- "traefik.protocol=http"
- "traefik.backend=traefik"
slackbotsimple:
image: solvedshared/slackbotsimple:latest
networks:
- slackbotnet
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- "traefik.enable=true"
- "traefik.docker.network=slackbotnet"
- "traefik.frontend.rule=Host:localhost;PathPrefix:/echo"
- "traefik.port=8080"
- "traefik.protocol=http"
- "traefik.backend=slackbotsimple"
networks:
slackbotnet:
name: slackbotnet