Accessing Puma app running with systemd service behind Nginx proxy results in the following error in nginx error.log:
*6 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 1.2.3.4, server: mydomain.com, request: "GET / HTTP/1.1", upstream: "http://unix:/home/deploy/opt/app/shared/sockets/puma.app.sock/", host: "mydomain.com"
Puma service log has no errors.
Running Puma app manually locally (before nginx) yields no errors, though. Similarly, running the same app on http proxy instead of puma unix socket also works fine, allowing Nginx to server requests correctly. So it looks like the problem is not in my backend ruby.
Stack
- Puma 4.3.3
- Roda 3.30.0
- Rbenv Ruby 2.7.0
- Nginx 1.14.0
/etc/nginx/sites_available/mydomain.com
upstream app {
server unix:/home/deploy/opt/app/shared/sockets/puma.app.sock;
}
server {
listen 80;
server_name mydomain.com;
root /home/deploy/opt/app/public;
location / {
try_files $uri @puma;
}
location @puma {
include proxy_params;
proxy_pass http://app;
}
}
/etc/systemd/system/puma-app.service
[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
# Foreground process (do not use --daemon in ExecStart or config.rb)
Type=simple
# Preferably configure a non-privileged user
User=deploy
Group=sudo
# Specify the path to your puma application root
WorkingDirectory=/home/deploy/opt/app
# Helpful for debugging socket activation, etc.
Environment=DEBUG=1
EnvironmentFile=/home/deploy/opt/app/.env
# The command to start Puma
ExecStart=/home/deploy/.rbenv/shims/bundle exec puma -C /home/deploy/opt/app/config/puma.rb
TimeoutSec = 15
Restart=always
[Install]
WantedBy=multi-user.target
/home/deploy/opt/app/config/puma.rb
# Change to match your CPU core count
workers ENV.fetch("PUMA_WORKERS") { 1 }
# Min and Max threads per worker
threads ENV.fetch("PUMA_MIN_THREADS") { 1 }, ENV.fetch("PUMA_MAX_THREADS") { 10 }
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.app.sock"
# Redirect STDOUT to log files
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.app.pid"
state_path "#{shared_dir}/pids/puma.app.state"
rackup app_dir
activate_control_app