Handling server redirection with traefik - docker

I have a http server running in a docker. Accessing the server at / redirects it to /web. This works fine locally. I have setup traefik to connect to the docker through xxxxxxx.com domain. However, this results in a 404 page not found but when I try xxxxxxxx.com/web it works. How does traefik handle this kind of redirects? Thanks in advance.
Here's my docker-compose.yml file:
version: "3"
networks:
proxy:
external: true
internal:
external: false
services:
web:
restart: always
image: odoo:10.0
labels:
- traefik.backend=web
- traefik.frontend.rule=Host:portal.sironirestaurant.com
- traefik.docker.network=proxy
- traefik.port=8069
networks:
- internal
- proxy
depends_on:
- db
ports:
- 8069:8069
volumes:
- odoo-web-data:/var/lib/odoo
- ./config:/etc/odoo
- ./addons:/mnt/extra-addons
db:
restart: always
image: postgres:9.4
networks:
- internal
labels:
- traefik.enable=false
environment:
- POSTGRES_PASSWORD=xxxxxxx
- POSTGRES_USER=xxxxxx
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- odoo-db-data:/var/lib/postgresql/data/pgdata
volumes:
odoo-web-data:
odoo-db-data:

Related

I want docker to listen to "http://localhost/user" and forward to "http://portal.local/user" using traefik

I've got my docker environment setup using traefik and I've got two services running at the moment.
I'm using Google OAuth for authentication which redirects to my web application with auth-code. The redirect URL isn't allowed anything but localhost or localhost:<any-port> or any CDN. I've setup my docker for http://portal.local.
I now want http://localhost/user/googleLogin?code=xxxxxxxxxx to be translated to http://portal.local/user/googleLogin?code=xxxxxxxx for further processing of authentication.
Right now, I'm having to manually change localhost to portal.local in browser URL after it gives site not found error, which then takes me to further processing.
Below is my docker-compose.yml file.
version: "3.9"
services:
portal-traefik:
container_name: portal-traefik
command:
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
# - --entrypoints.websecure.address=:443
# - --certificatesresolvers.myresolver.acme.httpchallenge=true
# - --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
# - --certificatesresolvers.myresolver.acme.email=ssl#idealsalessolutions.com
# - --certificatesresolvers.myresolver.acme.storage=/acme/acme.json
image: traefik:latest
networks:
api_driven:
ports:
- "80:80"
- "8080:8080"
# - "443:443"
restart: unless-stopped
volumes:
- portal_acme:/acme
- /var/run/docker.sock:/var/run/docker.sock:ro
api-i4f:
container_name: api-i4f
depends_on:
- php-i4f
- portal-traefik
image: nginx:stable-alpine
labels:
- traefik.enable=true
- traefik.http.routers.api.rule=Host(`api.local`)
networks:
api_driven:
restart: unless-stopped
volumes:
- ../docker.sites/api.local:/usr/share/nginx/api.local
- ./conf/nginx/conf.d:/etc/nginx/conf.d:ro
command: [nginx, '-g', 'daemon off;']
hostname: api.local
portal-i4f:
container_name: portal-i4f
depends_on:
- php-i4f
- portal-traefik
image: nginx:stable-alpine
labels:
- traefik.enable=true
- traefik.http.routers.portal.rule=Host(`portal.local`)
networks:
api_driven:
restart: unless-stopped
volumes:
- ../docker.sites/portal.local:/usr/share/nginx/portal.local
- ./conf/nginx/conf.d:/etc/nginx/conf.d:ro
command: [nginx, '-g', 'daemon off;']
hostname: portal.local
php-i4f:
container_name: php-i4f
depends_on:
- portal-traefik
image: isshub/core:php7.4.30-fpm-alpine3.16-intl-mysql
networks:
api_driven:
restart: unless-stopped
volumes:
- ../docker.sites/api.local:/usr/share/nginx/api.local
- ../docker.sites/portal.local:/usr/share/nginx/portal.local
networks:
api_driven:
name: "api_driven"
volumes:
portal_acme:
I've tried to use multiple router rules to listen to both localhost and portal.local using regex/replacement middlewares as well but that stops the service at all and gives 404 error.

