Die Antwort von @ T0xicCode ist richtig, aber ich dachte, ich würde die Details erweitern, da ich tatsächlich ungefähr 20 Stunden gebraucht habe, um endlich eine funktionierende Lösung zu implementieren.
Wenn Sie Nginx in einem eigenen Container ausführen und als Reverse-Proxy verwenden möchten, um mehrere Anwendungen auf derselben Serverinstanz auszugleichen, müssen Sie die folgenden Schritte ausführen:
Verknüpfen Sie Ihre Container
Wenn Sie docker runIhre Container verwenden, in der Regel durch Eingabe eines Shell-Skripts User Data, können Sie Links zu anderen laufenden Containern deklarieren . Dies bedeutet, dass Sie Ihre Container in der richtigen Reihenfolge starten müssen und nur die letzteren Container mit den ersteren verknüpft werden können. Wie so:
#!/bin/bash
sudo docker run -p 3000:3000 --name API mydockerhub/api
sudo docker run -p 3001:3001 --link API:API --name App mydockerhub/app
sudo docker run -p 80:80 -p 443:443 --link API:API --link App:App --name Nginx mydockerhub/nginx
So in diesem Beispiel das APIwird Behälter aller anderen nicht verbunden, aber der
AppBehälter verknüpft ist APIund Nginxauf beide verbunden APIund App.
Das Ergebnis sind Änderungen an den envVariablen und /etc/hostsDateien, die sich in den Containern APIund befinden App. Die Ergebnisse sehen so aus:
/ etc / hosts
Wenn Sie cat /etc/hostsin Ihrem NginxContainer ausgeführt werden, wird Folgendes erzeugt:
172.17.0.5 0fd9a40ab5ec
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 App
172.17.0.2 API
ENV Vars
Wenn Sie envin Ihrem NginxContainer ausgeführt werden, wird Folgendes erzeugt:
API_PORT=tcp://172.17.0.2:3000
API_PORT_3000_TCP_PROTO=tcp
API_PORT_3000_TCP_PORT=3000
API_PORT_3000_TCP_ADDR=172.17.0.2
APP_PORT=tcp://172.17.0.3:3001
APP_PORT_3001_TCP_PROTO=tcp
APP_PORT_3001_TCP_PORT=3001
APP_PORT_3001_TCP_ADDR=172.17.0.3
Ich habe viele der tatsächlichen Variablen abgeschnitten, aber die oben genannten sind die Schlüsselwerte, die Sie benötigen, um den Datenverkehr auf Ihre Container zu übertragen.
Verwenden Sie Folgendes, um eine Shell zum Ausführen der oben genannten Befehle in einem laufenden Container zu erhalten:
sudo docker exec -i -t Nginx bash
Sie können sehen, dass Sie jetzt sowohl /etc/hostsDateieinträge als auch envVariablen haben, die die lokale IP-Adresse für einen der verknüpften Container enthalten. Soweit ich das beurteilen kann, ist dies alles, was passiert, wenn Sie Container mit deklarierten Linkoptionen ausführen. Sie können diese Informationen jetzt jedoch zum Konfigurieren nginxin Ihrem NginxContainer verwenden.
Nginx konfigurieren
Hier wird es etwas knifflig und es gibt einige Möglichkeiten. Sie können Ihre Sites so konfigurieren, dass sie auf einen Eintrag in der erstellten /etc/hostsDatei verweisen docker, oder Sie können die ENVvars verwenden und einen String-Ersatz (den ich verwendet habe sed) für Ihre nginx.confund alle anderen conf-Dateien ausführen, die sich möglicherweise in Ihrem /etc/nginx/sites-enabledOrdner befinden, um die IP einzufügen Werte.
OPTION A: Konfigurieren Sie Nginx mit ENV Vars
Dies ist die Option, die ich gewählt habe, weil ich die Dateioption nicht
/etc/hostszum Laufen bringen konnte. Ich werde Option B früh genug ausprobieren und diesen Beitrag mit allen Ergebnissen aktualisieren.
Der Hauptunterschied zwischen dieser Option und der Verwendung der /etc/hostsDateioption besteht darin, wie Sie schreiben Dockerfile, um ein Shell-Skript als CMDArgument zu verwenden, das wiederum das Ersetzen der Zeichenfolge zum Kopieren der IP-Werte ENVin Ihre Conf-Datei (en) übernimmt.
Hier sind die Konfigurationsdateien, mit denen ich am Ende fertig war:
Dockerfile
FROM ubuntu:14.04
MAINTAINER Your Name <you@myapp.com>
RUN apt-get update && apt-get install -y nano htop git nginx
ADD nginx.conf /etc/nginx/nginx.conf
ADD api.myapp.conf /etc/nginx/sites-enabled/api.myapp.conf
ADD app.myapp.conf /etc/nginx/sites-enabled/app.myapp.conf
ADD Nginx-Startup.sh /etc/nginx/Nginx-Startup.sh
EXPOSE 80 443
CMD ["/bin/bash","/etc/nginx/Nginx-Startup.sh"]
nginx.conf
daemon off;
user www-data;
pid /var/run/nginx.pid;
worker_processes 1;
events {
worker_connections 1024;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 33;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip Settings
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 3;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/xml text/css application/x-javascript application/json;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# Virtual Host Configs
include /etc/nginx/sites-enabled/*;
# Error Page Config
#error_page 403 404 500 502 /srv/Splash;
}
HINWEIS: Es ist wichtig, diese daemon off;in Ihre nginx.confDatei aufzunehmen, um sicherzustellen, dass Ihr Container nicht sofort nach dem Start beendet wird.
api.myapp.conf
upstream api_upstream{
server APP_IP:3000;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.myapp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
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_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
Nginx-Startup.sh
#!/bin/bash
sed -i 's/APP_IP/'"$API_PORT_3000_TCP_ADDR"'/g' /etc/nginx/sites-enabled/api.myapp.com
sed -i 's/APP_IP/'"$APP_PORT_3001_TCP_ADDR"'/g' /etc/nginx/sites-enabled/app.myapp.com
service nginx start
Ich überlasse es Ihnen, Ihre Hausaufgaben über die meisten Inhalte von nginx.confund zu machen api.myapp.conf.
Die Magie entsteht dort, Nginx-Startup.shwo wir sedden APP_IPPlatzhalter, den wir in den geschrieben haben, durch Zeichenfolgen ersetzenupstream Block unserer api.myapp.confund app.myapp.conf-Dateien geschrieben haben.
Diese ask.ubuntu.com-Frage erklärt es sehr gut:
Suchen und Ersetzen von Text in einer Datei mithilfe von Befehlen
GOTCHA Behandelt unter
OSX sedOptionen unterschiedlich, insbesondere das -iFlag. Unter Ubuntu -iübernimmt das Flag den Ersatz "an Ort und Stelle". Es öffnet die Datei, ändert den Text und speichert dieselbe Datei. Unter OSX erfordert das -iFlag die Dateierweiterung, die die resultierende Datei haben soll. Wenn Sie mit einer Datei ohne Erweiterung arbeiten, müssen Sie '' als Wert für das eingeben-i Flag eingeben.
GOTCHA
Um ENV-Variablen innerhalb des regulären Ausdrucks zu verwendensed mit dem die zu ersetzende Zeichenfolge gefunden wird, müssen Sie die in doppelte Anführungszeichen setzen. Die korrekte, wenn auch wackelig aussehende Syntax lautet also wie oben.
Daher hat Docker unseren Container gestartet und die Nginx-Startup.shAusführung des Skripts ausgelöst , mit dem sedder Wert APP_IPin die entsprechende ENVVariable geändert wurde , die wir im sedBefehl angegeben haben. Wir haben jetzt conf-Dateien in unserem /etc/nginx/sites-enabledVerzeichnis, die die IP-Adressen der ENVVariablen enthalten, die Docker beim Starten des Containers festgelegt hat. In Ihrer api.myapp.confDatei sehen Sie, dass sich der upstreamBlock wie folgt geändert hat:
upstream api_upstream{
server 172.0.0.2:3000;
}
Die IP-Adresse, die Sie sehen, kann unterschiedlich sein, aber ich habe festgestellt, dass dies normalerweise der Fall ist 172.0.0.x.
Sie sollten jetzt alles entsprechend routen.
GOTCHA
Sie können keine Container neu starten / erneut ausführen, sobald Sie den ersten Instanzstart ausgeführt haben. Docker stellt jedem Container beim Start eine neue IP-Adresse zur Verfügung und scheint keine zuvor verwendete IP-Adresse wiederzuverwenden. So api.myapp.comwird beim ersten Mal 172.0.0.2, beim nächsten Mal 172.0.0.4. Aber Nginxwird bereits die erste IP in seine conf - Dateien festgelegt, oder in seiner /etc/hostsDatei, so wird es nicht möglich sein , für die neue IP zu bestimmen api.myapp.com. Die Lösung hierfür wird wahrscheinlich CoreOSund ihr etcdDienst verwendet, der nach meinem begrenzten Verständnis ENVfür alle im selben CoreOSCluster registrierten Computer wie eine gemeinsame Lösung fungiert . Dies ist das nächste Spielzeug, mit dem ich spielen werde.
OPTION B: Verwenden Sie /etc/hostsDateieinträge
Dies sollte der schnellere und einfachere Weg sein, aber ich konnte es nicht zum Laufen bringen. Angeblich haben Sie nur den Wert des /etc/hostsEintrags in Ihre api.myapp.confund app.myapp.confDateien eingegeben , aber ich konnte diese Methode nicht zum Laufen bringen.
UPDATE:
Siehe die Antwort von @Wes Tod für Anweisungen, wie diese Methode funktioniert.
Hier ist der Versuch, den ich gemacht habe api.myapp.conf:
upstream api_upstream{
server API:3000;
}
In Anbetracht dessen, dass es einen Eintrag in meinem gibt /etc/hosts Datei wie den folgenden enthält: 172.0.0.2 APIIch dachte, er würde nur den Wert abrufen, aber es scheint nicht so zu sein.
Ich hatte auch ein paar zusätzliche Probleme mit meiner Elastic Load BalancerBeschaffung von allen AZs, so dass dies möglicherweise das Problem war, als ich diese Route ausprobierte. Stattdessen musste ich lernen, wie man unter Linux mit dem Ersetzen von Strings umgeht, also hat das Spaß gemacht. Ich werde es gleich versuchen und sehen, wie es geht.