I am attempting to create multiple Docker-Compose projects and have them share a single service, a database server. I'm currently unable to get projects to use my mariadb instance. I'm not sure if my issues is in traefik or docker. I can get wordpress to recognize the database if it is included in the same docker-compose, but as I would ultimately like to not have multiple instances of a database server running, I would prefer it to be it's own project.
# ~/docker/traefik/docker-compose.yml
version: "3.3"
services:
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
- "--api=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=namedotcom"
- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.myresolver.acme.email=<MY-EMAIL>"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
networks:
t2_proxy:
ports:
- "80:80"
- "443:443"
environment:
- "NAMECOM_USERNAME=<My-USERNAME>
- "NAMECOM_API_TOKEN=<My-Token>
labels:
# Dashboard
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`api.mydomain.com`)"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.middlewares=admin"
- "traefik.http.routers.traefik.tls.certresolver=myresolver"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.middlewares.admin.basicauth.users=myuser:mypasswordhash/"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# global redirect to https
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=web"
- "traefik.http.routers.redirs.middlewares=redirect-to-https"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
t2_proxy:
# ~/docker/db/docker-compose.yml
version: '3.3'
services:
mysql:
image: mariadb
container_name: "mariadb"
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: wordpressDB
MYSQL_USER: wordpressUSER
MYSQL_PASSWORD: wordpressPW
networks:
default:
ports:
- 3306:3306
adminer:
image: adminer
restart: always
container_name: "adminer"
labels:
- "traefik.enable=true"
- "traefik.http.routers.adminer.rule=PathPrefix(`/adminer`)"
- "traefik.http.routers.adminer.entrypoints=websecure"
- "traefik.http.routers.adminer.tls.certresolver=myresolver"
networks:
- default
- traefik_t2_proxy
networks:
default:
traefik_t2_proxy:
external: true
# ~/docker/wordpress/docker-compose.yml
version: '3.3'
services:
wordpress:
image: wordpress:latest
restart: always
container_name: "mySite"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpressUSER
WORDPRESS_DB_PASSWORD: wordpressPW
WORDPRESS_DB_NAME: wordpressDB
networks:
traefik_t2_proxy:
db_default:
labels:
- "traefik.enable=true"
- "traefik.http.routers.wp2.rule=PathPrefix(`/wordpress`)"
- "traefik.http.routers.wp2.entrypoints=websecure"
- "traefik.http.routers.wp2.tls.certresolver=myresolver"
volumes:
db_data: {}
networks:
traefik_t2_proxy:
external: true
db_default:
external: true
You can have multiple docker-compose files, with the same network and run them together as below:
docker-compose -f docker-compose-1.yml -f docker-compose-2.yml up -d
But if you need the services to recognize eachother, the networks should be the same. Give your traefik_t2_proxy network to mysql too.
Related
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
This is docker-compose file that starts the containers all are working fine except the caddy.
version: '3'
services:
db:
image: postgres:latest
restart: always
expose:
- "5555"
volumes:
- pgdata:/var/lib/postgresql/data/
environment:
- POSTGRES_DB=chiefonboarding
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
networks:
- global
web:
image: chiefonboarding/chiefonboarding:latest
restart: always
expose:
- "9000"
environment:
- SECRET_KEY=somethingsupersecret
- BASE_URL=https://on.hr.gravesfoods.com
- DATABASE_URL=postgres://postgres:postgres#db:5432/chiefonboarding
- ALLOWED_HOSTS=on.hr.gravesfoods.com
- DEFAULT_FROM_EMAIL=hello#gravesfoods.com
depends_on:
- db
networks:
- global
caddy:
image: caddy:2.3.0-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- $PWD/Caddyfile:/etc/caddy/Caddyfile
- $PWD/site:/srv
- caddy_data:/data
- caddy_config:/config
networks:
- global
volumes:
pgdata:
caddy_data:
caddy_config:
networks:
global:
Also these are the logs it is generating:
[https://on.hr.gravesfoods.com:80] scheme and port violate convention "level":"info","ts":1656425557.6256478,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile" run: adapting config using caddyfile: server block 0, key 0 (https://on.hr.gravesfoods.com:80): determining listener address: [https://on.hr.gravesfoods.com:80] scheme and port violate convention.
We are trying to configure api and frontend with docker-compose using Traefik and we need that both applications are exposed by domain.
With this configuration we get 404 but commented "frontend" lines make api works.
In Traefik dashboard we can see both applications in "HTTP Services" tab as loadbalancer but we have no routers in "Routers" tab.
What we miss?
We also tried using "network" with no luck (receive "gateway time out").
version: "3.3"
services:
traefik:
image: "traefik:latest"
restart: always
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=myemail" # Let's Encrypt email
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
db:
image: mysql:latest
volumes:
- db_data:/var/lib/mysql
restart: always
container_name: "db"
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_DATABASE: mydb
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
ports:
- "32769:3306"
api:
image: "myregistry/myimage:latest"
restart: always
container_name: "api"
labels:
- "traefik.enable=true"
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
- traefik.http.routers.web.middlewares=redirect-to-https
- traefik.http.routers.web.rule=Host(`mydomainapi`)
- traefik.http.routers.web.entrypoints=web
- "traefik.http.routers.websecure.rule=Host(`mydomainapi`)"
- "traefik.http.routers.websecure.entrypoints=websecure"
- "traefik.http.routers.websecure.tls.certresolver=letsencrypt"
depends_on:
- db
frontend:
image: "myregistry/myimagefrontend:latest"
restart: always
container_name: "frontend"
labels:
- "traefik.enable=true"
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
- traefik.http.routers.web.middlewares=redirect-to-https
- traefik.http.routers.web.rule=Host(`mydomainfrontend`)
- traefik.http.routers.web.entrypoints=web
- "traefik.http.routers.websecure.rule=Host(`mydomainfrontend`)"
- "traefik.http.routers.websecure.entrypoints=websecure"
- "traefik.http.routers.websecure.tls.certresolver=letsencrypt"
depends_on:
- api
volumes:
db_data:
driver: local
I am trying to deploy multiple apps on my docker host and have traefik route traffic based on hostnames to the different apps
I am using docker-compose for all my docker containers
Here is my traeffik.yaml file
version: '3.5'
services:
traefik:
image: traefik
container_name: traefik
command: --api --docker
networks:
- traefik_network
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
traefik_network:
name: traefik_network
here is my wpapp1.yaml file
version: '3.5'
services:
mysql:
image: mysql:5.7
volumes:
- wpapp1_mysql:/var/lib/mysql
restart: always
container_name: wpapp1_mysql
networks:
- traefik_network
environment:
MYSQL_ROOT_PASSWORD: wpapp1
MYSQL_DATABASE: wpapp1
MYSQL_USER: wpapp1
MYSQL_PASSWORD: wpapp1
wordpress:
depends_on:
- mysql
image: wordpress:latest
volumes:
- wpapp1_wordpress:/var/www/html
restart: always
container_name: wpapp1_wordpress
networks:
- traefik_network
labels:
- "traefik.frontend.rule=Host:wpapp1.example.com"
- "traefik.port=80"
- "traefik.docker.network=traefik_network"
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wpapp1
WORDPRESS_DB_PASSWORD: wpapp1
volumes:
wpapp1_mysql:
name: wpapp1_mysql
wpapp1_wordpress:
name: wpapp1_wordpress
networks:
traefik_network:
external:
name: traefik_network
and here is my wpapp2.yaml file
version: '3.5'
services:
mysql:
image: mysql:5.7
volumes:
- wpapp2_mysql:/var/lib/mysql
restart: always
container_name: wpapp2_mysql
networks:
- traefik_network
environment:
MYSQL_ROOT_PASSWORD: wpapp2
MYSQL_DATABASE: wpapp2
MYSQL_USER: wpapp2
MYSQL_PASSWORD: wpapp2
wordpress:
depends_on:
- mysql
image: wordpress:latest
volumes:
- wpapp2_wordpress:/var/www/html
restart: always
container_name: wpapp2_wordpress
networks:
- traefik_network
labels:
- "traefik.frontend.rule=Host:wpapp2.example.com"
- "traefik.port=80"
- "traefik.docker.network=traefik_network"
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wpapp2
WORDPRESS_DB_PASSWORD: wpapp2
volumes:
wpapp2_mysql:
name: wpapp2_mysql
wpapp2_wordpress:
name: wpapp2_wordpress
networks:
traefik_network:
external:
name: traefik_network
So now i expect traefik to route based on the hostnames wpapp1.example.com and wpapp2.example.com BUT traefik is loadbalancing traffic!!!
So when i go to http:/wpapp1.example.com, traefik is loadbalancing it between the two apps and same for the other hostnames. Now sure what is going on here since i specifically add the traefik.frontend.rule
I mean how in the hell is that happening?
I have spent hours to figure what is going on and before i go insane i decided to some here to get some help on what is going on here.
Put your database on a different network. Otherwise WordPress will RR load balance to the two mysql instances in the same docker network (that's the expected behavior when you have two containers with the same alias on the same network). You can do that with the default network:
version: '3.5'
services:
mysql:
image: mysql:5.7
volumes:
- mysql:/var/lib/mysql
restart: unless-stopped
networks:
- db
environment:
MYSQL_ROOT_PASSWORD: wpapp
MYSQL_DATABASE: wpapp
MYSQL_USER: wpapp
MYSQL_PASSWORD: wpapp
wordpress:
depends_on:
- mysql
image: wordpress:latest
volumes:
- wordpress:/var/www/html
restart: unless-stopped
networks:
- traefik
- db
labels:
- "traefik.frontend.rule=Host:wpapp1.example.com"
- "traefik.port=80"
- "traefik.docker.network=traefik_network"
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wpapp
WORDPRESS_DB_PASSWORD: wpapp
volumes:
mysql:
wordpress:
networks:
db:
traefik:
external:
name: traefik_network
I am encountering some conflicts between the traefik.frontend.redirect and PathPrefixStrip. the docker-compose.yml file below always routes www.mysite.nl/adminer to the wordpress container. If I omit the redirect rules it works correctly and i get routed to the adminer instance. How can I make these rules work together?
Drilled down docker-comose.yml:
version: '3'
services:
wordpress:
image: wordpress:latest
restart: $RESTART
container_name: ${COMPOSE_PROJECT_NAME}_wp
depends_on:
- mysql
networks:
- web
labels:
- 'traefik.backend=$COMPOSE_PROJECT_NAME'
- 'traefik.entrypoint=https'
- 'traefik.enable=true'
- 'traefik.frontend.rule=Host:mysite.nl, www.mysite.nl, cdn.mysite.net'
# omitting these rules make the adminer instance reachable
- 'traefik.frontend.redirect.regex=^https?://mysite.nl/(.*)'
- 'traefik.frontend.redirect.replacement=https://www.mysite.nl/$${1}'
mysql:
image: mysql:latest
restart: $RESTART
container_name: ${COMPOSE_PROJECT_NAME}_db
networks:
- web
adminer:
image: adminer:4.6.2
restart: $RESTART
container_name: ${COMPOSE_PROJECT_NAME}
depends_on:
- mysql
networks:
- web
labels:
- 'traefik.backend=${COMPOSE_PROJECT_NAME}_adminer'
- 'traefik.entrypoint=https'
- 'traefik.enable=true'
- 'traefik.frontend.rule=Host:www.mysite.nl;PathPrefixStrip:/adminer'
networks:
web:
external:
name: traefik_${COMPOSE_PROJECT_NAME}_web
The issue you are running into is due to overlapping rules.
The request www.mysite.nl/adminer
Matches both:
traefik.frontend.rule=Host:mysite.nl, www.mysite.nl, cdn.mysite.net
and traefik.frontend.rule=Host:www.mysite.nl;PathPrefixStrip:/adminer
Therefore Traefik does not know which to route requests to.
Use the traefik.frontend.priority label to set an order for matching (from https://docs.traefik.io/configuration/backends/docker/#on-containers)
With help from Daniel Tomcej i came to the following working docker-compose.yml. You have to set the priority explicitly on both containers.
version: '3'
services:
wordpress:
image: wordpress:latest
restart: $RESTART
container_name: ${COMPOSE_PROJECT_NAME}_wp
depends_on:
- mysql
networks:
- web
labels:
- 'traefik.backend=$COMPOSE_PROJECT_NAME'
- 'traefik.entrypoint=https'
- 'traefik.enable=true'
- 'traefik.frontend.rule=Host:mysite.nl, www.mysite.nl, cdn.mysite.net'
- 'traefik.frontend.redirect.regex=^https?://mysite.nl/(.*)'
- 'traefik.frontend.redirect.replacement=https://www.mysite.nl/$${1}'
- 'traefik.frontend.priority=5'
mysql:
image: mysql:latest
restart: $RESTART
container_name: ${COMPOSE_PROJECT_NAME}_db
networks:
- web
adminer:
image: adminer:4.6.2
restart: $RESTART
container_name: ${COMPOSE_PROJECT_NAME}
depends_on:
- mysql
networks:
- web
labels:
- 'traefik.backend=${COMPOSE_PROJECT_NAME}_adminer'
- 'traefik.entrypoint=https'
- 'traefik.enable=true'
- 'traefik.frontend.rule=Host:www.mysite.nl;PathPrefixStrip:/adminer'
- 'traefik.frontend.priority=20'
networks:
web:
external:
name: traefik_${COMPOSE_PROJECT_NAME}_web