How to add a simple routing rule to traefik - reverse-proxy

I'm trying to get started with traefik in the hopes I can replace my current reverse proxy (pound) with traefik.
How do I add a simple routing rule so that mysubdomain.mydomain.com routes to http://192.168.x.x:8080?
I'm following the quickstart here. I created the following docker compose yml file and started it with docker-compose up -d reverse-proxy
version: '3'
services:
reverse-proxy:
container_name: reverse-proxy
image: traefik #The official Traefik docker image
command: --api --docker #Enables the web UI and tells Træfik to listen to docker
ports:
- "80:80" #The HTTP port
- "8080:8080" #The Web UI (enabled by --api)
volumes:
- /var/run/docker.sock:/var/run/docker.sock #So that Traefik can listen to the Docker events
Great, the container is running, but now what? How would I go about adding the simply routing rule?
If my backend web service isn't running one of these supported backends will it not work? Surely traefik can simply route http requests to any http backend right?
For example my backend web service is a web interface for my synology NAS at home. Traefik should be able to route this right? If so, how?

Related

Traefik load balance between Docker provider and server at url

I currently have a Traefik setup with one nodejs service running locally in a docker container with a docker-compose.yml file like so:
container_name: nestjs-server
build:
context: ./
dockerfile: Dockerfile
networks:
- traefik-global-proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.nestjs-server.rule=Host(`mydomain.com`) || Host(`www.mydomain.com`)"
- "traefik.http.routers.nestjs-server.entrypoints=websecure"
- "traefik.http.routers.nestjs-server.tls.certresolver=letsencrypt"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
I am running on a 1vCPU / 2GB cloud instance. Now I would like to add a second node app instance on another VM. I have seen it is possible to add server instances to the load balancer like so:
services:
my-service:
loadBalancer:
servers:
- url: "http://<private-ip-server-1>:<private-port-server-1>/"
- url: "http://<private-ip-server-2>:<private-port-server-2>/"
But I am not sure how to load balance between instances on another service alongside local docker instances. I have read that it is not possible to mix the label based config with the file config, so I assume I'd need to do something like:
my-service:
loadBalancer:
servers:
- url: "http://<private-ip-server-1>:<private-port-server-1>/"
- port: "<local-port-server-2>"
Is this possible? What is the correct way to accomplish this, other than having everything run on the same machine within docker?

traefik v2 forwarding to external host. Non container host

I am looking for examples of traefik v2 forwarding to other host such as virtual machines ( ie non container ).
Kind Regards,
Edward
That should look like this in the file-provider:
http:
routers:
...
...
services:
somename:
loadBalancer:
servers:
- url: http://yourserverip
Docker has to "see" your server (test with curl or ping).
Further information: Traefik Docs - Routers

Traefik internal only traffic

I have an Ubuntu 16.04 Docker host running Traefik and Free-ipa server, i want to use trafek to block extranal access to free-ips server but allow internal ranges.
is this possible?
Thanks
Mo
You can use docker's network to isolate your environment, for exemple,
services:
traefik:
networks:
- traefik-net
free-ipa:
networks:
- internal-net
others:
networks:
- traefik-net
- internal-net
Here, others can access free-ipa just by using free-ipa as dns name, and it's accessible by traefik as well. traefik can't see free-ipa because they are not in the same network.

Traefik - Unable to expose redis docker containers with the same port for different domains

I'm trying to set up a Redis with docker-compose for different environments.
Therefore I need to expose two domains with traefik on the same port:
domain.com:6379
domain-dev.com:6379
I can't expose those ports on the container, because they are running on the same server.
My docker-compose file (for domain-dev) looks like this:
version: '2'
services:
redis:
container_name: redis-signalr-dev
image: redis
volumes:
- ./redis-signalr-data:/data
restart: always
labels:
- traefik.enable=true
- traefik.backend=redis-signalr-dev
- traefik.frontend.rule=Host:domain-dev.com
- traefik.port=6379
- traefik.docker.network=traefik_default
- traefik.frontend.entryPoints=redis
networks:
- traefik_default
volumes:
redis-signalr-data:
networks:
traefik_default:
external: true
I also tried to configure the treafik to use the following endpoint:
--entrypoints='Name:redis Address::6379'
When connecting to "domain-dev.com:6379" a connection cannot be astablished.
Does anyone know a solution to this problem?
Traefik is a reverse proxy for http, not a tcp load balancer. So traefik itself (usually) opens ports 80 and 443 for ingress and forwards incoming http requests to the given http-able backends. The port you specify in your compose service labels is the port of the container, the traffic should be passed to.
So if you run a nodejs (http) server on port 3000, you would connect to http://yourdomain:80 and traefik would forward the requests to your nodejs container on port 3000. This means that by specifying a port on a compose service, you will not open this port on your host.
In your example running redis with its custom protocol, traefik is not a solution as traefik only does http proxying. To expose redis on your host (if you really want to do that), just use regular docker port mappings and point your domains to your docker hosts. Doing this, there is no way to use the same port with different domains, just specify two different ports for your both instances. For http this works by traefik inspecting the http requests and doing routing based on the host header.
Traefik 2.0 will have TCP support: https://github.com/containous/traefik/pull/4587
Until then you'd have to use NGINX or similar.

How to make REST calls between Frontend and Backend using Docker containers

I have 3 docker containers:
Backend (Spring boot rest api)
Frontend (Js and html in the apache image)
Mongodb
I'm orchestrating them through docker-compose and works nicely.
However I don't know how to let my frontend javascript client know the backend container's host/ip in order to reach it.
This is my docker-compose.yml:
version: '3.1'
services:
project-server:
build: .
restart: always
container_name: project-server
ports:
- 8200:8200
working_dir: /opt/app
depends_on:
- mongo
httpd:
image: project-ui
container_name: project-ui
ports:
- 8201:80
mongo:
image: project-mongo
container_name: project-mongo
ports:
- 27018:27017
volumes:
- $HOME/data/mongo-data:/data/db
- $HOME/data/mongo-bkp:/data/bkp
restart: always
So i've tried with this in my js client app:
export default {
REMOTE_HOST: 'http://project-server:8200'
}
But it doesn't work. (Failed to load resource: net::ERR_NAME_NOT_RESOLVED)
And i'm pretty sure it's because JS runs locally on the browser so it has no way to resolve that.
What's the right way to do this? There is any way for the frontend service (apache) to pass/render the real host to Javascript and get it somehow?
Thanks a lot
project-server can be resolved only within the network created by docker-compose. As you mentioned, to connect from the outside world you need to export the IP of your host instead of project-server. The problem is the guest container doesn't know the IP of the guest. Here is a detailed discussion about that: How to get the IP address of the docker host from inside a docker container
What you probably need in your situation is to run the container passing the IP of the host as an environment variable:
run --env <IP>=<value>
Then in node you can just read that variable.
Hope it helps