2015-06-30 8 views
10

Ich habe einige Probleme mit Mix und MIX_ENV=prod mit mix phoenix.server, wo es beim Start fehlschlägt. Alles läuft neu (Elixir 1.0.5, Phoenix 0.14.0) außer Erlang (17.x, 17.3 glaube ich) auf Linodes Ubuntu 14.04.MIX_ENV = Absturz auf einem Phoenix-Server stürzt ab mit PORT = 80

$ MIX_ENV=prod PORT=80 mix phoenix.server 
{"Kernel pid terminated",application_controller,"{application_start_failure,elirc_site,{{shutdown,{failed_to_start_child,'Elixir.ElircSite.Endpoint',{shutdown,{failed_to_start_child,'Elixir.Phoenix.Endpoint.Server',{shutdown,{failed_to_start_child,{ranch_listener_sup,'Elixir.ElircSite.Endpoint.HTTP'},{shutdown,{failed_to_start_child,ranch_acceptors_sup,{{badmatch,{error,eacces}},[{ranch_acceptors_sup,init,1,[{file,\"src/ranch_acceptors_sup.erl\"},{line,30}]},{supervisor,init,1,[{file,\"supervisor.erl\"},{line,243}]},{gen_server,init_it,6,[{file,\"gen_server.erl\"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,\"proc_lib.erl\"},{line,239}]}]}}}}}}}}},{'Elixir.ElircSite',start,[normal,[]]}}}"} 

Speziell ich denke, es ist dieser Teil der Spur.

{{badmatch,{error,eacces}},[{ranch_acceptors_sup,init,1,[{file,\"src/ranch_acceptors_sup.erl\"},{line,30}]} 

Antwort

5

Es sieht so aus, als ob Ihr Server versucht, an einen eingeschränkten Port (weniger als 1024) ohne Root-Rechte zu binden. Versuchen Sie es mit einem höheren Port, wie Phoenix standardmäßig 4000. Wenn es auf Port 80 sein muss, entweder führen Sie es als root oder (besser) Proxy mit nginx.

+4

Es gibt normalerweise keine Notwendigkeit, Phoenix hinter nginx zu laufen. :) –

+0

Richtig. Das ist nur dann besser, wenn Sie Ihren Code auf Anwendungsebene nicht als root ausführen möchten, sondern unbedingt Port 80/443 benötigen (was ich hier für möglich gehalten habe). –

+4

Sie können auch eine NAT für den Port mit iptables (oder Firewall der Präferenz) tun. Ex: iptables -t nat -A OUTPUT -d myhostname -p --dport 80 tcp -j REDIRECT --to-Ports 8080 && iptables -t nat -A PREROUTING -d myhostname -p tcp --dport 80 -j REDIRECT --to-ports 8080 – diogovk

4

Wie Nick Meharry darauf hingewiesen hat, versuchen Sie, Ihren Phoenix-Server-Prozess auf einem Port auszuführen, der traditionell unter Unix läuft, nur root kann binden (niedrige Ports (< 1024)).

Das Ausführen Ihres Prozesses als root wird aus Sicherheitsgründen nicht empfohlen - ein Angreifer, der den Prozess übernehmen würde, könnte Root-Zugriff auf das gesamte Betriebssystem erhalten.

Es ist sicherer, dies zu umgehen, indem Sie Ihren Server auf einem hohen Port (z. B. 4000) ausführen und eine einfache iptables-Regel verwenden, um die Verbindungen von Port 80 zu Port 4000 weiterzuleiten. Beachten Sie, dass jeder Benutzer auf Ihrem Computer binden Sie an Port 4000 - so verlieren Sie den zusätzlichen Schutz vor den niedrigen Ports.

Eine andere Lösung ist, bestimmte Programme (mix, elixir) zu ermöglichen Ports unter 1024 mit CAP_NET_BIND_SERVICE Linux-Kernel-Fähigkeit (verfügbar seit 2.6.24) zu binden, welche eingestellt setcap mit werden kann. Aber dennoch kann jeder Benutzer diese ausführbaren Dateien verwenden, sofern sie nicht nur für einen bestimmten Benutzer verfügbar sind, indem er die richtigen Dateizugriffsrechte verwendet.

4

ich folgende Optionen:

  1. Verwenden Apache/nginx vor als Proxy für Phoenix auf einem höheren Port dahinter Der Schöpfer von Elixir läuft, hat gesagt, es gibt in der Regel keine Notwendigkeit zu tun, dass in dieser Frage Thread. Wenn Sie bereits nginx für etwas anderes benötigen (wie zum Beispiel WP ausführen oder statische Images bereitstellen), tun Sie dies einfach.
  2. Führen Sie als root-einfache, aber sehr schlechte Idee aus einer Sicherheits-Perspektive.
  3. Verwenden Sie IP-Tabellen-einfach und effektiv, aber bricht ipv6
  4. Verwenden Sie SetCap, um bestimmte Binärdateien die Macht zu geben, unteren Ports zu öffnen.

Ich mag Option 4.

Um mix phoenix.server und ähnliche Befehle auszuführen, müssen Sie setcap auf BEAM binär laufen. Sie können es finden, indem Sie den Server kurz als root starten und ps -ef | grep beam tun. Auf meinem System ist es /usr/lib/erlang/erts-8.1/bin/beam.smp, so lief ich:

sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/lib/erlang/erts-8.1/bin/beam.smp

Nun kann der Server auf einem normal Port mit Mix-Befehlen gestartet werden. Als nächstes werden Sie voraussichtlich eine aktuelle Elixir-Version bereitstellen und als Dienst ausführen. Die gleiche Strategie funktioniert. Verwenden Sie setcap auf der run_erl Binär, die Ihre Version erstellt.Für meine app es war:

sudo setcap CAP_NET_BIND_SERVICE=+eip /home/ubuntu/myapp/_build/prod/rel/myapp/erts-8.1/bin/run_erl

Jetzt ein Emporkömmling oder systemd Skript auf den Server starten können, auch.

+1

Für mich musste ich 'setcap' on/beam not /beam.smp verwenden. Dies hilft beim Testen, wenn es funktioniert: run 'iex', dann': gen_tcp.listen (80, []) '. Sollte etwa so aussehen: '{: ok, #Port <0.1426>}' – Vantalk