J'ai un service qui écoute le port 8080. Celui-ci n'est pas un conteneur.
Ensuite, j'ai créé un conteneur nginx en utilisant une image officielle:
docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d -p 443:443 -p 80:80 nginx
Après tout:
# netstat -tupln | grep 443
tcp6 0 0 :::443 :::* LISTEN 3482/docker-proxy
# netstat -tupln | grep 80
tcp6 0 0 :::80 :::* LISTEN 3489/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 1009/Java
La configuration de Nginx est:
upstream eighty {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name eighty.domain.com;
location / {
proxy_pass http://eighty;
}
}
J'ai vérifié que je pouvais me connecter avec ce serveur avec # curl http://127.0.0.1:8080
<html><head><meta http-equiv='refresh'
content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body
style='background-color:white; color:white;'>
...
Cela semble bien fonctionner, cependant, lorsque j'essaie d'accéder à l'aide de mon navigateur, nginx indique à bt une réponse de passerelle mauvaise.
Je suis en train de comprendre que cela peut être un problème lié à la visibilité entre une ouverture par un processus non conteneurisé et un conteneur. Est-ce que le conteneur peut établir une connexion avec un port ouvert par un processus autre que le conteneur?
MODIFIER
Journaux où upstream { server 127.0.0.1:8080; }
:
2016/07/13 09:06:53 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", Host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:06:53 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"
Journaux où upstream { server 0.0.0.0:8080; }
:
62.57.217.25 - - [13/Jul/2016:09:00:30 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" 2016/07/13 09:00:30 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client:
62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", Host: "eighty.domain.com" 2016/07/13 09:00:32 [error] 5#5: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", Host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:00:32 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"
Des idées?
Localhost est un peu délicat quand il s'agit de conteneurs. Dans un conteneur docker, localhost pointe sur le conteneur lui-même . Cela signifie, avec un amont comme celui-ci:
upstream foo{
server 127.0.0.1:8080;
}
ou
upstream foo{
server 0.0.0.0:8080;
}
vous dites à nginx de transmettre votre demande à l'hôte local . Mais dans le contexte d'un conteneur docker, localhost (et les adresses IP correspondantes) pointent vers le conteneur lui-même:
en vous adressant à 127.0.0.1, vous n'atteindrez jamais votre ordinateur hôte si votre conteneur n'est pas sur le réseau hôte.
Vous pouvez choisir d’exécuter nginx sur le même réseau que votre hôte:
docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d --net=Host nginx
Notez qu'il n'est pas nécessaire d'exposer les ports dans ce cas.
Cela fonctionne bien que vous perdiez l’avantage du réseautage Docker Si plusieurs conteneurs doivent communiquer via le réseau Docker, cette approche peut poser problème. Si vous souhaitez simplement déployer nginx avec docker et ne pas utiliser de fonctionnalités réseau avancées, vous pouvez utiliser cette approche.
Une autre approche consiste à reconfigurer votre directive nginx en amont pour vous connecter directement à votre ordinateur hôte en ajoutant son adresse IP distante:
upstream foo{
//insert your hosts ip here
server 192.168.99.100:8080;
}
Le conteneur va maintenant passer par la pile réseau et résoudre votre hôte correctement:
Vous pouvez également utiliser votre nom DNS si vous en avez un. Assurez-vous que docker connaît votre serveur DNS.
Pour moi aidé cette ligne de code proxy_set_header Host $http_Host;
server {
listen 80;
server_name localhost;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_Host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://myserver;
}
ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1)
docker run --name nginx --add-Host="Host:${ip}" -p 80:80 -d nginx
location / {
...
proxy_pass http://Host:8080/;
}
Ça marche pour moi
Ce que vous pouvez faire est de configurer proxy_pass
afin que, de la perspective container
, l’adresse pointe vers votre hôte réel.
Pour obtenir une adresse Host
du point de vue du conteneur, procédez comme suit sous Windows avec le code fixe 18.03
(ou plus récent):
Exécutez bash sur le conteneur de l'hôte où le nom de l'image est nginx
(fonctionne sur Alpine Linux distribution
):
docker run -it nginx /bin/ash
Puis courez à l'intérieur du conteneur
/ # nslookup Host.docker.internal
Name: Host.docker.internal
Address 1: 192.168.65.2
192.168.65.2
est l'adresse IP de l'hôte - pas l'adresse IP du pont comme dans spinus
réponse acceptée.
J'utilise ici Host.docker.internal :
L'hôte a une adresse IP changeante (ou aucune si vous n'avez pas d'accès au réseau). À partir du 18.03, nous vous recommandons de vous connecter au nom DNS spécial Host.docker.internal, qui correspond à l'adresse IP interne utilisée par l'hôte. Ceci à des fins de développement et ne fonctionnera pas dans un environnement de production en dehors de Docker pour Windows.
Ensuite, vous pouvez changer la configuration nginx
en: proxy_pass http://192.168.65.2:{your_app_port};
et ça devrait marcher.
N'oubliez pas de fournir la même port
que votre application locale s'exécute.