traefik with docker breaks when I setup networks

I'm trying to setup docker networks with traefik on an existing website.
Before my tries, it had this:
version: "3"
services:
database:
build:
context: ./database
environment:
MYSQL_DATABASE: '${MYSQL_DATABASE}'
MYSQL_USER: '${MYSQL_USER}'
MYSQL_PASSWORD: '${MYSQL_PASSWORD}'
MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD}'
volumes:
- ./database/data:/var/lib/mysql
restart: always
php-http:
build:
context: ../
dockerfile: ./docker/php-apache/Dockerfile
args:
MAIN_DOMAIN: '${MAIN_DOMAIN}'
ALL_DOMAINS: '${ALL_DOMAINS}'
PROJECT_FOLDER_NAME: '${PROJECT_FOLDER_NAME}'
WEBSITE_USER_PASSWORD: '${WEBSITE_USER_PASSWORD}'
depends_on:
- database
- mailserver
volumes:
- ./apachelogs:/var/log/apache2
- ./apachelogs/auth.log:/var/log/auth.log
- './symfonylogs:/var/www/html/mywebsite/var/log/'
labels:
- traefik.http.routers.php-http.tls=true
- traefik.http.routers.php-http.tls.certresolver=letsencrypt
- traefik.http.services.php-http.loadbalancer.server.port=80
- traefik.enable=true
- traefik.http.routers.php-http.rule=Host(`mystuff.com`, `en.mystuff.com`)
- 'traefik.http.routers.php-http.tls.domains[0].main=mystuff.com'
- 'traefik.http.routers.php-http.tls.domains[1].main=en.mystuff.com'
restart: always
mailserver:
[doesntmatter]
traefik:
image: traefik:v2.9
command:
- --providers.docker
- --providers.docker.exposedByDefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --certificatesresolvers.letsencrypt.acme.email=heyho#gmail.com
- --certificatesresolvers.letsencrypt.acme.storage=acme.json
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
ports:
- 80:80
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./acme.json:/acme.json
It works fine.
Then I tried doing this :
docker network create web
And in the yml:
networks:
web:
external: true
internal:
external: false
For php-http:
networks:
- internal
- web
and (I tried without and with it)
- "traefik.docker.network=web"
In database and mailserver :
networks:
- internal
In traefik:
networks:
- web
and (tried without and with it)
- "traefik.docker.network=web"
It didn't work at all, my website wasn't accessible anymore.
Then as said there : https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/
I tried :
networks:
web: {}
Then in php-http and traefik:
networks:
- web
It didn't work either. Their example (with whoami) works on my server. (Tried with a local curl). Like always, this makes me hate sysadmin very much, does anyone has any clue on what's wrong there? It doesn't make anysense to me. I followed everything, tried everything.
Thank you

Traefic Routing for FireflyIII

