Running multiple apps on a single machine has never been easier! In this tutorial, I’ll show you how to run 3 apps on one server using Docker and Traefik.
Say you’re low on cash and can only rent one server, you can run your website, blog and SaaS app on the same machine (what we’ll do in this tutorial). Or you can run an API (back-end) and SPA (front-end). You can even run two different websites (example1.com and example2.com) if you want.
Docker is the most widely used containerization software today. It allows you bundle code with it’s config and dependencies, making it easy and seamless to deploy your apps on any machine (or several machines). It also helps in development by providing a consistent environment for collaborators on a project. More info here: https://docs.docker.com.
Traefik is a HTTP reverse proxy and load balancer that integrates with Docker, Swarm, Kubernetes among other orchestration tools. You can learn more here: https://docs.traefik.io.
We’ll be using Docker via Docker Compose. Docker Compose makes it easy to run multi-container Docker applications. You can configure all your containers in one file and run them at once with a single command. Read more here: https://docs.docker.com/compose.
The 3 apps we’ll be running are a website (static site), a blog and a SaaS app (dasboard-ish). For the sake of demonstration, I just downloaded HTML templates online 👀. So I have a landing page template, blog template and dashboard template. They’ll all be served with Ngnix 😉.
Here’s the project repo: https://github.com/nicholaskajoh/jack.
Each app is put in it’s own folder, with its own Dockerfile. The Dockerfiles are identical since we’re basically just serving static files in all the apps.
1 2 3
# Dockerfile FROM nginx:alpine COPY . /usr/share/nginx/html
The docker compose file brings everything together under one roof. Here’s how it looks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
# docker-compose.yml version: "3" services: traefik: image: traefik command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG ports: - "80:80" - "8080:8080" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock - /dev/null:/traefik.toml app: build: ./app volumes: - ./app:/usr/share/nginx/html labels: - "traefik.backend=app-be" - "traefik.frontend.rule=Host:app.localhost" blog: build: ./blog volumes: - ./blog:/usr/share/nginx/html labels: - "traefik.backend=blog-be" - "traefik.frontend.rule=Host:blog.localhost" website: build: ./website volumes: - ./website:/usr/share/nginx/html labels: - "traefik.backend=website-be" - "traefik.frontend.rule=Host:localhost"
As can be seen, traefik itself is run in a container. The domain is set to localhost and the ports 80, 8080 and 443 are published. The web flag (
--web) under command parameter tells traefik to run its API dashboard which will be exposed on port 8080.
Traefik can be configured using a traefik.toml file. It can also pick configs from service labels. As such, we specified the
traefik.frontend.rule configs using labels.
traefik.backend specifies the service to handle requests from
traefik.frontend.rule. So if we go to app.localhost, we will be served content from the app service. Same with localhost and website, and blog.localhost and blog.
Try it out: clone Jack, run
docker-compose up and visit localhost, app.localhost and blog.localhost.
The Traefik dashboard displays useful information including the available front-ends and back-ends, and the health of the containers. You can password protect the dashboard so only authorized persons can access it.
Traefik can handle SSL for you automatically. This guide (https://docs.traefik.io/user-guide/docker-and-lets-encrypt) explains the configuration process using Let’s Encrypt.
Scaling and load balancing
Traefik load balances multiple instances of a given service automatically. You can use the scale flag/parameter in docker compose to run multiple instances of your containers.