Can't Access Traefik dashboard outside server - linux

I am learning traefik and I am trying to connect to Ubuntu server hosted on a raspberry pi, Traefik is running on Docker. Currently I just want to access the dashboard, however am unable to access it outside my server but can ping it from inside the server itself,
This is how my traefik.yml file looks like
api:
dashboard: true
insecure: true
entryPoints:
http:
address: ":80"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
docker-compose file
services:
proxy:
image: traefik
networks:
- traefik
ports:
- "80:80"
- "8080:8080"
command:
- "--api.insecure=true"
- "--api.dashboard=true"
- "--providers.docker"
- "--log.level=DEBUG"
- "--configFile=/home/ubuntu/traefik/traefik.yml"
volumes:
- $PWD/traefik.yml:/home/ubuntu/traefik/traefik.yml
- $PWD/acme.json:/home/ubuntu/traefik/acme.json
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
networks:
traefik:
external:
name: traefik
I have docker network registered called traefik
NETWORK ID NAME DRIVER SCOPE
...
ef66....... traefik bridge local

Related

Azure web app multi container (MEAN app), what is the URL to connect to node backend container from front end container?

Trying to learn to deploy angular app to azure web app using multi-container, the frontend loads fine but cant connect to the backend node container, I want to add the url of the node backend to my angular frontend but i cant figure out what it is. I've tried https://rojesh.azure.io:3000, https://rojesh.azurewebsites.net:3000, http://server:3000 and more but nothing seems to work. Website Hostname: https://rojesh.azurewebsites.net and the acr name is rojesh.azurecr.io which has 3 images. This is my config file for compose in azure:
version: '3.3'
services:
db:
image: rojesh.azurecr.io/db:latest
ports:
- "27017:27017"
restart: always
networks:
- app-network
server:
image: rojesh.azurecr.io/server:latest
depends_on:
- db
ports:
- "3000:3000"
restart: always
networks:
- app-network
app:
depends_on:
- server
image: rojesh.azurecr.io/app:latest
environment:
NGINX_HOST: rojesh.azurewebsites.net
NGINX_PORT: 80
ports:
- "80:80"
restart: always
networks:
- app-network
networks:
app-network:
driver: bridge
The app works fine locally using docker compose which is:
version: '3.9'
services:
docker-app:
build:
context: app
dockerfile: Dockerfile.dev
ports:
- '4200:4200'
volumes:
- ./app/src:/app/src
docker-server:
build:
context: server
dockerfile: Dockerfile
environment:
PORT: 3000
MONGODB_URI: mongodb://mongo:27017/rojesh
JWT_SECRET: secret
ports:
- 3000:3000
depends_on:
- mongo
volumes:
- ./server:/server
mongo:
container_name: mongo-server
image: mongo:latest
ports:
- 27017:27017
Thanks # ajkuma-msft. Azure App Service only exposes ports 80 and 443. Yes, incoming requests from client would just be over 443/80 which should be mapped to the exposed port of the container.
App Service will attempt to detect which port to bind to your container. If you want to bind to your container the WEBSITES_PORT app setting and configure it with a value of the port.
Web App for Containers currently allows you to expose only one port to the outside world. The container can only listen for HTTP requests on a single port.
From Docker compose configuration stand-point : Ports other than 80 and 8080 are ignored.
Refer Docker Compose options lists shows supported and unsupported Docker Compose configuration options.
Refer here

How to use Traefik to reverse proxy an already running node service?

