Alpha Coder

How to run multiple apps on one server using Docker and Traefik

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.

Use case

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

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

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.

Docker Compose

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.

Project setup

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 😉.

website

blog

SaaS app

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.backend and 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.

Traefik dashboard

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.

SSL

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.

NB: I added SSL configs in docker-compose.prod.yml and traefik.toml for use in production.

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.

Subscribe to my newsletter for updates on new articles, courses and more. Enjoy the content on Alpha Coder? Please buy me a coffee.

comments powered by Disqus