Greetings Stack Overflow,
I have a RespberryPi4B, on which I installed Ubuntu 20.
(Linux ubuntu 5.4.0-1034-raspi aarch64 - Ubuntu 20.04.1 LTS)
On this Pi I want to install several Applications for my local use only.
To be able to have multiple Applications exposed, I use Traefik as a Proxy.
To easier deploy the Applications, I use Docker and Docker-Compose
Already up and running I have a Nextcloud instance, which works just fine.
Now I want to add FireflyIII as an Application, but the routing does not comply, and greets me with "Bad Gateway".
Here's what I have
The following docker-compose.yml for my Nextcloud works like a charm:
version: '3.3'
services:
nextcloud-db:
image: mariadb
container_name: nextcloud-db
command: --transaction-isolation=READ-COMMITTED --log-bin=ROW
restart: unless-stopped
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /opt/containers/nextcloud/database:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD={supersecret}
- MYSQL_PASSWORD={supersecret}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloudusr
- MYSQL_INITDB_SKIP_TZINFO=1
networks:
- default
nextcloud-redis:
image: redis:alpine
container_name: nextcloud-redis
hostname: nextcloud-redis
networks:
- default
restart: unless-stopped
command: redis-server --requirepass {supersecret}
nextcloud-app:
image: nextcloud
container_name: nextcloud-app
restart: unless-stopped
depends_on:
- nextcloud-db
- nextcloud-redis
environment:
REDIS_HOST: nextcloud-redis
REDIS_HOST_PASSWORD: {supersecret}
volumes:
- /opt/containers/nextcloud/app:/var/www/html
- /opt/containers/nextcloud/daten:/var/www/html/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud-app.entrypoints=http"
- "traefik.http.routers.nextcloud-app.rule=Host(`nextcloud.mydomain.com`)"
- "traefik.http.middlewares.nextcloud-app-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.nextcloud-app.middlewares=nextcloud-app-https-redirect"
- "traefik.http.routers.nextcloud-app-secure.entrypoints=https"
- "traefik.http.routers.nextcloud-app-secure.rule=Host(`nextcloud.mydomain.com`)"
- "traefik.http.routers.nextcloud-app-secure.tls=true"
- "traefik.http.routers.nextcloud-app-secure.tls.certresolver=http"
- "traefik.http.routers.nextcloud-app-secure.service=nextcloud-app"
- "traefik.http.services.nextcloud-app.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
- "traefik.http.routers.nextcloud-app-secure.middlewares=nextcloud-dav,secHeaders#file"
- "traefik.http.middlewares.nextcloud-dav.replacepathregex.regex=^/.well-known/ca(l|rd)dav"
- "traefik.http.middlewares.nextcloud-dav.replacepathregex.replacement=/remote.php/dav/"
networks:
- proxy
- default
networks:
proxy:
external: true
While knowing that this configuration, and these traefik labels work, I would assume, that the following docker-compose.yml, now for FireflyIII would work as well. And while the container spins up without any visible issues - I can see in the container logs, that the applications connects to the database and prepares everything - the access via browser is not possible - I get a Bad Gateway.
This is my FireflyIII's docker-compose.yml
version: '3.3'
services:
fireflydb:
image: mariadb
container_name: fireflydb
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_USER=fireflyuser
- MYSQL_PASSWORD={supersecret}
- MYSQL_DATABASE=fireflydb
volumes:
- firefly_db:/var/lib/mysql
networks:
- default
firefly:
image: jc5x/firefly-iii:latest
container_name: firefly
volumes:
- firefly_upload:/var/www/html/storage/upload
depends_on:
- fireflydb
env_file: .env
labels:
- "traefik.enable=true"
- "traefik.http.routers.firefly-app.entrypoints=http"
- "traefik.http.routers.firefly-app.rule=Host(`firefly.mydomain.com`)"
- "traefik.http.middlewares.firefly-app-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.firefly-app.middlewares=firefly-app-https-redirect"
- "traefik.http.routers.firefly-app-secure.entrypoints=https"
- "traefik.http.routers.firefly-app-secure.rule=Host(`firefly.mydomain.com`)"
- "traefik.http.routers.firefly-app-secure.tls=true"
- "traefik.http.routers.firefly-app-secure.tls.certresolver=http"
- "traefik.http.routers.firefly-app-secure.service=firefly-app"
- "traefik.http.services.firefly-app.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
networks:
- proxy
- default
volumes:
firefly_upload:
firefly_db:
networks:
proxy:
external: true
The only difference between the Traefik Labels is, that I don't need the replacepathregex labels for firefly, and that I changed the Hosts and application names:
nextcloud.mydomain.com -> firefly.mydomain.com
nextcloud-app/nextcloud-app-secure -> firefly-app/firefly-app-secure
I just don't understand yet, why the "same" configuration behaves differently.
The Traefik container logs don't throw any errors.
A note about the SSL Certificates, since the applications are run in my local network, and I edit my local hostfile to access the application via browser, the SSL renewal isn't possible, I am aware of that. I currently work around it by manually renewing on a different server and copying the cert to my Pi. Quick and dirty, but works for now.
For completeness, here's my Traefik's traefik.yml, docker-compose.yml and dynamic_conf.yml:
traefik.yml:
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: "/dynamic_conf.yml"
certificatesResolvers:
http:
acme:
email: mymail#mydomain.com
storage: acme.json
httpChallenge:
entryPoint: http
docker-compose.yml:
version: '3'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
- ./data/dynamic_conf.yml:/dynamic_conf.yml
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=user:secret"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.mydomain.com`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=http"
- "traefik.http.routers.traefik-secure.service=api#internal"
- "providers.file.filename=/dynamic_conf.yml"
networks:
proxy:
external: true
dynamic_conf.yml
tls:
options:
default:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true
http:
middlewares:
secHeaders:
headers:
browserXssFilter: true
contentTypeNosniff: true
frameDeny: true
sslRedirect: true
#HSTS Configuration
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
customFrameOptionsValue: "SAMEORIGIN"
The only thing I could think of, might be a problem with the internal Ports.
But I don't know enough about traefik and docker yet, to say for sure.
I appreciate any hints and suggestions for improvement.
At first glance I'd recommend to change the port to 8080:
version: '3.3'
services:
# [...]
firefly:
labels:
#
- "traefik.http.services.firefly-app.loadbalancer.server.port=8080"
# [...]
The firefly-iii-Image you're using is based on their BaseImage which's README.md says:
Basically, I use the 7.4 Apache image with some minor changes.
And one change is:
Switch to port 8080

