├── LICENSE ├── README.md ├── docker-compose.nginx.yml ├── docker-compose.traefik-ssl.yml ├── docker-compose.traefik.yml ├── nginx ├── Dockerfile ├── default.conf ├── nginx.conf └── nginx.sh ├── traefik-ssl ├── acme.json ├── traefik.toml └── traefik_dynamic.toml └── traefik └── traefik.toml /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alex Hyett 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # traefik-vs-nginx-docker 2 | 3 | Examples showing how to use Traefik and Nginx for Reverse Proxy. 4 | 5 | This repository is to complement my blog post on this topic, [Traefik vs Nginx for Reverse Proxy with Docker on a Raspberry Pi](https://www.alexhyett.com/traefik-vs-nginx-docker-raspberry-pi). 6 | 7 | ## NGINX Example 8 | 9 | ``` 10 | docker-compose -f docker-compose.nginx.yml up 11 | ``` 12 | 13 | You will then be able to access whoami from http://localhost/whoami (or replace localhost with the IP address of your Raspberry Pi if accessing it remotely) 14 | 15 | ## Traefik Example 16 | 17 | For traefik I have included 2 version, one insecure version for local use and a SSL password protected version. 18 | 19 | ### Insecure version 20 | 21 | ``` 22 | docker-compose -f docker-compose.traefik.yml up 23 | ``` 24 | 25 | You will then be able to access whoami from http://localhost/whoami and the Traefik dashboard from http://localhost:8080 (or replace localhost with the IP address of your Raspberry Pi if accessing it remotely) 26 | 27 | ### Secure version 28 | 29 | You need to replace `youremailhere` in `traefik.toml` and `yourdomain.com` in `traefik_dynamic.toml` for this to work. 30 | 31 | ``` 32 | docker-compose -f docker-compose.traefik-ssl.yml up 33 | ``` 34 | 35 | You will then be able to access whoami from https://localhost/whoami and the Traefik dashboard from https://localhost/dashboard (or replace localhost with the IP address of your Raspberry Pi or `yourdomain.com` if accessing it remotely). 36 | 37 | The username is `admin` and the password is `admin`. Read my blog post on how to set this up, [Traefik vs Nginx for Reverse Proxy with Docker on a Raspberry Pi](https://www.alexhyett.com/traefik-vs-nginx-docker-raspberry-pi) 38 | -------------------------------------------------------------------------------- /docker-compose.nginx.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | services: 3 | nginx: 4 | build: nginx 5 | restart: 'unless-stopped' 6 | networks: 7 | - pi 8 | ports: 9 | - '80:80' 10 | depends_on: 11 | - whoami 12 | 13 | whoami: 14 | image: 'traefik/whoami' 15 | restart: 'unless-stopped' 16 | networks: 17 | - pi 18 | 19 | networks: 20 | pi: 21 | external: true 22 | -------------------------------------------------------------------------------- /docker-compose.traefik-ssl.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | services: 3 | traefik: 4 | image: 'traefik:2.3' 5 | container_name: 'traefik' 6 | restart: 'unless-stopped' 7 | ports: 8 | - '80:80' 9 | - '443:443' 10 | volumes: 11 | - '/var/run/docker.sock:/var/run/docker.sock:ro' 12 | - './traefik-ssl/traefik.toml:/traefik.toml' 13 | - './traefik-ssl/traefik_dynamic.toml:/traefik_dynamic.toml' 14 | - './traefik-ssl/acme.json:/acme.json' 15 | networks: 16 | - pi 17 | 18 | whoami: 19 | image: 'traefik/whoami' 20 | restart: 'unless-stopped' 21 | labels: 22 | - 'traefik.enable=true' 23 | - 'traefik.http.routers.whoami.rule=PathPrefix(`/whoami{regex:$$|/.*}`)' 24 | - 'traefik.http.services.whoami.loadbalancer.server.port=80' 25 | - 'traefik.http.routers.whoami.middlewares=simpleAuth@file' 26 | networks: 27 | - pi 28 | 29 | networks: 30 | pi: 31 | external: true 32 | -------------------------------------------------------------------------------- /docker-compose.traefik.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | services: 3 | traefik: 4 | image: 'traefik:2.3' 5 | container_name: 'traefik' 6 | restart: 'unless-stopped' 7 | ports: 8 | - '80:80' 9 | - '8080:8080' 10 | volumes: 11 | - '/var/run/docker.sock:/var/run/docker.sock:ro' 12 | - ./traefik/traefik.toml:/traefik.toml 13 | networks: 14 | - pi 15 | 16 | whoami: 17 | image: 'traefik/whoami' 18 | restart: 'unless-stopped' 19 | labels: 20 | - 'traefik.enable=true' 21 | - 'traefik.http.routers.whoami.rule=PathPrefix(`/whoami{regex:$$|/.*}`)' 22 | - 'traefik.http.services.whoami.loadbalancer.server.port=80' 23 | networks: 24 | - pi 25 | 26 | networks: 27 | pi: 28 | external: true 29 | -------------------------------------------------------------------------------- /nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim 2 | 3 | # Default timezone to UTC 4 | ENV TMZ UTC 5 | 6 | COPY nginx.sh /usr/bin/nginx.sh 7 | RUN chmod 755 /usr/bin/nginx.sh 8 | 9 | RUN export DEBIAN_FRONTEND='noninteractive' && \ 10 | apt-get update -qq && \ 11 | apt-get install -qqy --no-install-recommends nginx &&\ 12 | apt-get clean && \ 13 | sed -i 's/#gzip/gzip/' /etc/nginx/nginx.conf && \ 14 | sed -i "/http_x_forwarded_for\"';/s/';/ '/" /etc/nginx/nginx.conf && \ 15 | rm -rf /etc/nginx/sites-enabled/* && \ 16 | rm -rf /var/lib/apt/lists/* /tmp/* 17 | 18 | # forward request and error logs to docker log collector 19 | RUN ln -sf /dev/stdout /var/log/nginx/access.log \ 20 | && ln -sf /dev/stderr /var/log/nginx/error.log 21 | 22 | COPY default.conf /etc/nginx/conf.d/ 23 | 24 | EXPOSE 80 443 25 | 26 | ENTRYPOINT ["nginx.sh"] -------------------------------------------------------------------------------- /nginx/default.conf: -------------------------------------------------------------------------------- 1 | ## 2 | # You should look at the following URL's in order to grasp a solid understanding 3 | # of Nginx configuration files in order to fully unleash the power of Nginx. 4 | # http://wiki.nginx.org/Pitfalls 5 | # http://wiki.nginx.org/QuickStart 6 | # http://wiki.nginx.org/Configuration 7 | # 8 | # Generally, you will want to move this file somewhere, and start with a clean 9 | # file but keep this around for reference. Or just disable in sites-enabled. 10 | # 11 | # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. 12 | ## 13 | 14 | # HTTP Server 15 | server { 16 | listen 80 default_server; 17 | # listen [::]:80 default_server ipv6only=on; 18 | root /srv/www; 19 | 20 | # Make site accessible from http://localhost/ 21 | server_name localhost; 22 | 23 | error_log stderr notice; 24 | 25 | #location-start 26 | location /whoami { 27 | proxy_pass http://whoami; 28 | proxy_set_header Host $host; 29 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 30 | proxy_set_header X-Forwarded-Proto $scheme; 31 | proxy_set_header X-Real-IP $remote_addr; 32 | 33 | 34 | ## Required for websockets 35 | proxy_http_version 1.1; 36 | proxy_set_header Connection "upgrade"; 37 | proxy_set_header Upgrade $http_upgrade; 38 | proxy_read_timeout 600s; 39 | 40 | ## Optional: Do not log, get it at the destination 41 | access_log off; 42 | } 43 | #location-end 44 | } -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | user abc; 2 | worker_processes 4; 3 | pid /run/nginx.pid; 4 | include /etc/nginx/modules/*.conf; 5 | 6 | events { 7 | worker_connections 768; 8 | # multi_accept on; 9 | } 10 | 11 | http { 12 | 13 | ## 14 | # Basic Settings 15 | ## 16 | 17 | sendfile on; 18 | tcp_nopush on; 19 | tcp_nodelay on; 20 | keepalive_timeout 65; 21 | types_hash_max_size 2048; 22 | # server_tokens off; 23 | 24 | # server_names_hash_bucket_size 64; 25 | # server_name_in_redirect off; 26 | 27 | client_max_body_size 0; 28 | 29 | include /etc/nginx/mime.types; 30 | default_type application/octet-stream; 31 | 32 | ## 33 | # Logging Settings 34 | ## 35 | 36 | access_log /config/log/nginx/access.log; 37 | error_log /config/log/nginx/error.log; 38 | 39 | ## 40 | # Gzip Settings 41 | ## 42 | 43 | gzip on; 44 | gzip_disable "msie6"; 45 | 46 | # gzip_vary on; 47 | # gzip_proxied any; 48 | # gzip_comp_level 6; 49 | # gzip_buffers 16 8k; 50 | # gzip_http_version 1.1; 51 | # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; 52 | 53 | ## 54 | # nginx-naxsi config 55 | ## 56 | # Uncomment it if you installed nginx-naxsi 57 | ## 58 | 59 | #include /etc/nginx/naxsi_core.rules; 60 | 61 | ## 62 | # nginx-passenger config 63 | ## 64 | # Uncomment it if you installed nginx-passenger 65 | ## 66 | 67 | #passenger_root /usr; 68 | #passenger_ruby /usr/bin/ruby; 69 | 70 | ## 71 | # Virtual Host Configs 72 | ## 73 | include /etc/nginx/conf.d/*.conf; 74 | include /config/nginx/site-confs/*; 75 | } 76 | 77 | 78 | #mail { 79 | # # See sample authentication script at: 80 | # # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript 81 | # 82 | # # auth_http localhost/auth.php; 83 | # # pop3_capabilities "TOP" "USER"; 84 | # # imap_capabilities "IMAP4rev1" "UIDPLUS"; 85 | # 86 | # server { 87 | # listen localhost:110; 88 | # protocol pop3; 89 | # proxy on; 90 | # } 91 | # 92 | # server { 93 | # listen localhost:143; 94 | # protocol imap; 95 | # proxy on; 96 | # } 97 | #} 98 | daemon off; 99 | -------------------------------------------------------------------------------- /nginx/nginx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o nounset # Treat unset variables as an error 3 | 4 | ### timezone: Set the timezone for the container 5 | timezone="$TMZ" 6 | [[ -e /usr/share/zoneinfo/$timezone ]] || { 7 | echo "ERROR: invalid timezone specified: $timezone" >&2 8 | return 9 | } 10 | 11 | if [[ -w /etc/timezone && $(cat /etc/timezone) != $timezone ]]; then 12 | echo "$timezone" >/etc/timezone 13 | ln -sf /usr/share/zoneinfo/$timezone /etc/localtime 14 | dpkg-reconfigure -f noninteractive tzdata >/dev/null 2>&1 15 | fi 16 | 17 | # Start Nginx 18 | exec nginx -g "daemon off;" -------------------------------------------------------------------------------- /traefik-ssl/acme.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexhyett/traefik-vs-nginx-docker/9c8e8df7517939f792c73dd74ee0d81c7150ec7d/traefik-ssl/acme.json -------------------------------------------------------------------------------- /traefik-ssl/traefik.toml: -------------------------------------------------------------------------------- 1 | [entryPoints] 2 | [entryPoints.web] 3 | address = ":80" 4 | [entryPoints.web.http.redirections.entryPoint] 5 | to = "websecure" 6 | scheme = "https" 7 | 8 | [entryPoints.websecure] 9 | address = ":443" 10 | 11 | [entryPoints.websecure.http.tls] 12 | certResolver = "lets-encrypt" 13 | 14 | [api] 15 | dashboard = true 16 | 17 | [certificatesResolvers.lets-encrypt.acme] 18 | email = "youremailhere" 19 | storage = "acme.json" 20 | [certificatesResolvers.lets-encrypt.acme.tlsChallenge] 21 | 22 | [providers.docker] 23 | watch = true 24 | network = "web" 25 | exposedByDefault = false 26 | 27 | [providers.file] 28 | filename = "traefik_dynamic.toml" -------------------------------------------------------------------------------- /traefik-ssl/traefik_dynamic.toml: -------------------------------------------------------------------------------- 1 | [http.middlewares.simpleAuth.basicAuth] 2 | users = [ 3 | "admin:$apr1$86fC1Dr4$tDIyf.Zhg4z.NSf3uHY./." 4 | ] 5 | 6 | [http.routers.api] 7 | rule = "Host(`yourdomain.com`)" 8 | entrypoints = ["web","websecure"] 9 | middlewares = ["simpleAuth"] 10 | service = "api@internal" 11 | [http.routers.api.tls] 12 | certResolver = "lets-encrypt" -------------------------------------------------------------------------------- /traefik/traefik.toml: -------------------------------------------------------------------------------- 1 | [entryPoints] 2 | [entryPoints.web] 3 | address = ":80" 4 | 5 | [api] 6 | dashboard = true 7 | insecure = true 8 | 9 | [providers.docker] 10 | watch = true 11 | network = "web" 12 | exposedByDefault = false --------------------------------------------------------------------------------