I have traefik setup on a virtual server on my network (192.168.1.41). I'm trying to proxy multiple local services so they're available on *.local. My internal DNS points *.local to 192.168.1.41.
With the following docker-compose.yml:
---
version: "2"
services:
homer:
image: b4bz/homer
#To build from source, comment previous line and uncomment below
#build: .
container_name: homer
volumes:
- /home/mbell/homer/assets/:/www/assets
ports:
- 8081:8080
#environment:
# - UID=1000
# - GID=1000
restart: unless-stopped
tty: true
labels:
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.http.routers.homer.rule=(`dashboard.local`)"
- "traefik.http.routers.homer.entrypoints=web"
- "traefik.http.services.homer.loadbalancer.server.port=8081"
networks:
- web
networks:
web:
external: true
I think I'm write in assuming that it should run as dashboard.local but it only works on dashboard.local:8081
How do I make it work so it's only available on dashboard.local?
This line:
"traefik.http.routers.homer.rule=(`dashboard.local`)"
Should be:
"traefik.http.routers.homer.rule=Host(`dashboard.local`)"
Related
So, I've setup several container apps that use MariaDB as their db backend, using docker-compose.
Containers are setup as needed and therefore MariaDB gets installed each time on every container that uses the db.
For example, I have some containers (PHPMyAdmin, NGiNX-PM, etc.) that use MariaDB, and they, in turn, have a version of it installed within their container. I also have a separate container (MariaDB) that I would rather have shared amongst the other containered apps and, thereby, I'd only have to maintain one version of the db.
I've searched for a solution, but no luck. Needless to say, I'm a noob at docker.
The only thing I can come up with is that all the apps need to be installed through the same docker-compose.yaml file to use the same db? That would make for a very long file if I had many containers running, and I'd prefer to have a directory per app and all the app's contents available in this one location.
I'm sure there is a way, I just haven't been able to figure it out.
So this is what I've tried:
The following setup is what I've tried but I am unable to get it to work:
(/docker/apps/mariadb/mariadb.yml)
version: '3.9'
networks:
NET:
external: true
services:
#############################################################################################
# MariaDB (docker-compose -f mariadb.yml up -d) #
#############################################################################################
mariadb:
image: jsurf/rpi-mariadb:latest
restart: unless-stopped
environment:
- TZ=${TIMEZONE}
- MYSQL_DATABASE=dockerApps
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
volumes:
- $HOME/docker/apps/mariadb/db:/var/lib/mysql
expose:
- '3306'
networks:
- NET
(/docker/apps/nginxpm/nginxpm.yml)
version: '3.9'
networks:
NET:
external: true
services:
#############################################################################################
# NGiNX Proxy Manager (docker-compose -f nginxpm.yml up -d) #
#############################################################################################
nginxpm:
container_name: NGiNX_Proxy_Manager
image: 'jc21/nginx-proxy-manager:latest'
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./config.json:/app/config/production.json
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- NET
depends_on:
- mariadb
(/docker/apps/phpmyadmin/phpmyadmin.yml)
version: "3.9"
networks:
NET:
external: true
services:
#############################################################################################
# phpMyAdmin (docker-compose up -d -OR- docker-compose -f phpmyadmin.yml up -d) #
#############################################################################################
phpmyadmin:
image: phpmyadmin:latest
container_name: phpMyAdmin
restart: unless-stopped
environment:
PMA_HOST: mariadb
PMA_USER: root
PMA_PASSWORD: ${MYSQL_PASSWORD}
volumes:
# Must add ServerName directive to end of file "ServerName 127.0.0.1"
- $HOME/docker/apps/phpmyadmin/apache2.conf:/etc/apache2/apache2.conf
ports:
- '8004:80'
networks:
- NET
Any help in this matter is greatly appreciated.
Ok, so after some more reading and testing, I've found the answer to my issue. I was assuming that "depends_on" was supposed to connect the containers, somehow. Not true!
I found that "external_links" is the correct way of connecting them.
So, my final docker-compose file looks like this:
(/docker/apps/nginxpm/nginxpm.yml)
version: '3.9'
networks:
NET:
external: true
services:
#############################################################################################
# NGiNX Proxy Manager (docker-compose -f nginxpm.yml up -d) #
#############################################################################################
nginxpm:
container_name: NGiNX_Proxy_Manager
image: 'jc21/nginx-proxy-manager:latest'
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./config.json:/app/config/production.json
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- NET
external_links:
- mariadb
I would like to build a docker landscape. I use a container with a traefik (v2. 1) image and a mysql container for multiple databases.
traefik/docker-compose.yml
version: "3.3"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
restart: always
command:
- "--log.level=DEBUG"
- "--api=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik-dashboard.address=:8080"
- "--certificatesresolvers.devnik-resolver.acme.httpchallenge=true"
- "--certificatesresolvers.devnik-resolver.acme.httpchallenge.entrypoint=web"
#- "--certificatesresolvers.devnik-resolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.devnik-resolver.acme.email=####"
- "--certificatesresolvers.devnik-resolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "./data:/etc/traefik"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- "proxy"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`devnik.dev`)"
- "traefik.http.routers.traefik.entrypoints=traefik-dashboard"
- "traefik.http.routers.traefik.tls.certresolver=devnik-resolver"
#basic auth
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.usersfile=/etc/traefik/.htpasswd"
#Docker Networks
networks:
proxy:
database/docker-compose.yml
version: "3.3"
services:
#MySQL Service
mysql:
image: mysql:5.7
container_name: mysql
restart: always
ports:
- "3306:3306"
volumes:
#persist data
- ./mysqldata/:/var/lib/mysql/
- ./init:/docker-entrypoint-initdb.d
networks:
- "mysql"
environment:
MYSQL_ROOT_PASSWORD: ####
TZ: Europe/Berlin
#Docker Networks
networks:
mysql:
driver: bridge
For the structure I want to control all projects via multiple docker-compose files. These containers should run on the same network as the traefik container and some with the mysql container.
This also works for the following case (but only sometimes)
dev-releases/docker-compose.yml
version: "3.3"
services:
backend:
image: "registry.gitlab.com/devnik/dev-releases-backend/master:latest"
container_name: "dev-releases-backend"
restart: always
volumes:
#laravel logs
- "./logs/backend:/app/storage/logs"
#cron logs
- "./logs/backend/cron.log:/var/log/cron.log"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dev-releases-backend.rule=Host(`dev-releases.backend.devnik.dev`)"
- "traefik.http.routers.dev-releases-backend.entrypoints=websecure"
- "traefik.http.routers.dev-releases-backend.tls.certresolver=devnik-resolver"
networks:
- proxy
- mysql
environment:
TZ: Europe/Berlin
#Docker Networks
networks:
proxy:
external:
name: "traefik_proxy"
mysql:
external:
name: "database_mysql"
As soon as I restart the containers in dev-releases/ via docker-compose up -d I get the typical error "Gateway timeout" when calling them in the browser.
As soon as I comment the network networks: #- mysql and restart the docker-compose in dev-releases/ it works again.
My guess is that I have not configured the external networks correctly. Is it not possible to use 2 external networks?
I'd like some container have access to the 'mysql' network but it should not be accessible for the whole traefik network.
Let me know if you need more information
EDIT (26.03.2020)
I make it running.
I put all my containers into one network "proxy". It seems mysql also have to be in the proxy network.
So I add following to database/docker-compose.yml
networks:
proxy:
external:
name: "traefik_proxy"
And removed the database_mysql network out of dev-releases/docker-compose.yml
based on the names of the files, your mysql network should be mysql_mysql.
you can verify this by executing
$> docker network ls
You are also missing a couple of labels for your services such as
traefik command line
- '--providers.docker.watch=true'
- '--providers.docker.swarmMode=true'
labels
- traefik.docker.network=proxy
- traefik.http.services.dev-releases-backend.loadbalancer.server.port=yourport
- traefik.http.routers.dev-releases-backend.service=mailcatcher
You can check this for more info
Here's my docker-compose.yml:
version: '3'
services:
website:
build: ./website
expose: [3000]
labels:
- "traefik.frontend.rule=Host:localhost"
blog:
build: ./blog
expose: [4000]
labels:
- "traefik.frontend.rule=Host:localhost;PathPrefix:/blog"
docs:
build: ./docs
expose: [3000]
labels:
- "traefik.frontend.rule=Host:localhost;PathPrefix:/docs"
proxy:
image: traefik
command: --api.insecure=true --providers.docker
networks:
- webgateway
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
webgateway:
driver: bridge
What I want is access three different node.js websites via different routes. But these three node.js websites actually expose different ports. Now my treafik is running. I can config via localhost:8080 But localhost localhost/blog and localhost/docs are all 404 page not found
P.S: I'm not sure whether port is the issue I should investigate, because changing one node.js service to port 80 doesn't solve the puzzle. And I saw on traefik dashboard the rule is Host(blog-dev)
PathPrefix:/blog
When you have this as a routing rule, traefix won't automatically remove the prefix when sending to the container.
So unless you have a route /blog inside your container you will get a 404.
So what you normally do is also add a middleware to strip this ->
https://docs.traefik.io/middlewares/stripprefix/
Also you appear not to be setting your rules based on your service.
So as an example for your first service blog,
try->
labels:
- "traefik.http.routers.blog.rule=Host(`localhost`) && PathPrefix(`/blog`)"
- "traefik.http.routers.blog.middlewares=strip-blog"
- "traefik.http.middlewares.strip-blog.stripprefix.prefixes=/blog"
And then do the same for your other routes, don't forget to replace routers.blog with routers.docs etc..
labels:
- traefik.http.services.<YOUR-SERVICE-NAME>.loadbalancer.server.port=9763
EG:
services:
wso:
image: "my-custom-wso-image"
volumes:
- .....
labels:
- "traefik.enable=true"
- "traefik.http.routers.wso.tls=true"
- "traefik.http.routers.wso.rule=Host(`my.nice.url`)"
- "traefik.http.services.wso.loadbalancer.server.port=9763" #<-----
Thanks to #Keith I found the solution
version: '3'
services:
website:
build: ./website
expose: [3000]
networks: # It's essential to specify the same network in every service
- webgateway
labels:
- "traefik.http.routers.website.rule=Host(`localhost`)" # Use the right format
- "traefik.port=3000" # Let traefik find the right port
blog:
build: ./blog
expose: [4000]
networks:
- webgateway
labels:
- "traefik.http.routers.blog.rule=Host(`localhost`) && PathPrefix(`/blog`)" # blog has a root as `/blog` so no need to strip otherwise too many redirects
- "traefik.port=4000"
docs:
build: ./docs
expose: [3000]
networks:
- webgateway
labels:
- "traefik.http.routers.docs.rule=Host(`localhost`) && PathPrefix(`/docs`)"
- "traefik.http.routers.docs.middlewares=strip-docs" # Necessary as Keith mentioned
- "traefik.http.middlewares.strip-docs.stripprefix.prefixes=/docs"
- "traefik.port=3000"
proxy:
image: traefik
command: --api.insecure=true --providers.docker
networks:
- webgateway
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
webgateway:
driver: bridge
I'm using docker-compose and I've a dev server with lot of virtual hosts on Nginx+PHP-FPM. At the moment nginx container handles multiple virtual hosts:
version: '3'
services:
nginx-proxy:
image: nginx:1.17.4-alpine
container_name: nginx-proxy
ports:
- '80:80'
- '443:443'
volumes:
- conf:/etc/nginx/conf.d
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs:ro
labels:
- 'com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true'
restart: always
dockergen:
[...]
letsencrypt:
[...]
nginx:
image: nginx:1.17.4-alpine
restart: always
container_name: nginx
environment:
VIRTUAL_HOST: proj1.site.com, proj2.example.com
LETSENCRYPT_HOST: proj1.site.com, proj2.example.com
LETSENCRYPT_EMAIL: tech#example.com
volumes:
- './proj1:/proj1'
- './proj2:/proj2'
- './site.conf:/etc/nginx/conf.d/site.conf'
php:
build:
context: ./php
container_name: php
volumes:
- './proj1:/proj1'
- './proj2:/proj2'
restart: always
volumes:
conf:
vhost:
html:
certs:
networks:
default:
external:
name: nginx-proxy
Now, I'd like to separate the virtual host containers, because I need to inject different env files. Should i replicate the nginx container (of course with different name) and the site.conf per each project? Am I doing it the right way? Could you please suggest me the right direction? P.S. I've read that extends keyword is deprecated for docker-compose v3, so I'd like to avoid that if possible.
I'm trying to use traefik in my docker-compose file. My php app is listening on port 8000
version: '3'
services:
traefik:
image: traefik:1.7.4
container_name: traefik-${PROJECT_NAME}
ports:
- ${TRAEFIK_PORT}:80
- ${TRAEFIK_PORT_HTTPS}:443
- ${TRAEFIK_DASHBOARD_PORT}:8080
volumes:
- ./traefik/traefik.toml:/etc/traefik/traefik.toml
- /var/run/docker.sock:/var/run/docker.sock
networks:
- webgateway
php-fpm:
build:
context: .
dockerfile: Dockerfile-php
container_name: php-fpm-${PROJECT_NAME}
ports:
- 8000
working_dir: /var/www/html/
volumes:
- ../app:/var/www/html
tty: true
env_file:
- ./.env
entrypoint: /entrypoint.sh
networks:
- traefik
networks:
webgateway:
driver: bridge
traefik:
external:
name: traefik_webgateway
volumes:
data-volume: {}
Trefik watch every container
[docker]
domain = "local"
watch = true
All container appear in Traefik dashboard but frontend Host do not match with IP address. I can't access the app.
But when I go directly through the container IP address, it works.
Did I missed something in the configuration?
Found it. I have added host name in my /etc/hosts file.
Works fine with that