I've got a node process running on port 3000 using pm2.
I want to configure Traefik so that it reverse proxies this service on port 80.
Following this excellent blog post, I was able to quickly start Traefik using docker compose and set up a skeleton config for the node-server.
However, that example assumes the node process is hosted inside a docker as well. I couldn't get this to work for my node process (*) so I just want to be able to configure Traefik by pointing to port 3000 in some way. Seems straightforward but couldn't get it to work.
I'm stuck with the following config (which is a mix of various blog-posts without actually knowing what I'm doing):
services:
reverse-proxy:
image: traefik:v2.4
container_name: "traefik"
command:
- "--api.insecure=true"
- "--api.dashboard=true"
- "--api.debug=true"
- "--providers.docker=true"
- "--log.LEVEL=DEBUG"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--providers.docker.exposedbydefault=false"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.myresolver.acme.email=xxxx#xxx.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
- "80:80"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
node-server:
loadBalancer:
servers:
- url: http://127.0.0.1:3000/
labels:
- "traefik.enable=true"
- "traefik.http.routers.node-server.rule=Host(`xxxxxx.com`)"
- "traefik.http.routers.node-server.entrypoints=websecure"
- "traefik.http.routers.node-server.tls.certresolver=myresolver"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=web"
- "traefik.http.routers.redirs.middlewares=redirect-to-https"
This gives the error: 'Unsupported config option for services.node-server: 'loadBalancer'"
Long story short: how would I configure Traefik to just reverse proxy a service running on port 3000?
*) A total newbie to Docker and I couldn't get the situation to work, where the node process depends on custom javascript modules in a parent directory. Perhaps there's a way to do this and I could do it in the 'host node in docker' way instead. I'm all ears
A few months ago I have configured a reverse proxy, here you go my configuration:
version: '3'
services:
reverse-proxy:
image: traefik:v2.5
container_name: selling-point-reverse-proxy
ports:
- 80:80
- 8080:8080
volumes:
# Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
command:
# Enables the web UI
- --api.insecure=true
# Tells Traefik to listen to docker
- --providers.docker
# Creates a new entrypoint called web
- --entrypoints.web.address=:80
# Disable container exposition
- --providers.docker.exposedByDefault=false
# Traefik matches against the container's labels to determine whether to create any route for that container
- --providers.docker.constraints=Label(`traefik.scope`,`selling-point`)
# Enable tracing (using jaeger by default)
- --tracing=true
# Name of the tracing service on Jaeger
- --tracing.serviceName=reverse-proxy
# Host and port of the Jaeger agent
- --tracing.jaeger.localAgentHostPort=jaeger:6831
labels:
# Matcher for creating a route
- traefik.scope=selling-point
# Exposes container
- traefik.enable=true
# Creates circuit breaker middleware
- traefik.http.middlewares.latency.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 10000
# Creates a forward auth middleware
- traefik.http.middlewares.auth.forwardauth.address=http://auth:3000/auth/authorize
# Enables cross origin requests
- traefik.http.middlewares.cors.headers.accesscontrolalloworiginlist=*
# Enables forwarding of the request headers
- traefik.http.middlewares.cors.headers.accessControlAllowHeaders=*
networks:
- selling-point
api:
image: selling-point-api
container_name: selling-point-api
build:
context: ./selling-point-api
labels:
# Tells Traefik where to redirect the request if the url has the specified prefix
- traefik.http.routers.api.rule=PathPrefix(`/api`)
# Attaches a middleware for forwarding the authentication
- traefik.http.routers.api.middlewares=cors,auth,latency
# Attaches entrypoints
- traefik.http.routers.api.entrypoints=web
# Exposes container
- traefik.enable=true
# Matcher for creating a route
- traefik.scope=selling-point
# Creates a service called selling-point-api
- traefik.http.services.selling-point-api.loadbalancer.server.port=3000
# Attach the container to a service
- traefik.http.routers.api.service=selling-point-api
volumes:
- ./selling-point-api/src:/app/src
networks:
- selling-point
environment:
WAIT_HOSTS: mysql:3306
DATABASE_URL: mysql://root:huachinango#mysql:3306/selling_point
NODE_ENV: development
auth:
image: selling-point-auth
container_name: selling-point-auth
build:
context: ./selling-point-auth
labels:
# Tells Traefik where to redirect the request if the url has the specified prefix
- traefik.http.routers.auth.rule=PathPrefix(`/auth`)
# Attaches a circuit breaker middleware
- traefik.http.routers.auth.middlewares=cors,latency
# Attaches entrypoints
- traefik.http.routers.auth.entrypoints=web
# Exposes container
- traefik.enable=true
# Matcher for creating a route
- traefik.scope=selling-point
# Creates a service called selling-point-auth
- traefik.http.services.selling-point-auth.loadbalancer.server.port=3000
# Attach the container to a service
- traefik.http.routers.auth.service=selling-point-auth
environment:
WAIT_HOSTS: mysql:3306
IGNORE_ENV_FILE: 'true'
DATABASE_URL: mysql://root:huachinango#mysql:3306/selling_point
PASSWORD_SALT: $$2b$$10$$g0OI8KtIE3j6OQqt1ZUDte
NODE_ENV: development
volumes:
- ./selling-point-auth/src:/app/src
networks:
- selling-point
mysql:
image: mysql:5
container_name: selling-point-mysql
environment:
MYSQL_ROOT_PASSWORD: huachinango
MYSQL_DATABASE: selling_point
networks:
- selling-point
volumes:
- mysql-db:/var/lib/mysql
jaeger:
image: jaegertracing/all-in-one:1.29
container_name: selling-point-tracing
environment:
COLLECTOR_ZIPKIN_HOST_PORT: :9411
ports:
- 16686:16686
networks:
- selling-point
volumes:
mysql-db:
networks:
selling-point:
name: selling-point
driver: bridge

Docker compose and Service communication

