简体   繁体   English

凤凰服务器上的MIX_ENV = prod在PORT = 80时崩溃

[英]MIX_ENV=prod on a Phoenix server crashes on starting with PORT=80

I am having some issues with mix, and MIX_ENV=prod with mix phoenix.server , where it fails on starting. 我有一些混合问题, MIX_ENV=prod with mix phoenix.server ,它在启动时失败。 Running all latest (Elixir 1.0.5, Phoenix 0.14.0) except Erlang (17.x, 17.3 I think) on Linode's Ubuntu 14.04. 在Linode的Ubuntu 14.04上运行所有最新的(Elixir 1.0.5,Phoenix 0.14.0),除了Erlang(17.x,17.3我认为)。

$ 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,[]]}}}"}

Specifically I think its this part of the trace. 具体来说,我认为这部分是追踪。

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

It looks like your server is attempting to bind to a restricted port (less than 1024) without root privileges. 看起来您的服务器正在尝试绑定到没有root权限的受限端口(小于1024)。 Try using a higher port, like Phoenix's default of 4000. If it needs to be on port 80, either run it as root or (better) proxy it with nginx. 尝试使用更高端口,例如Phoenix的默认值4000.如果它需要在端口80上,要么以root身份运行,要么(更好)使用nginx代理它。

As Nick Meharry pointed out you are trying to run your Phoenix server process on a port that traditionally on Unix, only root can bind to (low ports (<1024)). 正如Nick Meharry指出你试图在传统上在Unix上的端口上运行Phoenix服务器进程,只有root可以绑定到(低端口(<1024))。

Running your process as root is not recommended because of security reasons - an attacker who would take over the process could get root access to the whole operating system. 由于安全原因,不建议以root身份运行您的进程 - 接管该进程的攻击者可以获得对整个操作系统的root访问权限。

It's more secure to work around this by running your server on a high port (for instance, 4000) and use a simple iptables rule to forward the connections from port 80 to port 4000. Note that any user on your machine can bind to port 4000 - so you lose the extra protection from the low ports. 通过在高端口(例如,4000)上运行服务器并使用简单的iptables规则将连接从端口80转发到端口4000来解决此问题更安全。请注意,计算机上的任何用户都可以绑定到端口4000 - 所以你失去了低端口的额外保护。

Another solution is to allow certain programs ( mix , elixir ) to bind to ports below 1024 using CAP_NET_BIND_SERVICE Linux kernels capability (available since 2.6.24) which can be set using setcap . 另一个解决方案是允许某些程序( mixelixir )使用CAP_NET_BIND_SERVICE Linux内核功能(自2.6.24开始提供)绑定到1024以下的端口,该功能可以使用setcap设置。 But then still any user can use this executables unless they are available only to a certain user by using proper file access rights. 但是,任何用户仍然可以使用此可执行文件,除非它们仅通过使用适当的文件访问权限对特定用户可用。

I see the following options: 我看到以下选项:

  1. Use apache/nginx in front as a proxy for phoenix running on a higher port behind it—The creator of Elixir, has said there's usually no need to do that in this very question thread. 在前面使用apache / nginx作为凤凰在其后面的更高端口上运行的代理 - Elixir的创建者,已经说过在这个问题线程中通常没有必要这样做。 If you already need nginx for something else (like running WP or serving static images), then just do this. 如果你已经需要nginx用于其他东西(比如运行WP或提供静态图像),那么就这样做吧。
  2. Run as root—simple but very bad idea from a security perspective. 从安全角度来看,以简单但非常糟糕的方式运行。
  3. Use IP tables—simple and effective, but breaks ipv6 使用IP表 - 简单有效,但打破ipv6
  4. Use setcap to give specific binaries the power to open lower ports. 使用setcap为特定二进制文件提供打开较低端口的能力。

I like option 4. 我喜欢选项4。

In order to run mix phoenix.server and similar commands, you need to run setcap on your BEAM binary. 要运行mix phoenix.server和类似命令,需要在BEAM二进制文件上运行setcap You can find it by briefly starting the server as root and doing ps -ef | grep beam 你可以通过简单地以root身份启动服务器并执行ps -ef | grep beam来找到它 ps -ef | grep beam . ps -ef | grep beam On my system, it's /usr/lib/erlang/erts-8.1/bin/beam.smp , so I ran: 在我的系统上,它是/usr/lib/erlang/erts-8.1/bin/beam.smp ,所以我运行:

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

Now the server can be started on a normal port with mix commands. 现在可以使用mix命令在普通端口上启动服务器。 Next, presumably you're going to want to deploy an actual elixir release and run it as a service. 接下来,大概你会想要部署一个实际的elixir版本并将其作为服务运行。 The same strategy works. 同样的策略也有效。 Use setcap on the run_erl binary your release created. 在您的发布版本创建的run_erl二进制文件上使用setcap For my app it was: 对于我的应用程序,它是:

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

Now an upstart or systemd script can launch the server, too. 现在,一个upstart或systemd脚本也可以启动服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows:Elixir phoenix MIX_ENV = prod:该术语无法识别 - Windows: Elixir phoenix MIX_ENV=prod : The term is not recognized 在Heroku中为Phoenix Framework设置MIX_ENV - Setting MIX_ENV in Heroku for Phoenix Framework ** (CaseClauseError) 没有 case 子句匹配::eacces - 使用 MIX_ENV=prod 构建版本 - ** (CaseClauseError) no case clause matching: :eacces - Building release with MIX_ENV=prod Elixir-在Mac上设置MIX_ENV会产生FunctionClauseError - Elixir - setting MIX_ENV on a Mac yields FunctionClauseError 仅当MIX_ENV最初未设置为“test”时才加载混合依赖项标记为test - Loading mix dependencies marked as test only when the MIX_ENV was not originally set to “test” 在另一个端口上运行iex mix phoenix.server不起作用 - Running iex mix phoenix.server on a different port does not work 无法将“ MIX_ENV”识别为内部或外部命令,可操作程序或批处理文件 - 'MIX_ENV' is not recognized as an internal or external command, operable program or batch file mix phoenix.server (启动) &gt; 杀死 (phoenix server 不启动) - mix phoenix.server (startup) > killed (phoenix server does not start) Edeliver在随机TCP端口上启动Phoenix / Elixir应用程序 - Edeliver Starting Phoenix/Elixir App on Random TCP Port 使用Hound / Phoenix“自动”启动PhantomJS服务器 - Starting PhantomJS server 'automatically' with Hound / Phoenix
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM