
At the beginning of times, when the mountains were not so tall I was using simple nginx image, which was exposed to 80 port (8080 or any other) and website was accessible in browser by http://127.0.0.1[:8080] url. Later I found the article where traefik was described and started to use in every docker-compose.yml file. it was used only for one virtual network but with user-friendly urls! http://mywebsite.in-docker.localhost/.
Suddenly the task has come to make two (or more) websites running on local env and to make them see each other by clean urls, made a request, receive responses, check each other health etc. Idea of cloning containers in docker-compose was moved in trash immediatly. Because it's not funny to have nginx-1 + php-1, nginx-2 + php-2 containeers in one docker-compose file. But what if the amount of websites will be changd in future? Not funny to have php-1, php-2,php-3, php-4 there…
The solution of this problem is running the one common network and common Traefik for all websites.
Create file docker-compose.traefik.yml
version: "3"
services:
traefik:
image: traefik
container_name: "my-traefik"
ports:
- "80:80"
- "8080:8080"
volumes:
- ./traefik.toml:/etc/traefik/traefik.toml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
default:
external:
name: common-traefik
80 port for all websites, 8080 port for Traefik's dashboard.
Important!! file /images-traefik/traefik.toml has the command to enable the dashboard and the network name with dockers to monitor
[api] dashboard = true insecure = true [providers.docker] watch = true network = "common-traefik"
Next we create docker-compose for our websites clones. docker-compose.drupal8.yml
version: '3' services: php-fpm: image: php:7.4-fpm-alpine container_name: "${PROJECT_NAME}-php-fpm" volumes: - ../${PROJECT_NAME}:/drupal links: - mariadb labels: - "traefik.enable=false" networks: - default - project-network web: image: nginx:alpine container_name: "${PROJECT_NAME}-web" expose: - '80' volumes: - ../${PROJECT_NAME}:/drupal environment: - SERVER_NAME=${PROJECT_NAME}.my-docker.localhost links: - php-fpm labels: - traefik.http.routers.${PROJECT_NAME}.rule=Host(`${PROJECT_NAME}.my-docker.localhost`) depends_on: - php-fpm networks: - default - project-network mariadb: image: mariadb:10.3 container_name: "${PROJECT_NAME}-sql" environment: MYSQL_ROOT_PASSWORD: 'password' MYSQL_DATABASE: 'drupal8' MYSQL_USER: 'drupal8' MYSQL_PASSWORD: 'drupal8' command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--default-authentication-plugin=mysql_native_password'] labels: - "traefik.enable=false" cap_add: - SYS_NICE volumes: - db:/var/lib/mysql networks: - project-network volumes: db: networks: default: external: name: common-traefik project-network: name: ${PROJECT_NAME}-network internal: true
It's simplfied a lot, you should have more complicated structure. You should pay attention to networks section at the bottom of the file. Our external network is common-traefik.
I think you've noticed variable ${PROJECT_NAME} – it should have own value for each website.
How to use env files for different instances I will show up in another article.
Check the labels in the configs – they provide the rules for websites in Traefik. And make websites visible by labels values.
- traefik.http.routers.${PROJECT_NAME}.rule=Host(`${PROJECT_NAME}.my-docker.localhost`)
Before running this all stuff we should create a network for it
$ docker network create \ --driver=bridge \ --attachable \ --internal=false \ common-traefik
Проверяем что сеть создана комнадой. В списке должна быть сеть common-traefik
$ docker network ls
Lets run our docker with traefik
$ docker-compose --project-name my-traefik --file ./docker-compose.traefik.yml up -d –build
and after everything downloaded and running up successfully we can check it to be sure.
$ docker ps
Now spin-up our websites:
$ export PROJECT_NAME=website1;docker-compose --project-name ${PROJECT_NAME}--file ./docker-compose.drupal8.yml up -d –build
$ export PROJECT_NAME=website2;docker-compose --project-name ${PROJECT_NAME}--file ./docker-compose.drupal8.yml up -d –build
Great! What's next?
We can check if Traefik's dashboard is working
http://127.0.0.1:8080/dashboard
Check the Routes page and find out there our two instances
http://127.0.0.1:8080/dashboard#/http/routers
paste the urls in browser and smile if it's really works.
http://website1.my-docker.localhost/
http://website2.my-docker.localhost/
Turn that stuff down:
$ export PROJECT_NAME=website1;docker-compose --project-name ${PROJECT_NAME} --file ./docker-compose.drupal8.yml down $ export PROJECT_NAME=website2;docker-compose --project-name ${PROJECT_NAME} --file ./docker-compose.drupal8.yml down $ docker-compose --project-name my-traefik --file ./docker-compose.traefik.yml down
Okay, I agree that copy-paste this stuff in shell is not what you want on your daily job. In some of the next articles I will show you how to use Makefile files.
So, with the help of Traefik and Docker we had a success to run two (or more) websites on local machine, which use the same external virtual network. And both websites are runnong on 80 port with user friendly urls launched from one docker-compose file. Of course this example is just for local environment. Before using it on production you should take care of security!
check the source code here: https://github.com/onesixromcom/docker_traefik_multiple