Sometimes you need to use a reverse proxy to protect expose your app directly on web, to do it several tools comes up (Nginx,Apache,AWS ELB …).
In this article we will be interested to Traefik
First step :
Traefik need a config file traefik.toml :
defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":80"
#config of host traefik with http auth basic
[web]
address = ":8080"
[web.auth.basic]
users = ["admin:$apr1$o1HmXW0i$wWgVewL1kLu9gaqmMDh6d/"]
[docker]
endpoint = "unix:///var/run/docker.sock"
#choose local domain you want
domain = "dev.local"
watch = true
exposedbydefault = true
What we’re going to do is configure a docker network – let’s call it traefik – that every service will be placed into that’s actually connected to the internet. Since this network will be service agnostic we’ll create it as an external network directly with the docker cli.
docker network create traefik
Now lets create a new docker-compose file for traefik that looks like.
version: '3.2'
services:
proxy:
image: traefik
networks:
- traefik
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- "$PWD/traefik.toml:/etc/traefik/traefik.toml"
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
labels:
- "traefik.frontend.rule=Host:traefik.dev.local"
- "traefik.port=8080"
- "traefik.backend=traefik"
- "traefik.frontend.entryPoints=http"
This create a new container based on the official traefik image, which is restarted automatically if it stops, exposes ports 80 (HTTP), 443 (HTTPS) and 8080 (dashboard) directly, has a few mounted volumes and is part of the web network. For the network to be picked up by docker-compose we need to explicitly list it in a networks section below.
Running Other Services
we’re going to configure Ruby on Rails and Postgres.
Postgres
db:
image: postgres
volumes:
- ./postgres/data:/var/lib/postgresql/data
networks:
- traefik
RubyOnRails:
Create a ruby_app in the root directory and clone the rails app inside, before docker-compose you should create a dockerfile and entrypoint.sh file for your app like this one.
Entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
Dockerfile:
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
Docker-compose ROR:
web:
build: ./ruby_app
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- ./ruby_app:/app
ports:
- "3000:3000"
networks:
- traefik
depends_on:
- db
labels:
- "traefik.frontend.rule=Host:rails.dev.local"
- "traefik.port=3000"
- "traefik.backend=rails"
- "traefik.frontend.entryPoints=http"
Global docker-compose:
version: '3.2'
services:
db:
image: postgres
volumes:
- ./postgres/data:/var/lib/postgresql/data
networks:
- traefik
web:
build: ./ruby_app
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- ./ruby_app:/app
ports:
- "3000:3000"
networks:
- traefik
depends_on:
- db
labels:
- "traefik.frontend.rule=Host:rails.dev.local"
- "traefik.port=3000"
- "traefik.backend=rails"
- "traefik.frontend.entryPoints=http"
proxy:
image: traefik
networks:
- traefik
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- "$PWD/traefik.toml:/etc/traefik/traefik.toml"
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
labels:
- "traefik.frontend.rule=Host:traefik.dev.local"
- "traefik.port=8080"
- "traefik.backend=traefik"
- "traefik.frontend.entryPoints=http"
networks:
traefik:
external:
name: traefik
NB: You should add hosts : (Linux : /etc/hosts)
- 127.0.0.1 traefik.dev.local
- 127.0.0.1 rails.dev.local
It’s time to run your docker-compose:
docker-compose up -d
If all container run correctly test host on your browser: