Puma 与 systemd 和套接字激活 - Errno::EADDRINUSE

Puma 与 systemd 和套接字激活 - Errno::EADDRINUSE

我有一个 Rails 5 应用程序,运行在 puma 3.12.1、MRI 2.6.2 和 Ubuntu 18.04 上。它曾经使用pumactl自定义控制脚本运行,但我想使用 systemd 正确配置它,使用套接字激活来实现零停机部署。

问题是套接字持有端口并且 puma 想要绑定到同一个端口,因此出现此错误:

/opt/myapp/shared/vendor/ruby/2.6.0/gems/puma-3.12.1/lib/puma/binder.rb:273:in `initialize': 
Address already in use - bind(2) for "0.0.0.0" port 3000 (Errno::EADDRINUSE)

我按照彪马文档systemd 文档

我当然重新加载了 systemd 配置,并尝试重新启动了几次。我不太了解 systemd 如何进行套接字激活,但对我来说,puma 的错误消息似乎是合理的 :/

也许 puma 不应该尝试绑定到该端口?但是我该如何与 puma 通信以不绑定到它而是使用 systemd 的转发流?

我的配置:

$ cat /etc/systemd/system/puma.socket
[Unit]
Description=Puma HTTP Server Accept Sockets

[Socket]
ListenStream=0.0.0.0:3000

# Socket options matching Puma defaults
NoDelay=true
ReusePort=true
Backlog=1024

[Install]
WantedBy=sockets.target
$ cat /etc/systemd/system/puma.service
[Unit]
Description=API with Puma server
After=network.target
Requires=puma.socket

[Service]
Type=simple
WorkingDirectory=/opt/myapp/current
ExecStart=/opt/myapp/current/script/bootup_puma
SyslogIdentifier=api-puma
PIDFile=/opt/myapp/current/tmp/pids/puma.pid
Restart=no
TimeoutSec=30
User=ubuntu

[Install]
WantedBy=multi-user.target
$ cat script/bootup_puma
#!/bin/bash

# [setting up some envvars here]

bundle exec puma -C config/puma.rb
$ cat config/puma.rb
# frozen_string_literal: true

app_dir = File.expand_path("..", __dir__)

workers ENV.fetch("API__PUMA_WORKERS", 4).to_i
threads 1, ENV.fetch("RAILS_MAX_THREADS", 8).to_i

bind "tcp://0.0.0.0:#{ENV.fetch('PORT', 3000)}"

pidfile "#{app_dir}/tmp/pids/puma.pid"

directory ENV.fetch("API__PUMA_DIRECTORY") unless ENV.fetch("RAILS_ENV", "development") == "development"

出于绝望的尝试,我还尝试使用 unix 套接字而不是 TCP,但尽管我小心不通过符号链接引用套接字,但最终仍然出现了类似的错误。

/opt/myapp/shared/vendor/ruby/2.6.0/gems/puma-3.12.1/lib/puma/binder.rb:367:in `add_unix_listener': 
There is already a server bound to: /opt/myapp/shared/tmp/puma.sock (RuntimeError)

我已经浏览过的其他有用资源:

答案1

问题在于中间 shell 脚本,bootup_puma正如 Micheal Hampton 在评论

将服务更改为 ExecStart=/opt/myapp/current/bin/puma -C config/puma.rb并为环境提供EnvironmentFile指令解决了该问题。

相关内容