Last active
August 19, 2018 19:22
-
-
Save efossas/395f8b81fbd2b4f09a839437ba7b6031 to your computer and use it in GitHub Desktop.
docker-compose.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# set the version of Docker compose to use | |
# avoiding the minor number just uses the latest version, i.e. 3 -> 3.7 | |
version: '3' | |
# our Docker networks. we create just one: 'proxy' | |
# we set 'proxy' to use the 'bridge' driver, which actually happens by default if that field is omitted | |
# since our containers aren't on the 'host' network, they will be isolated from the host until we do some port mapping/exposing | |
# if you don't define a network, docker compose will create a 'default' network and put all services/containers on it | |
networks: | |
proxy: | |
driver: bridge | |
# our Docker named volumes. we create two: 'db-mongo' & 'cache-redis' | |
# when containers are removed, any data they created are destroyed | |
# we attach volumes to containers to make data persistent | |
volumes: | |
db-mongo: | |
cache-redis: | |
# our Docker services. each container becomes a service | |
# in Docker world, a service is just a container with extra info on how to deploy it | |
services: | |
# define the Traefik service | |
traefik: | |
# set the image to use | |
image: 'traefik:alpine' | |
# set the container name, it defaults to the service name if not defined | |
container_name: 'traefik' | |
# expose port 8080 on the container. | |
# Exposed ports are only accessible to other containers on the same Docker network like so -> http://CONTAINER:PORT | |
expose: | |
- 8080 | |
# map ports from host to container, this is how we make our containers accessible from outside the Docker network | |
# map host port 80 to container port 80 for http & ditto for 443 https | |
# so http://127.0.0.1:80 on host routes to port 80 on this container and ditto for port 443. | |
ports: | |
- "80:80" | |
- "443:443" | |
# these are actually 'bind mounts' which are when you mount a host directory to a container directory | |
# they're used to share data from the host to a container, typically for development | |
# they're rarely used in production, since it doesn't scale well (think about binding a single host directory when multiple copies of your service are running on multiple machines) | |
# for production, you usually build that data into the image (except for secrets, which are another matter) | |
volumes: | |
# Traefik auto-detects containers on the network by reading from the Docker socket | |
- /var/run/docker.sock:/var/run/docker.sock | |
# this is the Traefik configuration file | |
- ./traefik.toml:/etc/traefik/traefik.toml | |
# this directory will store self-signed certificates for enabling TLS (https) connections to Traefik | |
- ./ssl:/ssl | |
# labels are just arbitrary metadata | |
# you can use them to search for containers like so: docker ps --filter 'label=LABEL' | |
# since Traefik is connected to the docker.sock, it can read the labels on all containers | |
# so Traefik uses labels to dynamically update its routing | |
labels: | |
# accept connections to entry point 'https' & 'http' (these are defined in traefik.toml) | |
- traefik.frontend.entryPoints=https,http | |
# if the connection matches this front end rule, route the connection to this container | |
# in this case, the connection must have a host name of 'traefik.docker.localhost' | |
- traefik.frontend.rule=Host:traefik.docker.localhost | |
# route frontend rule matches to port 8080 on this container | |
- traefik.port=8080 | |
# enable Traefik to route to this container, this isn't always needed (I'll explain more when going over treafik.toml) | |
- traefik.enable=true | |
# add this container to the 'proxy' network | |
networks: | |
proxy: | |
# the 'crud' service, it's our Node+Express server | |
crud: | |
image: 'efossas/crud' | |
container_name: 'crud' | |
expose: | |
- 80 | |
- 443 | |
volumes: | |
- ./:/crud | |
labels: | |
# the 'INSECURE' part is called a segment label | |
# you use segments when you need to define routing to more than one port on a container | |
- traefik.INSECURE.frontend.entryPoints=https,http | |
- traefik.INSECURE.frontend.rule=Host:crud.docker.localhost | |
- traefik.INSECURE.port=80 | |
## traefik does not support ssl between containers, and doesn't have a rule for matching http or https (https://github.com/containous/traefik/issues/364) | |
## so I've commented this out, but it should give you an idea of how segments work | |
#- traefik.SECURE.frontend.rule=Host:crud.docker.localhost | |
#- traefik.SECURE.port=443 | |
- traefik.enable=true | |
# this service won't start until our 'mongo' & 'redis' service has started | |
depends_on: | |
- mongo | |
- redis | |
networks: | |
proxy: | |
# the 'mongo' service, it's our NoSQL database | |
mongo: | |
image: 'mongo:xenial' | |
container_name: 'mongo' | |
volumes: | |
# this is a 'named volume' | |
# we don't need to directly access the directory storing data, but we want the data to persist | |
# these are definitely used in production | |
- db-mongo:/data/db | |
labels: | |
# we don't want to expose our MongoDB to the world, so we disable Traefik routing here | |
- traefik.enable=false | |
networks: | |
proxy: | |
# the 'redis' service, it's our key=value database for session cacheing | |
redis: | |
image: 'redis:alpine' | |
container_name: 'redis' | |
volumes: | |
- cache-redis:/data | |
labels: | |
- traefik.enable=false | |
networks: | |
proxy: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment