Ubuntu

帶有 systemd 和套接字啟動的 Puma - Errno::EADDRINUSE

  • March 27, 2019

我有一個 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)

我根據puma docssystemd docs設置了一切。

我當然重新載入了 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)

我已經瀏覽過的其他有用資源:

問題在於 Micheal Hampton 在評論bootup_puma中指出的中間 shell 腳本。

將服務更改為 指令ExecStart=/opt/myapp/current/bin/puma -C config/puma.rb並為環境提供EnvironmentFile指令解決了該問題。

引用自:https://serverfault.com/questions/960132