I have a docker-compose with 5 services that have to communicate.
I checked whether they would be in the same network using docker network inspect networkname_dafult
and I could find all the apps there in the same network.
The result of inspect returned a json with a name property.
```"Name": "app_1",```
In each service I am using that name to make http requests but they return
"connect ECONNREFUSED 127.0.0.1:5003" for example.
If I access localhost:5003 it works, and it will work for each service.
If i try to make the http requests from my apps using localhost:port it wont work either.
My dockercompose.yml
version: "3.7"
services:
App1:
image: user/app1
ports:
- 5001:5001
links:
- App2
- App3
- App4
- App5
hostname: app1
App2:
image: user/app2
ports:
- 5002:5002
hostname: app2
App3:
image: user/app3
ports:
- 5003:5003
hostname: app3
App4:
image: user/app4
ports:
- 5004:5004
hostname: app4
App5:
image: user/app5
ports:
- 5005:5005
hostname: app5
I tried to make the http requests using the hostname, Appx and etc... I cant make them communicate with each other.
What might I be missing here?
Create a network and assign all the parts of the service to that network. One example:
version: '3.7'
networks:
app_net:
driver: bridge
services:
App1:
image: user/app1
ports:
- 5001:5001
networks:
- app_net
hostname: app1
App2:
image: user/app2
ports:
- 5002:5002
networks:
- app_net
hostname: app2
App3:
image: user/app3
ports:
- 5003:5003
networks:
- app_net
hostname: app3
App4:
image: user/app4
ports:
- 5004:5004
networks:
- app_net
hostname: app4
App5:
image: user/app5
ports:
- 5005:5005
networks:
- app_net
hostname: app5
But it might be that I'm missing something. Another thing to consider is using links - more info here. Also, if you are going to copy+paste this code, take care about indentation.
Docker-compose already creates a default network.
I ran docker network ls to see which networks were available
and used docker network inspect mynetwork to see if the apps on my docker-compose were running on the same network (They will be).
The result of docker network inspect is an array of containers objects.
Each container object has a name property (That was the information I nedded to make http connections between services)
"Containers": {
"01fcacc2b2dc8450c5c75e": {
"Name": "myapp_1",
"EndpointID": "9e3fa9633d9d1692d4f7120c",
"MacAddress": "00:00:00:00:00:00",
"IPv4Address": "172.33.0.2/16",
"IPv6Address": ""
},
On each service I was performing http requests I used that property name to make the requests.
axios.get(http://myapp_1)
An important detail was to rebuild my container after changing it!
docker build -t myapp .
When I ran docker-compose again everything worked.

Communication between microservices with docker-compose and traefik

I have a microservice based node app. I am using docker, docker-compose and traefik for service discovery.
I have 2 microservices at this moment:
the server app: running at node-app.localhost:8000
the search microservice running at search-microservice.localhost:8002
The issue I can't make a request from one microservice to another.
Here are my docker compose config:
# all variables used in this file are defined in the .env file
version: "2.2"
services:
node-app-0:
container_name: node-app
restart: always
build: ./backend/server
links:
- ${DB_HOST}
depends_on:
- ${DB_HOST}
ports:
- "8000:3000"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:node-app.localhost"
reverse-proxy:
image: traefik # The official Traefik docker image
command: --api --docker # Enables the web UI and tells Traefik 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
search-microservice:
container_name: ${CONTAINER_NAME_SEARCH}
restart: always
build: ./backend/search-service
links:
- ${DB_HOST}
depends_on:
- ${DB_HOST}
ports:
- "8002:3000"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:search-microservice.localhost"
volumes:
node-ts-app-volume:
external: true
Both the node-app and the search-microservice expose the port 3000.
Why can't I call http://search-microservice.localhost:8002 from the node app ? calling it from the browser works though.
Because node-app is a container and to access other containers it has to use service name and internal port.
In your case it is search-microservice:3000.
To access host PC and exposed ports, you have to use host.docker.internal name for all services and external port.
If you want to access other services from in a different container with their hostnames, you can use the "extra_hosts" parameter in your docker-compose.yml file. Also, you have to use the "ipv4_address" parameter under the network parameter for each all services.
For example;
services:
node-app-1:
container_name: node-app
networks:
apps:
ipv4_address: 10.1.3.1
extra_hosts:
"search-microservice.localhost:10.1.3.2"
node-app-2:
container_name: search-microservice
networks:
apps:
ipv4_address: 10.1.3.2
extra_hosts:
"node-app.localhost:10.1.3.1"
Extra hosts in docker-compose

Docker from a container calls to another container (Connection Refused)

I have container for two NodeJS services and one Nginx for reverse-proxy.
I have make NGINX on port 80 so it's publicly available via localhost on my browser
I also use reverse-proxy to proxy_pass to each responsible service.
location /api/v1/service1/ {
proxy_pass http://service1:3000/;
}
location /api/v1/service2/ {
proxy_pass http://service2:3000/;
}
In my service 1, there is an axios module that wants to call to service 2 by making a request to localhost/api/v1/service2
But, it says that connection is refused. I doubt if the localhost in service 1 refer to its container, not the docker host.
version: '3'
services:
service1:
build: './service1'
networks:
- backend
service2:
build: './service2'
networks:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
networks:
backend:
driver: bridge
Even after using network, it still says ECONNREFUSED.
Please help.
Try adding the depends_on in your docker-compose file for the nginx, like below:
version: '3'
services:
service1:
build: './service1'
expose:
- "3000"
networks:
- backend
service2:
build: './service2'
expose:
- "3000"
networks:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
depends_on:
- service1
- service2
networks:
backend:
driver: bridge
This would make sure that both services are running first before the nginx container attempts to connect to them. Perhaps the connection is refused because the nginx container keeps crashing due to it not finding the two services running when it executes its conf file and connect to the backends.

Resources