[résolu] Docker-compose et nginx

Hello,

Je tente d’installer Kresus (via docker-compose) sur mon dédié. Ce dernier hoste déjà deux apps servies en https via Nginx.

Le certificat est de Let’s Encrypt et généré par certbot et gère les 3 sous-domaines.

Du coup, ça fait 3 applications qui tournent sur le même serveur, accessible chacune depuis un sous-nom de domaine en https :

Lors du premier lancement de docker-compose up, Traefik a essayé de bind le port 443 sans succès puisque déjà utilisé. C’est pourquoi, j’ai le docker-compose file en utilisant le port 445 du host 445.

Du coup, Kresus se lance sans soucis mais n’est jamais sollicité. Nginx ne semble pas router sa requête vers Traefik.

Aujourd’hui, j’ai un beau 404 lorsque je tente d’accéder à https://finances.domain.tld

Le .env file :

# [...]
MY_DOMAIN=kresus.domain.tld
# [...]

Le docker-compose file :

###################################
#  TRAEFIK
###################################
  traefik:
    image: traefik:v1.7.7
    # ne génère pas de certificat, Nginx s'occupe ça
    command: --web --docker --docker.domain=docker.localhost --entryPoints='Name:https Address::443 TLS' --entryPoints='Name:http Address::80  Redirect.EntryPoint:https'
    ports:
      - "80:80"
      - "445:443" # utilise le port 445 car, 443 est déjà utilisé par d'autres apps
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
      - /opt/traefik:/etc/traefik/acme
      - /opt/certs:/certs
    labels:
      - "traefik.backend=traefik"
      - "traefik.frontend.rule=Host:${MY_DOMAIN};PathPrefix:/traefik"
      - "traefik.backend.port=8080"
      - "traefik.frontend.auth.basic=${MY_USERNAME}:${MY_PASSWD}"
      - "traefik.frontend.entryPoints=https,http"
    container_name: traefik

Voici la configuration Nginx qui s’occupe de router la requête vers Traefik :

server {
  listen 443 ssl;
  server_name kresus.domain.tld;

  # un certificat et une clef pour les 3 applications
  ssl_certificate /etc/letsencrypt/live/sub.domain.tld/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/sub.domain.tld/privkey.pem; # managed by Certbot

  access_log /var/log/nginx/finances.access.log;
  error_log /var/log/nginx/finances.error.log;

  location / {
    proxy_pass https://127.0.0.1:445; # je demande bien à router vers le port 445
  }
}

Et c’est tout ce que j’ai comme log de Nginx, :

==> finances.access.log <==
89.225.253.218 - tom [19/Aug/2019:13:58:07 +0200] "GET / HTTP/2.0" 404 19 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0"
89.225.253.218 - tom [19/Aug/2019:13:58:07 +0200] "GET /favicon.ico HTTP/2.0" 499 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0"

Une idée de ce qui ne va pas dans ma configuration ?

Par ailleurs, je me demande si je peux me passer complètement de https au sein de traefik puisque la requête est chiffré jusqu’à Nginx.

Qu’en penses-vous ?

Je dirais que tu peux te passer du SSL/TLS en effet puisque nginx le gère.

Tout d’abord, qu’est-ce que te retourne curl -v https://127.0.0.1:445 depuis ton serveur ? et curl -v http://127.0.0.1:445 si différent ?

Salut !

Effectivement tu peux te passer de Traefik vu que tu utilises nginx. Maintenant, y a deux choses différentes à faire, selon que nginx est également dans un container docker ou non :

  • si nginx est dans un container docker, il faut les mettre sur le même sous-réseau virtuel (docker network --help devrait t’aider un peu), et ensuite dans le fichier de configuration de nginx, pointer vers l’hostname de l’image Docker de Kresus.
  • si nginx n’est pas dans un container docker, il faut que l’instance de Kresus soit sur un réseau bridge avec la machine hôte, et que le nginx pointe vers l’IP du container Kresus (que tu peux trouver avec docker inspect de mémoire).

Voilà, tiens-nous au courant :slight_smile:
Benjamin

Bon je crois que je le tiens enfin !!!

@nicofrand merci beaucoup pour le tip de checker kresus via cURL à l’intérieur du serveur. Ça m’a permis de voir que ma configuration était pas bonne depuis le début puisque j’avais un 404 :disappointed:

@bnjbvr nginx est installé directement sur mon host et le passage entre les deux a fonctionné avec un simple localhost. J’imagine que mon docker était donc déjà en mode bridge. Est-ce une configuration par défaut de docker ?

