Sometimes the easiest and quickest way to try (or even deploy) a new service is by using the recommended docker-compose-setup that they often have as an example. But if you have an existing infrastructure, like we do with the great mother of all self-hosting ansible playbooks, this isn't always easy to integrate. In particular when that infrastructure is managed and started and stopped independently from the additional docker-compose you intend to add. Lucky, who is running their out-most proxy using traefik, because with just a few extra labels your docker-compose becomes available TLS-certs included.
Fortunately for us the MASH-playbook uses traefik and so adding a Ghost setup for testing was quick and easy. Let's look at the docker-compose (for our fictional blog.example.org
-address) and then we'll explain some of the specific aspects to address:
version: '3.1'
services:
ghost:
image: ghost:5-alpine
restart: unless-stopped
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: SOME_PRIVATE_ROOT_PASSWORD
database__connection__database: ghost
# this url value is just an example, and is likely wrong for your environment!
url: https://blog.example.org
volumes:
- ./data/ghost:/var/lib/ghost/content
networks:
default:
traefik:
aliases:
- blog-example-org
labels:
- traefik.enable=true
- traefik.docker.network=traefik
- traefik.http.routers.blog-example-org.rule=Host(`blog.example.org`)
- traefik.http.services.blog-example-org.loadbalancer.server.port=2368
- traefik.http.routers.blog-example-org.entrypoints=web-secure
- traefik.http.routers.blog-example-org.tls=true
- traefik.http.routers.blog-example-org.tls.certResolver=default
- traefik.http.routers.blog-example-org.service=blog-example-org
db:
image: mysql:8.0
restart: unless-stopped
networks:
- default
environment:
MYSQL_ROOT_PASSWORD: SOME_PRIVATE_ROOT_PASSWORD
MYSQL_DATABASE: ghost
volumes:
- ./data/db:/var/lib/mysql
networks:
traefik:
external: true
default:
external: false
Alright, there's a few things here that have changes compared to the default example from ghost. We will be ignoring the specific Ghost and MySQL changes as they aren't that relevant but are only included for completeness.
The networks
First and foremost, we have the additional networks
-section a the bottom of the configuration with two networks: default
which we will use for this specific service and the other that is bridging to the traefik
-service, which is marked as external: true
telling docker to use the existing set up network. This must the the network the dockerized traefik
is using. In the case of MASH this is just called traefik
as well.
Secondly we need to the networks
-section to both our services, where any internal service is only on the default
network and the exposed service must also be on the traefik
-network. Here we also give it some specific DNS name within that network for traefik to route the traffic to.
the traefik
labels
When traefik
is set up to use docker-labels, which is the case in our MASH setup, we can just label our service with a view fields and the traefik
service will automatically recognize and configure the routing appropriately. Let's go through them one by one:
-
traefik.enable=true
: to configure traefik to route this one. Depending on your setup this might not be needed -
traefik.docker.network=traefik
: the network traefik is on -
traefik.http.routers.blog-example-org.rule=Host(\
blog.example.org)
: the actual hostname we want this service to be available under between the final ticks. Note that we are creating a custom traefik-router
for this calledblog-example-org
, all the following configuration is also using that router prefix: -
traefik.http.services.blog-example-org.loadbalancer.server.port=2368
: the port on this service the traffic should be routed to -
traefik.http.routers.blog-example-org.entrypoints=web-secure
: if the traefik has multiple outsid eendpoints, which ones to serve - in the MASH case we want this to be available athttps
, which is namedweb-secure
in our setup. -
traefik.http.routers.blog-example-org.tls=true
: to enable TLS for this router -
traefik.http.routers.blog-example-org.tls.certResolver=default
: use the default DNS cert resolving functionality. In MASH this means we are using lets-encrypt certification -
traefik.http.routers.blog-example-org.service=blog-example-org
: the service to route the traffic to. The value is the dns-alias we gave in the network configuration before.
up and go
And that's about it. Assuming the DNS name already resolves to your server and your traefik is already running just doing a docker compose up -d
and a short time later (if it needs to fetch the certificates for the first time), the service will be routed through and be available at blog.example.org
. Neat!
Top comments (0)