Why am I unable to route to my API backend with Traefik

I had two container frontend (nginx :80) and backend (nodejs :3000).
I'm trying to redirect all path to my frontend : localhost/* to my frontend
Except one path to my backend API : localhost/v1/* to my backend
I secure my database container (mongodb) by allowing only communication with my backend
Here is my docker-compose.yml (I'm only using this)
version: '3'
services:
traefik:
image: traefik:v2.3
container_name: traefik
command:
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
ports:
- "8080:8080"
- "443:443"
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
frontend:
image: registry.gitlab.com/test/frontend
container_name: frontend
build:
context: ../frontend/.
labels:
- traefik.enable=true
- traefik.http.routers.frontend.rule=PathPrefix(`/`)
- traefik.http.routers.frontend.entrypoints=web
networks:
- traefik-network
backend:
image: registry.gitlab.com/test/backend
container_name: backend
build:
context: ../backend/.
labels:
- traefik.enable=true
- traefik.http.routers.backend.rule=PathPrefix(`/v1`)
- traefik.http.routers.backend.service=backend
- traefik.http.routers.backend.entrypoints=web
- traefik.http.services.backend.loadbalancer.server.port=3000
command: yarn start
environment:
- MONGODB_URL=mongodb://mongodb:27017/backend
depends_on:
- mongodb
volumes:
- ../backend/.:/usr/src/backend
networks:
- traefik-network
- backend-network
mongodb:
image: mongo:4.2.1-bionic
container_name: mongodb
ports:
- 27017:27017
volumes:
- dbdata:/data/db
networks:
- backend-network
volumes:
dbdata:
networks:
backend-network:
traefik-network:
The problem is...
If the frontend (backend and traefik too) is turned on
the paths to localhost/* work (this is what I want),
but the paths to localhost/v1/* don't work (Problem here!).
If the frontend is turned off but traefik and backend is turned on
the paths to localhost/* don't work (of course, that's right),
but the paths to localhost/v1/* work (of course, this is what I want).
I've tried a lot of solutions but nothing seems to work the way I want it to.
What did I misunderstand?
Thanks for helping,
Have a nice day
Try to add the following labels to the backend service
- "traefik.http.routers.backend.rule=Host(`servicex.me`) && Path(`/v1`)"
and frontend
- traefik.http.routers.frontend.rule=Host(`servicex.me`)
you also need to add this line to your /etc/hosts
127.0.0.1 servicex.me
and make sure that you stop and start the services
Complete Example
version: '3'
services:
traefik:
image: traefik:v2.3
container_name: traefik
command:
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
ports:
- "8080:8080"
- "443:443"
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
frontend:
image: registry.gitlab.com/test/frontend
container_name: frontend
build:
context: ../frontend/.
labels:
- traefik.enable=true
- traefik.http.routers.frontend.rule=Host(`servicex.me`)
- traefik.http.routers.frontend.entrypoints=web
- traefik.http.routers.frontend.service=frontend
- traefik.http.services.frontend.loadbalancer.server.port=80
networks:
- traefik-network
backend:
image: registry.gitlab.com/test/backend
container_name: backend
build:
context: ../backend/.
labels:
- traefik.enable=true
- "traefik.http.routers.backend.rule=Host(`servicex.me`) && Path(`/v1`)"
- traefik.http.routers.backend.service=backend
- traefik.http.routers.backend.entrypoints=web
- traefik.http.services.backend.loadbalancer.server.port=3000
command: yarn start
environment:
- MONGODB_URL=mongodb://mongodb:27017/backend
depends_on:
- mongodb
volumes:
- ../backend/.:/usr/src/backend
networks:
- traefik-network
- backend-network
mongodb:
image: mongo:4.2.1-bionic
container_name: mongodb
ports:
- 27017:27017
volumes:
- dbdata:/data/db
networks:
- backend-network
volumes:
dbdata:
networks:
backend-network:
traefik-network:
BTW, why do you need both traefik and nginx (Both are doing the same job), it would be better if you can replace one with another.
I added this label to my containers
traefik.docker.network=traefik-network
It works fine now

Proxy web interface with help traefik

I'm trying to proxy the pgAdmin web interface using segment URLs. But I have some problems with this.
When I'm accessing the browser with the following URL -> http://localhost/pgadmin, it redirects me to the following URL -> http://localhost/login?next=%2F. This is the internal routing of pgAdmin.
I want routing to be next http://localhost/pgadmin/login?next=%2F.
Could you tell me how can I achieve this.
Here is an example of my docker-compose configuration
version: '3.7'
services:
traefik:
image: traefik:v2.2
container_name: traefik
restart: always
networks:
applications_network:
ipv4_address: 172.20.1.1
ports:
- "80:80"
- "8080:8080"
command:
- "--api.insecure=true --providers.docker"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--log.level=debug"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
pgAdmin4:
image: dpage/pgadmin4:latest
container_name: pgAdmin4
restart: always
networks:
applications_network:
ipv4_address: 172.20.2.1
ports:
- "15432:80"
environment:
PGADMIN_DEFAULT_EMAIL: "admin#test.com"
PGADMIN_DEFAULT_PASSWORD: "postgres"
labels:
- "traefik.enable=true"
- "traefik.http.routers.pgAdmin4.rule=Host(`localhost`)"
- "traefik.http.middlewares.pgAdmin4-prefix.stripprefix.prefixes=/pgadmin"
- "traefik.http.routers.pgAdmin4.middlewares=pgAdmin4-prefix"
- "traefik.http.routers.pgAdmin4.entrypoints=web"
- "traefik.http.routers.pgAdmin4.service=pgAdmin4"
- "traefik.http.services.pgAdmin4.loadbalancer.server.port=80"
networks:
applications_network:
name: applications_network
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
Thanks in advance.

Resources