Setting up phpmyadmin with traefik2 in docker - apache

I am having some trouble accessing my phpmyadmin through traefik2 reverse proxy! all the other apps I am using in my docker-compose are working correctly through traefik. Its as simple as setting the labels up, specififying which domain to use, and then going to that through a browser. Right now I am able to access phpmyadmin through the local ip and port, but unable to through my domain. I just get a 404 not found error. This is my phpmyadmin docker-compose setup.
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
depends_on:
- mariadb
container_name: phpmyadmin
restart: unless-stopped
networks:
- t2_proxy
security_opt:
- no-new-privileges:true
# volumes:
# - $USERDIR/docker/phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php
environment:
- PMA_PORT=$DB_PORT
- PMA_HOST=$MYSQL_HOST
# - PMA_ABSOLUTE_URI=$ABSOLUTE_URI
# - PMA_ARBITRARY=1
- MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
ports:
- $PHPMYADMIN_PORT:80
labels:
- "traefik.enable=true"
# - "traefik.backend=phpmyadmin"
## HTTP Routers
- "traefik.http.routers.phpmyadmin-rtr.entrypoints=https"
- "traefik.http.routers.phpmyadmin-rtr.rule=Host(`phpmyadmin.$DOMAINNAME`)"
## Middlewares
- "traefik.http.routers.phpmyadmin-rtr.middlewares=chain-oauth#file"
## HTTP Services
- "traefik.http.routers.phpmyadmin-rtr.service=phpmyadmin-svc"
- "traefik.http.services.phpmyadmin-svc.loadbalancer.server.port=80"
I am also getting a very similar error with my php/apache container that I can access locally but not through traefik. All the other containers have been a simple swap of the labels, rename them and boom, they are accessible ! what am I doing wrong? I tried adding PMA_ABSOLUTE_URI=$ABSOLUTE_URI and I can't figure out how to enable ssl in phpmyadmin in docker.
and it still doesnt work but phpmyadmin says:
There is a mismatch between HTTPS indicated on the server and client. This can lead to a non working phpMyAdmin or a security risk. Please fix your server configuration to indicate HTTPS properly.
And also for my apache server it is setup like this, with a similar problem where it can be accessed from localhost but not traefik!
apache:
build:
context: $USERDIR/docker/apache
dockerfile: Dockerfile
container_name: apache
volumes:
- $USERDIR/WEBSITE:/var/www/html/
ports:
- 6546:80
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.apache-rtr.entrypoints=https"
# - "traefik.http.routers.tautulli-rtr.rule=Host(`web.$DOMAINNAME`)"
- "traefik.http.routers.apache-rtr.rule=Host(`$SECONDDOMAINNAME`)"
## Middlewares
- "traefik.http.routers.apache-rtr.middlewares=chain-no-auth#file"
## HTTP Services
- "traefik.http.routers.apache-rtr.service=apache-svc"
- "traefik.http.services.apache-svc.loadbalancer.server.port=80"
sorry if this is alot, I am very new to docker, and really trying to figure this out! If i posted this in the wrong spot or something, let me know!
and if you need anymore information, please also let me know!

Try adding in the label - "traefik.http.routers.phpmyadmin-rtr.tls=true"
This fixed the issue for me

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/Portainer - ERR_TOO_MANY_REDIRECTS

I'm trying to setup Traefik and Portainer but seem to be hitting some issues. I think mainly around Traefik and setting up new containers.
Everything looks correct to me but I seem to be getting an error when I point to my subdomain
ERR_TOO_MANY_REDIRECTS
If I point to the IP address and Port, the Portainer dashboard is displayed, it just seems to be that when pointing to my sub-domain, there is some recursive redirection I'm assuming.
My docker compose looks like this:-
version: '3'
services:
portainer:
image: portainer/portainer:latest
container_name: portainer-new
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
ports:
- 8000:8000
- 9000:9000
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=http"
- "traefik.http.routers.portainer.rule=Host(`MY_URL`)"
- "traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.portainer.middlewares=portainer-https-redirect"
- "traefik.http.routers.portainer-secure.entrypoints=https"
- "traefik.http.routers.portainer-secure.rule=Host(`MY_URL`)"
- "traefik.http.routers.portainer-secure.tls=true"
- "traefik.http.routers.portainer-secure.tls.certresolver=http"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
Any ideas?
Okay, so I figured out my issue.
The above is correct and valid. I use CloudFlare for proxy/DNS etc... I had added my subdomain to my DNS settings, but my Proxy Status was Proxied rather than DNS ONLY. After setting DNS only the above worked.

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.

