├── .gitignore ├── LICENSE.md ├── README.md ├── Text ├── DraggedImage.png └── index.md ├── Vagrantfile ├── docker-compose.yml └── provision ├── configure-dns-client.yml ├── install-configure-services.yml ├── install-configure-traefik.yml ├── install-dns-server.yml ├── install-docker.yml ├── playbook-client.yml ├── playbook-server.yml └── templates ├── dhclient.conf ├── dnsmasq.conf ├── docker-compose-services.j2 ├── docker-compose-traefik.j2 ├── eth1.cfg └── server-hostsfile /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | *.iml 7 | .idea 8 | **.retry 9 | # User-specific stuff: 10 | .idea/**/workspace.xml 11 | .idea/**/tasks.xml 12 | .idea/dictionaries 13 | 14 | # Sensitive or high-churn files: 15 | .idea/**/dataSources/ 16 | .idea/**/dataSources.ids 17 | .idea/**/dataSources.xml 18 | .idea/**/dataSources.local.xml 19 | .idea/**/sqlDataSources.xml 20 | .idea/**/dynamic.xml 21 | .idea/**/uiDesigner.xml 22 | 23 | # Gradle: 24 | .idea/**/gradle.xml 25 | .idea/**/libraries 26 | 27 | # Mongo Explorer plugin: 28 | .idea/**/mongoSettings.xml 29 | 30 | ## File-based project format: 31 | *.iws 32 | 33 | ## Plugin-specific files: 34 | 35 | # IntelliJ 36 | /out/ 37 | 38 | # mpeltonen/sbt-idea plugin 39 | .idea_modules/ 40 | 41 | # JIRA plugin 42 | atlassian-ide-plugin.xml 43 | 44 | # Crashlytics plugin (for Android Studio and IntelliJ) 45 | com_crashlytics_export_strings.xml 46 | crashlytics.properties 47 | crashlytics-build.properties 48 | fabric.properties 49 | 50 | /playbook.retry 51 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | https://creativecommons.org/licenses/by-sa/4.0/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Intro 3 | 4 | This is the companion project for the [post](https://blog.codecentric.de/en/2017/09/traefik-modern-reverse-proxy/) on the codecentric blog. You can use it to follow along and setup your own environment to play with [Traefik](https://traefik.io/). 5 | 6 | Vagrant uses the ansible provisioner to bootstrap the machines. Have a look into the [provision directory](provision/) for details. The main entry file for the [server](provision/playbook-server.yml) and [client](provision/playbook-client.yml) are a good starting point. 7 | 8 | It will create two virtual machines as a server and a client. The server will host a DNS server and a Traefik server. The client is configured to use the previously created DNS resolver. 9 | 10 | # Setup 11 | 12 | To get started make sure you have [Vagrant](https://www.vagrantup.com/) installed on your machine. Once you are ready to go you can set the environment up: 13 | 14 | `vagrant up` 15 | 16 | This will create the two virtual machines with the name server and client. 17 | 18 | # Usage 19 | 20 | Now you can test the configuration 21 | 22 | `vagrant ssh client` 23 | 24 | Now you work within the context of the test DNS Server and the demo Traefik instance. 25 | 26 | Now you access the whoami docker container on the server 27 | 28 | `curl whoami.server.test` 29 | 30 | # Dashboard 31 | 32 | You can access the traefik Dashboard from the browser of your host machine. 33 | 34 | [localhost:8080](http://localhost:8080/) 35 | 36 | The port 8080 is explicitly exposed from the server. You can only have a look at the dashboard. 37 | 38 | # Configuration Files 39 | 40 | * [docker-compose-services.j2](provision/templates/docker-compose-services.j2) 41 | * [docker-compose-traefik.j2](provision/templates/docker-compose-traefik.j2) 42 | * [server-hostsfile.j2](provision/templates/server-hostsfile) 43 | -------------------------------------------------------------------------------- /Text/DraggedImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcopaga/Treafik-getting-started-article/8935f02cf722d6fdd3e4e03ed3dab794d7c33cee/Text/DraggedImage.png -------------------------------------------------------------------------------- /Text/index.md: -------------------------------------------------------------------------------- 1 | Traefik - The modern reverse proxy 2 | A getting started guide 3 | 4 | # Intro 5 | 6 | Imagine you have a set of microservices or applications that you want to publish to the world. There are several alternatives out there that you can choose from. Most of the reverse proxies were created when container technology was not around, so you have to jump through some loops to get going. As an broadly used example we will have a peak at how to configure nginx and some of it’s downsides. To get our hands dirty we have a more detailed walk-through of the modern, dynamic Traefik reverse proxy which we will use to deploy some services. 7 | 8 | # Best in class before Docker: Nginx 9 | 10 | There is quite a number of Container Deployments out there that use [nginx](http://nginx.org/) as a front end. The configuration is easy to read and write and the C style syntax gives you a cozy feeling. A simple config to deploy a service might look like this: 11 | 12 | worker_processes 4; 13 | events { worker_connections 1024; } 14 | 15 | http { 16 | 17 | upstream upstream-servers { 18 |             least_conn; 19 |               server container1:80 weight=10 max_fails=3 fail_timeout=30s; 20 |               server container2:80 weight=10 max_fails=3 fail_timeout=30s; 21 |               server container1280 weight=10 max_fails=3 fail_timeout=30s; 22 |         } 23 |           24 |         server { 25 |               listen 80; 26 |           27 |               location / { 28 |                 proxy_pass http://upstream-servers; 29 |                 proxy_http_version 1.1; 30 |                 proxy_set_header Host $host; 31 |                 proxy_cache_bypass $http_upgrade; 32 |               } 33 |         } 34 | } 35 | 36 | With this config we created a simple HTTP reverse Proxy on port 80. Nginx will answer the requests by forwarding these to the upstream servers. The container with the least number of active connections will be chosen from the pool. Nice configuration. Plain and easy to read. 37 | 38 | One thing you will encounter when you deploy nginx in a mutable container enviroment is that you can’t replace containers without at least reloading the nginx configuration although the container DNS name is still the same. Nginx will cache the IP address to the container and you have to manually take care of it. You can work around this problem in many ways but still you have to take care of it. 39 | Don't get me wrong: I don't want to pick on nginx. I like it and used it a lot before I switched to [Traefik](https://traefik.io/) as my go to solution. 40 | 41 | # Traefik 42 | 43 | There’s a more modern reverse proxy around that is able to handle dynamic container environments: [Traefik](https://traefik.io/). It is a small application written in [GO](https://golang.org/ "Go") tailored for the new challenges. You can use it as a frontend in a variety of environments. The simpler ones are [Docker](https://www.docker.com/) and Docker Swarm up to the more complex ones like [Apache Mesos](https://mesos.apache.org/) or [Kubernetes](https://kubernetes.io/ "Kuberntes"). You can even read meta data from directory services like [etcd](https://coreos.com/etcd/ "etcd") or [Consul](https://www.consul.io/). 44 | 45 | Back to our application we want to deploy. Let’s imagine we have a set of services that are described in a [Docker Compose ](https://docs.docker.com/compose/)file. We can wire up our services and deploy these. Here we can have a look at a simple configuration: 46 | 47 | version: '3.1' 48 | services: 49 | whoami: 50 | image: emilevauge/whoami 51 | restart: 52 | always 53 | ports: 54 | - "80:80" 55 | 56 | This configuration will start the [whoami](https://hub.docker.com/r/emilevauge/whoami/) test image that will allow us to see our requests in a kind of echo chamber. You can start it with `docker-compose up` and call it with your browser. How can we deploy it on a specific virtual host? Let’s extend the configuration a bit by adding Docker labels. 57 | 58 | version: '3.1' 59 | services: 60 | whoami: 61 | image: emilevauge/whoami 62 | networks: 63 | - web 64 | labels: 65 | - "traefik.backend=whoami" 66 | - "traefik.frontend.rule=Host:whoami.server.test" 67 | restart: 68 | always 69 | networks: 70 | web: 71 | external: 72 | name: traefik_webgateway 73 | 74 | This is the configuration needed for Traefik to deploy our service at http://whoami.server.test . Pretty straight forward. 75 | 76 | When you followed the example closely you might ask where Traefik is involved and you are right. Next we need to spin Traefik itself up: 77 | 78 | version: '2' 79 | 80 | services: 81 | proxy: 82 | image: marcopaga/traefik:1.3.5.2 83 | command: --web --docker --docker.domain=server.test --logLevel=INFO 84 | networks: 85 | - webgateway 86 | ports: 87 | - "80:80" 88 | - "8080:8080" 89 | volumes: 90 | - /var/run/docker.sock:/var/run/docker.sock 91 | - /dev/null:/traefik.toml 92 | restart: 93 | always 94 | 95 | networks: 96 | webgateway: 97 | driver: bridge 98 | 99 | The config above takes care of starting Traefik and will connect to the hosting docker deamon to retrieve the needed meta data. It will scan for docker containers that are marked with labels and will publish the services accordingly. The connection is kept so that changes will be reflected without any delay. 100 | 101 | Both services are wired together using a docker network called call webgateway that is prefixed by the project name. If no project name is specified the name is inferred by the directory name where the compose file is located. 102 | 103 | You can find more configuration options on the documentation site: [https://docs.traefik.io/toml/#docker-backend](https://docs.traefik.io/toml/#docker-backend "Docker Backend"). This takes you straight to a backend configuration part. Below that there is a list of Docker labels that can be used to further configure the publishing of the services. Currently we just used traefik.backend and traefik.frontend.rule in the sample above but you can find more. 104 | 105 | Once Traefik and the service are up you can connect to the service and test the deployment. Make sure you first start Traefik in this example because the config provides the network the services can connect to. 106 | Have a look at the built in dashboard by pointing your browser to: `http://localhost:8080/` 107 | ![](DraggedImage.png) 108 | Here you can see what services are deployed and how these are configured. You see that our service is available as whoami.server.test. But since we don’t have a DNS record pointing from this name to our localhost we need to manually set the [Host header](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23) and call the localhost. 109 | 110 | > curl -H Host:whoami.server.test http://localhost -v 111 | 112 | Once you entered the command you can see the request that is being sent to Traefik and the response that will be returned. The result will look similar to: 113 | 114 | ~ curl -H Host:whoami.server.test http://localhost 115 | Hostname: 2f3de5835785 116 | IP: 127.0.0.1 117 | IP: 172.21.0.3 118 | GET / HTTP/1.1 119 | Host: whoami.server.test 120 | User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0 121 | Accept: */* 122 | Accept-Encoding: gzip 123 | Referer: 124 | X-Forwarded-For: 172.21.0.1 125 | X-Forwarded-Host: whoami.server.test 126 | X-Forwarded-Proto: http 127 | X-Forwarded-Server: b2554c36ab87 128 | 129 | # DNS 130 | 131 | To fully enjoy the power of Traefik you need to take care of the DNS records of your deployments. But this is a one time setup so don’t worry about it too much. One deployment we run at a customer consists of two DNS records per host. One is an A record pointing to the IP Address of the host. And the other is a CNAME record that catches all virtual hosts below this one and forwards it to the A entry. This is a simple way to locate our services. 132 | Just a little example to show you the setup: 133 | 134 | server.test A 172.16.2.10 135 | *.server.test CNAME server.test 136 | 137 | This will allow us to reach our server as server.test and whatever.server.test, youwant.server.test. When you access the site with your favorite tool like a REST service, httpie or a browser the client will forward the target host in a HTTP header called Host. Traefik will find the right container based on this header to forward the request to. 138 | 139 | One advantage of using virtual hosts is that you don’t need to take extra care of redirects in your web application. We ran into problems when using relative paths for deployments because nobody thought about that being an option. Once you have your environment set up you can deploy the services as you like. 140 | 141 | # Scaling out 142 | 143 | Deploying a single container is easy and we could achieve it without any great effort. But what about scaling out? What part of the config do I have to change? The simple answer is: You don’t have to change your config. Just simply spin up more containers and that’s it. In our simple example: 144 | 145 | docker-compose scale whoami=4 146 | 147 | This command will spin up four containers that will get added to the load balancer instantly. You can verify it by hitting the endpoint repeatedly and see the container name change and by having a look at the dashboard that is located on port 8080. 148 | 149 | # Sticky Sessions 150 | 151 | Clearly I would strive for a stateless application backend that can be scaled independently and without any restrictions regarding the service endpoint. 152 | Sometimes you don't have the freedom because you are running a session based application that doesn't distribute the sessions in a cluster of servers. Or - if you think more of REST services - you heavily use caching of resources and you want your sessions pinned to a specific container. No matter why you want your clients to be pinned to a specific Docker container, there is an easy configuration switch to handle it: 153 | 154 | traefik.backend.loadbalancer.sticky=true 155 | 156 | This will check for a session cookie with a specific backend as a value. If the cookie is present and the backend is up the request will be forwarded there. If the backend is down another is chosen. 157 | Be sure to use the upcoming 1.4 version for this feature or my patched Docker image (marcopaga/traefik:1.3.5.2) if you want to use this feature. Before these versions the cookie path wasn't specified so that clients tended to drop the cookie once in while depending on the request path. 158 | 159 | # Closing 160 | I’m pretty sure: It became clear how simple life can be when it comes to the deployment of your services and web applications with Traefik. -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | 3 | config.vm.box = "ubuntu/trusty64" 4 | config.ssh.insert_key = false 5 | 6 | config.vm.provider :virtualbox do |v| 7 | v.memory = 512 8 | v.cpus = 2 9 | v.customize ["modifyvm", :id, "--ioapic", "on"] 10 | end 11 | 12 | config.vm.define "server" do |s| 13 | s.vm.hostname = "server" 14 | s.vm.network :private_network, ip: "172.16.2.10", auto_config: false, virtualbox__intnet: "isolated_network" 15 | s.vm.network "forwarded_port", guest: 8080, host: 8080 16 | 17 | s.vm.provision "ansible" do |ansible| 18 | ansible.playbook = "provision/playbook-server.yml" 19 | ansible.sudo = true 20 | end 21 | end 22 | 23 | config.vm.define "client" do |c| 24 | c.vm.hostname = "client" 25 | c.vm.network :private_network, ip: "172.16.2.11", auto_config: false, virtualbox__intnet: "isolated_network" 26 | 27 | c.vm.provision "ansible" do |ansible| 28 | ansible.playbook = "provision/playbook-client.yml" 29 | ansible.sudo = true 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | traefik: 4 | image: traefik:1.5.2 5 | command: --web --docker --docker.domain=docker.localhost --logLevel=INFO 6 | ports: 7 | - "80:80" 8 | - "8080:8080" 9 | volumes: 10 | - /var/run/docker.sock:/var/run/docker.sock 11 | - /dev/null:/traefik.toml 12 | labels: 13 | - "traefik.enable=false" 14 | whoami: 15 | image: emilevauge/whoami 16 | labels: 17 | - "traefik.backend=whoami" 18 | - "traefik.frontend.rule=Host:whoami.docker.localhost" 19 | -------------------------------------------------------------------------------- /provision/configure-dns-client.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ignore DNS Servers from DHCP 3 | copy: src=templates/dhclient.conf dest=/etc/dhcp/dhclient.conf owner=root group=root mode=0644 4 | 5 | - name: Use our DNS server 6 | shell: "echo 'nameserver 172.16.2.10' >> /etc/resolvconf/resolv.conf.d/head" 7 | 8 | - name: Ensure Resolvconf service is installed and restarted 9 | service: 10 | name: resolvconf 11 | state: restarted 12 | enabled: yes 13 | 14 | - name: Get a new DHCP Lease without DNS information 15 | shell: "dhclient -r; dhclient" 16 | 17 | - name: Template network config for eth1 18 | template: 19 | src: templates/eth1.cfg 20 | dest: "/etc/network/interfaces.d/eth1.cfg" 21 | owner: root 22 | group: root 23 | mode: 644 24 | 25 | - name: Bring eth1 up with correct config 26 | shell: "ifdown eth1 && ifup eth1" -------------------------------------------------------------------------------- /provision/install-configure-services.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create folder for the docker compose files 3 | file: 4 | path={{services_docker_build_path}} 5 | state=directory 6 | owner=root 7 | 8 | - name: Template Services docker-compose.yml 9 | template: 10 | src: templates/docker-compose-services.j2 11 | dest: "{{services_docker_build_path}}/docker-compose.yml" 12 | owner: root 13 | group: root 14 | mode: 644 15 | 16 | - name: Stop Services if they're up 17 | shell: docker-compose stop 18 | args: 19 | chdir: "{{services_docker_build_path}}" 20 | ignore_errors: yes 21 | 22 | - name: Fire up Services 23 | shell: docker-compose --project-name {{services_project_name}} up -d 24 | args: 25 | chdir: "{{services_docker_build_path}}" 26 | 27 | -------------------------------------------------------------------------------- /provision/install-configure-traefik.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create folder for the docker compose files 3 | file: 4 | path={{traefik_docker_build_path}} 5 | state=directory 6 | owner=root 7 | 8 | - name: Template Traefik docker-compose.yml 9 | template: 10 | src: templates/docker-compose-traefik.j2 11 | dest: "{{traefik_docker_build_path}}/docker-compose.yml" 12 | owner: root 13 | group: root 14 | mode: 644 15 | 16 | - name: Stop traefik if it's up 17 | shell: docker-compose stop 18 | args: 19 | chdir: "{{traefik_docker_build_path}}" 20 | ignore_errors: yes 21 | 22 | - name: Fire up Traefik 23 | shell: docker-compose --project-name {{traefik_project_name}} up -d 24 | args: 25 | chdir: "{{traefik_docker_build_path}}" 26 | 27 | - name: Check if Traefik Port ist available on the machine 28 | wait_for: 29 | host: localhost 30 | port: 80 31 | connect_timeout: 30 32 | timeout: 60 33 | 34 | 35 | -------------------------------------------------------------------------------- /provision/install-dns-server.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install dnsmasq (Simple DNS resolver) 3 | apt: 4 | name: dnsmasq 5 | state: latest 6 | 7 | - name: Ignore DNS Servers from DHCP 8 | copy: src=templates/dhclient.conf dest=/etc/dhcp/dhclient.conf owner=root group=root mode=0644 9 | 10 | - name: Set dnsmasq configuration 11 | copy: src=templates/dnsmasq.conf dest="/etc/dnsmasq.conf" owner=root group=root mode=644 12 | 13 | - name: Set our hostsfile that is used by dnsmasq to serve DNS requests 14 | copy: src=templates/server-hostsfile dest="/etc/hosts" owner=root group=root mode=644 15 | 16 | - name: Restart dnsmasq 17 | service: 18 | name: dnsmasq 19 | state: restarted 20 | enabled: yes 21 | 22 | - name: Template network config for eth1 23 | template: 24 | src: templates/eth1.cfg 25 | dest: "/etc/network/interfaces.d/eth1.cfg" 26 | owner: root 27 | group: root 28 | mode: 644 29 | 30 | - name: Bring eth1 up with correct config 31 | shell: "ifdown eth1 && ifup eth1" -------------------------------------------------------------------------------- /provision/install-docker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: update apt and autoremove 3 | apt: 4 | update_cache: yes 5 | cache_valid_time: 3600 6 | autoremove: yes 7 | 8 | - name: Install linux-image-extra-* for Ubuntu Trusty 14.04 (see https://docs.docker.com/engine/installation/linux/ubuntu/#recommended-extra-packages-for-trusty-1404) 9 | apt: 10 | name: linux-image-extra-3.13.0-106-generic 11 | state: latest 12 | sudo: yes 13 | 14 | - name: Install linux-image-extra-* for Ubuntu Trusty 14.04 (see https://docs.docker.com/engine/installation/linux/ubuntu/#recommended-extra-packages-for-trusty-1404) 15 | apt: 16 | name: linux-image-extra-virtual 17 | state: latest 18 | sudo: yes 19 | 20 | - name: Install apt-transport-https (see https://docs.docker.com/engine/installation/linux/ubuntu/#recommended-extra-packages-for-trusty-1404) 21 | apt: 22 | name: apt-transport-https 23 | state: latest 24 | sudo: yes 25 | 26 | - name: Install ca-certificates (see https://docs.docker.com/engine/installation/linux/ubuntu/#recommended-extra-packages-for-trusty-1404) 27 | apt: 28 | name: ca-certificates 29 | state: latest 30 | sudo: yes 31 | 32 | - name: Install software-properties-common (see https://docs.docker.com/engine/installation/linux/ubuntu/#recommended-extra-packages-for-trusty-1404) 33 | apt: 34 | name: software-properties-common 35 | state: latest 36 | sudo: yes 37 | 38 | - name: Add Docker apt key 39 | apt_key: 40 | url: https://download.docker.com/linux/ubuntu/gpg 41 | id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 42 | state: present 43 | register: add_repository_key 44 | ignore_errors: true 45 | 46 | - name: Ensure curl is present (on older systems without SNI). 47 | apt: 48 | name: curl 49 | state: latest 50 | sudo: yes 51 | when: add_repository_key|failed 52 | 53 | - name: Add Docker apt key (alternative for older systems without SNI). 54 | shell: "curl -sSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -" 55 | args: 56 | warn: no 57 | when: add_repository_key|failed 58 | 59 | - name: Add docker apt repo 60 | apt_repository: 61 | repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ansible_lsb.codename}} stable" 62 | update_cache: yes 63 | sudo: yes 64 | 65 | - name: Install Docker apt package 66 | apt: 67 | pkg: docker-ce 68 | state: latest 69 | update_cache: yes 70 | sudo: yes 71 | 72 | - name: Ensure Docker service is installed and restarted 73 | service: 74 | name: docker 75 | state: restarted 76 | enabled: yes 77 | 78 | - name: Install Docker Compose (if configured). 79 | get_url: 80 | url: https://github.com/docker/compose/releases/download/1.15.0/docker-compose-Linux-x86_64 81 | dest: /usr/local/bin/docker-compose 82 | mode: 0755 83 | 84 | - name: Add vagrant user to docker group. 85 | user: 86 | name: vagrant 87 | groups: docker 88 | append: yes 89 | become: yes -------------------------------------------------------------------------------- /provision/playbook-client.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | become: yes 4 | gather_facts: true 5 | vars: 6 | ip_address: 172.16.2.11 7 | 8 | pre_tasks: 9 | - name: Update apt cache if needed. 10 | apt: update_cache=yes cache_valid_time=3600 11 | 12 | tasks: 13 | - include: configure-dns-client.yml 14 | -------------------------------------------------------------------------------- /provision/playbook-server.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | become: yes 4 | gather_facts: true 5 | vars: 6 | traefik_docker_build_path: /tmp/traefik-docker-build 7 | services_docker_build_path: /tmp/services-docker-build 8 | traefik_project_name: traefik 9 | services_project_name: services 10 | ip_address: 172.16.2.10 11 | dns_alias: server.test 12 | 13 | pre_tasks: 14 | - name: Update apt cache if needed. 15 | apt: update_cache=yes cache_valid_time=3600 16 | 17 | tasks: 18 | - include: install-docker.yml 19 | - include: install-dns-server.yml 20 | - include: install-configure-traefik.yml 21 | - include: install-configure-services.yml 22 | -------------------------------------------------------------------------------- /provision/templates/dhclient.conf: -------------------------------------------------------------------------------- 1 | option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; 2 | 3 | #send host-name "andare.fugue.com"; 4 | send host-name = gethostname(); 5 | #send dhcp-client-identifier 1:0:a0:24:ab:fb:9c; 6 | #send dhcp-lease-time 3600; 7 | #supersede domain-name "fugue.com home.vix.com"; 8 | prepend domain-name-servers 127.0.0.1; 9 | request subnet-mask, broadcast-address, time-offset, routers, 10 | host-name, netbios-name-servers, netbios-scope, interface-mtu, 11 | rfc3442-classless-static-routes, ntp-servers, 12 | dhcp6.fqdn, dhcp6.sntp-servers; -------------------------------------------------------------------------------- /provision/templates/dnsmasq.conf: -------------------------------------------------------------------------------- 1 | # Serve requests from eth0 and eth1 2 | interface=eth0 3 | interface=eth1 4 | 5 | # For debugging purposes, log each DNS query as it passes through 6 | # dnsmasq. 7 | log-queries -------------------------------------------------------------------------------- /provision/templates/docker-compose-services.j2: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | 3 | services: 4 | whoami: 5 | image: emilevauge/whoami 6 | networks: 7 | - web 8 | labels: 9 | - "traefik.backend=whoami" 10 | - "traefik.frontend.rule=Host:whoami.{{dns_alias}}" 11 | - "traefik.backend.loadbalancer.sticky=true" 12 | restart: 13 | always 14 | 15 | networks: 16 | web: 17 | external: 18 | name: {{traefik_project_name}}_webgateway -------------------------------------------------------------------------------- /provision/templates/docker-compose-traefik.j2: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | 3 | services: 4 | proxy: 5 | image: traefik:1.4 6 | command: --web --docker --docker.domain={{dns_alias}} --logLevel=WARN 7 | networks: 8 | - webgateway 9 | ports: 10 | - "80:80" 11 | - "8080:8080" 12 | volumes: 13 | - /var/run/docker.sock:/var/run/docker.sock 14 | - /dev/null:/traefik.toml 15 | restart: 16 | always 17 | 18 | networks: 19 | webgateway: 20 | driver: bridge 21 | -------------------------------------------------------------------------------- /provision/templates/eth1.cfg: -------------------------------------------------------------------------------- 1 | auto eth1 2 | iface eth1 inet static 3 | address {{ ip_address }} 4 | netmask 255.255.0.0 -------------------------------------------------------------------------------- /provision/templates/server-hostsfile: -------------------------------------------------------------------------------- 1 | 172.16.2.10 server.test server 2 | 172.16.2.10 whoami.server.test server 3 | 172.16.2.10 api.server.test server 4 | 5 | 172.16.2.11 client.test client 6 | 7 | 127.0.0.1 server server 8 | 127.0.0.1 localhost 9 | 10 | # The following lines are desirable for IPv6 capable hosts 11 | ::1 ip6-localhost ip6-loopback 12 | fe00::0 ip6-localnet 13 | ff00::0 ip6-mcastprefix 14 | ff02::1 ip6-allnodes 15 | ff02::2 ip6-allrouters 16 | ff02::3 ip6-allhosts --------------------------------------------------------------------------------