Du coup, j’ai effectivement opté pour un passage par nginx qui gère le https et ensuite du http tout le reste :

Voici ce que ça donne pout Nginx:

server {
  listen 443 ssl http2;
  server_name finances.domain.tld;
  ssl_certificate /etc/letsencrypt/live/sub.domain.tld/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/sub.domain.tld/privkey.pem; # managed by Certbot

  access_log /var/log/nginx/finances.access.log;
  error_log /var/log/nginx/finances.error.log;

  location / {
    proxy_pass http://localhost:81;
  }
}

et le docker-compose file :

version: '2'
services:
###################################
#  TRAEFIK
###################################
  traefik:
    image: traefik:v1.7.7
    #toutes les configurations de let's encrypt sont retirés
    command: --web --docker --docker.domain=docker.localhost --entryPoints='Name:https Address::443 TLS' --entryPoints='Name:http Address::80' 
    ports:
     # le port 443 ne sert plus à rien, je l'ai retiré aussi
      - "81:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
      - /opt/traefik:/etc/traefik/acme
      - /opt/certs:/certs
    labels:
      - "traefik.backend=traefik"
      - "traefik.frontend.rule=Host:${MY_DOMAIN};PathPrefix:/traefik"
      - "traefik.backend.port=8080"
      - "traefik.frontend.auth.basic=${MY_USERNAME}:${MY_PASSWD}"
      # on a juste besoin de http maintenant
      - "traefik.frontend.entryPoints=http"
    container_name: traefik
############################################
# Postfix
############################################
  postfix:
    image: mwader/postfix-relay
    environment:
      - POSTFIX_myhostname=${MY_DOMAIN}
      - OPENDKIM_DOMAINS=${MY_DOMAIN}
    volumes:
      - /opt/postfix:/etc/opendkim/keys
##############################################
# KRESUS
##############################################
  kresus:
    image: bnjbvr/kresus
    volumes:
      - /opt/kresus:/home/user/data
      - /opt/weboob:/weboob
      - ./config.ini:/opt/config.ini
    environment:
      - LOCAL_USER_ID=1000
    labels:
      - "traefik.backend=kresus"
      - "traefik.frontend.rule=Host:${MY_DOMAIN}"
      - "traefik.backend.port=9876"
      - "traefik.frontend.auth.basic=${MY_USERNAME}:${MY_PASSWD}"
      # on a juste besoin de http maintenant
      - "traefik.frontend.entryPoints=http"
    links:
       - postfix:postfix

Dans mon .env :

[...]
MY_DOMAIN=localhost
[...]

et le tour est joué !

1 J'aime

En tout cas un grand merci à vous !

Maintenant, je me dis que tout ça c’est un peu du bricolage à l’arraché.

Qu’est-ce que vous conseilleriez pour rendre la configuration des mes services un peu plus consistante ?

J’aimerai bien tout passer en container mais je ne suis pas certain de quel service je dois utiliser derrière pour les gérer : kubernetes, Traefik (que je découvre avec Kresus) ?

Des suggestions ?

Salut !

Gros gros point de vigilance :

      - "81:80"

Cette ligne demande à Docker que le port 81 de l’hôte soit mappé sur le port 80 de la machine. Le seul problème, c’est que par défaut (il y a une préférence de dockerd pour le désactiver), Docker va ouvrir ce port sur l’hôte également, rendant ton Kresus accessible au monde entier. À la place, je te conseille d’enlever cette ligne, et de mettre le nginx et le docker Kresus sur le même sous-réseau ; depuis le nginx, passer l’adresse réseau du container Docker.

Qu’est-ce que vous conseilleriez pour rendre la configuration des mes services un peu plus consistante ?

Personnellement, je me contente très bien de docker-compose, même sans Kubernetes / Traefik. Après, à toi de voir selon tes besoins et tes envies de t’amuser avec tes technos :slight_smile:

Benjamin

:fearful: oula merci pour le spot ! Effectivement je vais régler ça.

À la place, je te conseille d’enlever cette ligne, et de mettre le nginx et le docker Kresus sur le même sous-réseau ; depuis le nginx, passer l’adresse réseau du container Docker.

Est-ce que je peux faire ça sans modifier la configuration globale de Nginx ?

Oui, normalement tu peux juste jouer avec le fichier de configuration nginx pour le site, en remplaçant “localhost:80” par l’IP du container Kresus dans le sous-réseau Docker avec le “:80” à la fin. Pour trouver l’IP du container Kresus, tu peux utiliser la commande docker inspect {HASH_OU_NOM_DU_CONTAINER} | grep IPAddress.