Deploying Traefik with LetsEncrypt and multiple Docker backend

I am considering replacing Apache for Traefik for my web project (Kestrel / .Net Core). After reading the documentation, a few things remain unclear to me regarding Traefik:
1/ Does Traefik automatically handle the LetsEncrypt certificate renewal or does it need to be done manually or via an external script? From the doc it's said that this is performed when adding a new host or restart, but what happens after 3 months of Traefik running without any restart/new host added?
2/ When a Docker backend becomes unreachable, how is it possible to serve a custom static HTML page? I can see how to set specific error page from the documentation, but not how to redirect trafic to it when a given backend becomes unavailable.
3/ When a Docker backend needs to be updated, is there some steps that need to be performed on Traefik prior to performing the Docker stop/restart?
4/ It seems I can't get to have 2 docker backend running at the same time, see the configuration file below, if I uncomment the 2nd backend (api.mydomain.io), then the 1st one becomes not available anymore. Am I missing something here?
version: '3'
services:
reverse-proxy:
image: traefik # The official Traefik docker image
command: --docker # Enables the web UI and tells Træfik to listen to docker
ports:
- "80:80" # The HTTP port
- "443:443" # The HTTPS port
- "8080:8080" # The Web UI (enabled by --api)
networks:
- proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/traefik.toml:/etc/traefik/traefik.toml
- $PWD/acme.json:/acme.json
- /root/mydomain_prod/cert/:/certs/
- /root/mydomain_prod/503.html:/503.html
container_name: traefik-reverse-proxy
##############################
# Front - www.mydomain.io
##############################
mydomain-front:
image: mydomain-front
labels:
- traefik.enable=true
- traefik.backend=mydomain-front
- traefik.frontend.rule=Host:traefik.mydomain.io
- traefik.port=8084
networks:
- internal
- proxy
container_name: mydomain-front
##############################
# API - api.mydomain.io
# Note: If I uncomment this one, then www.mydomain.io won't work anymore
##############################
#mydomain-api:
# image: mydomain-api
# labels:
# - traefik.enable=true
# - traefik.backend=mydomain-api
# - traefik.frontend.rule=Host:api.mydomain.io
# - traefik.port=8082
# networks:
# - internal
# - proxy
# container_name: mydomain-api
Many thanks,
Flo
1/ Traefik can handle the LetsEncrypt certificate renewal. Just remember to create a Volume to store the acme.json file. When the certificate expires, Traefik will do the renewal without asking.
2/ I don’t know if it’s possible. If you find a solution, share it.
3/ When you need to update a Docker, just update it. Traefik will be trigger from that change and update is own configuration.
4/ You can have to backend running at the same time. Below you can see a docker-compose.yml configuration :
version: '3'
services:
two-backend-service:
restart: always
image: ……..
labels:
- traefik.enable=true
- traefik.service1.frontend.rule=Host:service1.exemple.com
- traefik.service1.frontend.passHostHeader=true
- traefik.service1.port=8082
- traefik.Service2.backend=service2
- traefik.Service2.frontend.rule=Host:service2.exemple.com
- traefik.Service2.frontend.passHostHeader=true
- traefik.Service2.port=8081
traefik:
build:
context: ./traefik
dockerfile: Dockerfile
restart: always
ports:
- 80:80
- 443:443
labels:
- traefik.enable=false
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik_letsencrypt:/etc/traefik/acme/
volumes:
traefik_letsencrypt:
driver: local

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