2
votes

NGINX docker-compose - Hôte introuvable dans nuxt en amont: 3000

J'essaie de configurer une application déployée sur une instance EC2 que je ne parviens pas à visiter l'application lorsqu'elle est sur IP publique ec2. J'ai vérifié les groupes de sécurité et autorisé tout le trafic entrant vers les ports juste pour voir si je peux atteindre la page d'accueil ou la page d'administration de django.

Disons que mon adresse IP ec2 est 34.245.202.112 comment puis-je mapper mon application pour que nginx serve

Le frontend (nuxt) à 34.245.202.112

Le backend (django) à 34.245.202.112/admin

L'API (DRF) à 34.245.202.112/api

Lorsque j'essaye de faire cela, l'erreur que je reçois de nginx est

nginx | 2020-11-14T14:15:35.511973183Z 2020/11/14 14:15:35 [emerg] 1#1: host not found in upstream "nuxt:3000" in /etc/nginx/conf.d/autobets_nginx.conf:9

Ceci est ma configuration

docker-composer

version: "3.4"

# the upstream component nginx needs to connect to
upstream django {
    ip_hash;
    server django:8001;
}

upstream nuxt {
ip_hash;
server nuxt:3000;
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name 34.245.202.112; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    location /static/ {
        alias /static/;
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        proxy_pass  django;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host $host;
    }
}

nginx.conf

services:
db:
    restart: always
    image: postgres
    volumes:
    - pgdata:/var/lib/postgresql/data
    environment:
    - POSTGRES_USER=postgres
    - POSTGRES_PASSWORD=postgres
    ports:
    - "5432:5432"
    expose:
    - 5432
    networks:
    - random_name

django:
    container_name: django
    build:    
    context: ./backend
    env_file: .env
    environment:
    - DEBUG=True
    command: >
    sh -c "./wait-for-it.sh db:5432 && 
            ./autobets/manage.py collectstatic --no-input &&
            ./autobets/manage.py makemigrations &&
            ./autobets/manage.py migrate --no-input &&
            ./autobets/manage.py runserver_plus 0.0.0.0:8001
            "
    - "8001"
    volumes:
    - ./backend:/app
    depends_on:
    - db
    restart: on-failure

nginx:
    image: nginx
    container_name: nginx
    ports:
    - "80:80"
    restart: always
    depends_on:
    - nuxt
    - django
    volumes:
    - ./nginx/conf:/etc/nginx/conf.d
    - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
    - ./backend/static:/static
    networks:
    - random_name

nuxt:
    build:
    context: ./frontend
    environment:
    - API_URI=http://django:8001/api

    command: sh -c "npm install && npm run dev"
    volumes:
    - ./frontend:/app
    ports:
    - "3000:3000"
    depends_on:
    - django
    networks:
    - random_name

volumes:
pgdata:
networks:
random_name:


2 commentaires

Votre configuration nginx ne fonctionnera pas même si vous corrigez cette erreur. proxy_pass et uwsgi_pass sont les gestionnaires de contenu . Vous ne pouvez pas avoir plus d'un gestionnaire de contenu dans le même emplacement.


@IvanShatsky J'ai corrigé cela maintenant mais je reçois toujours la même erreur. Connaissez-vous un bon modèle de configuration que je peux utiliser comme référence?


3 Réponses :


1
votes

Regardez cet exemple minimal:

server {
  listen 80;
  listen 8000;  # from you config, remove if unnecessary

  server_name 34.245.202.112;

  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Host $host;

  location / {
    # 'the frontend(nuxt) at 34.245.202.112'
    # This is the default route. Requests get here when there's no
    # better match to go.
    proxy_pass http://nuxt:3000;
  }

  location /api/ {
    # This location will trigger when location in URI begins with '/api/'
    # e.g. http://yourserver.org/api/v1/hello/world
    proxy_pass http://django:8001;
  }

  location /admin/ {
    # exactly as /api/
    proxy_pass http://django:8001;
  }

  location /static/ {
    # same as /api/ but local files instead of proxy
    alias /static/;
  }
}

Comme vous le voyez dans l'exemple, chaque emplacement a un préfixe URI. NGINX testera tous ces «préfixes» par rapport à l'emplacement dans les requêtes HTTP entrantes, trouvant la meilleure correspondance. Une fois la meilleure correspondance trouvée, NGINX fera tout ce que vous avez écrit à l'intérieur du bloc. Dans l'exemple ci-dessus, toutes les requêtes commençant par /api/ ou /django/ vont au backend de django . Les requêtes commençant par /static/ sont servies à partir de fichiers locaux. Tout le reste va au backend nuxt .

Je ne sais pas si j'ai bien compris vos intentions, probablement parce qu'il me manque la configuration d'origine que vous avez modifiée, vous devez donc reprendre ici. N'oubliez pas que vous n'êtes pas limité aux préfixes d'URI pour les emplacements (vous pouvez utiliser une expression régulière ou une correspondance exacte) et que vous pouvez faire des emplacements imbriqués. Consultez ce grand guide du débutant de NGINX pour en savoir plus http://nginx.org/en/docs/beginners_guide.html .

MISE À JOUR : Après avoir regardé d'autres réponses ici, je pensais que je devais une réponse à la question dans le titre au lieu d'une simple configuration de base. La raison pour laquelle vous n'avez host not found in upstream l' host not found in upstream erreur host not found in upstream est que vous n'avez pas spécifié de directive de resolver . Il est nécessaire lors de l'utilisation de noms DNS dans des blocs en upstream et pour NGINX dans Docker, vous pouvez utiliser ceci: resolver 127.0.0.11 ipv6=off; . Mettez-le dans le bloc http , c'est-à-dire en dehors du bloc server .

«127.0.0.11» est le DNS Docker. Il résout les noms de service et de conteneur ainsi que les enregistrements DNS `` normaux '' (pour cela, il utilise la configuration DNS de l'hôte). Vous n'avez pas besoin d'attribuer un alias à un service ou de définir un container_name car le nom du service est un enregistrement DNS en soi. Il résout tous les conteneurs de ce service. L'utilisation du resolver n'était pas nécessaire dans la configuration de base que j'ai publiée car je n'utilisais pas de blocs en upstream .


0 commentaires

0
votes

Le nom du conteneur "nuxt" n'est pas défini dans le fichier docker-compose, donc le nom d'hôte ne peut pas être résolu par le conteneur nginx. Essayez de corriger l'erreur nginx en ajoutant nom_conteneur: nuxt au service nuxt dans le fichier docker-compose.


0 commentaires

0
votes

Il vous manque la section alias dans votre bloc network du fichier docker-compose. Les alias que vous définissez mettront automatiquement à jour le fichier /etc/hosts des conteneurs et, par conséquent, votre conteneur nginx connaîtra l'hôte nuxt .

services:
  nuxt:
    networks:
      some-network:
        aliases:
          - nuxt

Plus d'infos ici. ctrl-f pour les alias: https://docs.docker.com/compose/compose-file/


3 commentaires

utiliser driver: bridge ferait-il la même chose?


Sur la base de mes tests locaux, vous ne pouvez pas définir à la fois network_mode et networks dans le bloc de service . Et mon test avec juste network_mode: bridge n'a pas résolu l'hôte correctement.


Les noms de service (nuxt, django, db, etc.) deviennent des noms DNS par défaut. La résolution d'un nom de service à l'intérieur d'un conteneur se traduira par une liste d'adresses IP de tous les conteneurs appartenant à ce service. Je ne vois pas comment un alias peut aider ici.