EC2生产环境Puma启动失败求助:端口占用异常
Hey there, let's work through this tricky issue you're facing. You've deployed your Rails app to EC2 using Nginx, Puma, and Capistrano, but can't access it via the browser—plus Puma's throwing an Errno::EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 3000 error even though no process seems to be using that port. Let's break this down step by step.
First, Let's Rule Out the Obvious: Network & Nginx Basics
1. Verify EC2 Security Group Configuration
Your browser can't reach the site if AWS isn't letting traffic through:
- Log into the AWS Console, navigate to your EC2 instance's security group.
- Ensure there's an inbound rule allowing TCP traffic on port 80 from
0.0.0.0/0(IPv4) and::/0(IPv6). If this rule is missing, add it immediately.
2. Fix Nginx Server Name Mismatch
Looking at your Nginx config, you've set server_name localhost;. When you access your EC2 public IP, Nginx won't match this server block and will fall back to a default (which might not exist). Update this line to:
server_name xx.xxx.xxx.xx; # Replace with your EC2 public IP # Or use "_" to match all incoming requests: server_name _;
Then validate and restart Nginx:
sudo nginx -t # Checks for config syntax errors sudo systemctl restart nginx sudo systemctl status nginx # Confirm it's running without errors
3. Check Nginx Error Logs
You mentioned Nginx logs are empty, but let's double-check the default error log location (often /var/log/nginx/error.log):
sudo tail -20 /var/log/nginx/error.log
Look for errors like "permission denied" when connecting to the Puma sock, or "no such file or directory" for the sock path.
Dig Into Puma's Port Conflict Mystery
Your Puma config is set to use a Unix socket (unix:///home/yogesh/myapp_name/shared/tmp/sockets/puma.sock), so it shouldn't be trying to bind port 3000 at all. Here's how to track down why it is:
1. Use a More Comprehensive Port Check
lsof and netstat might miss TIME_WAIT connections or hidden processes. Try:
ss -tulpn | grep 3000
This will show all processes (and their PIDs) listening on port 3000, plus lingering connections in TIME_WAIT state. If you see TIME_WAIT entries, wait 2-3 minutes for them to release, or restart the server to clear them.
2. Verify Puma's Actual Startup Command
Check if Puma is being forced to bind port 3000 via a hidden config or Capistrano task:
ps aux | grep puma
Look for flags like -p 3000 or --port 3000 in the process arguments. If you see them, you have a conflicting configuration somewhere:
- Double-check the auto-generated
puma.rbin your shared directory (/home/yogesh/myapp_name/shared/puma.rb) to ensure it matches the config you provided (no extrabind 'tcp://0.0.0.0:3000'lines). - Confirm your Capistrano
deploy.rbdoesn't have any conflicting Puma port settings (yours looks correct, but it never hurts to recheck).
3. Test Puma Manually
Start Puma directly with your config to see if the error persists:
cd /home/yogesh/myapp_name/current bundle exec puma -C /home/yogesh/myapp_name/shared/puma.rb
If you still get the port 3000 error, there's a stray config somewhere—search your project for any references to port 3000 or bind 0.0.0.0:3000.
Fix Permissions Between Nginx and Puma
Nginx runs as a non-root user (usually www-data), while Puma runs as your user yogesh. This can cause permission issues with the Unix socket:
1. Check Sock File Permissions
ls -l /home/yogesh/myapp_name/shared/tmp/sockets/
If puma.sock has permissions like rw------- (700), Nginx can't access it. Add this line to your puma.rb to set a more permissive umask:
umask 0002 # Creates files with 775 permissions
Then restart Puma:
cap production puma:restart
Recheck the sock permissions—they should now be rwxrwxr-x.
2. Add Your User to the Nginx Group
If the umask fix doesn't work, add yogesh to the Nginx user group:
sudo usermod -aG www-data yogesh sudo systemctl restart nginx cap production puma:restart
Validate Local Connectivity
Once you've made these changes, test if the app works locally on the EC2 server:
curl http://localhost
If this returns your app's HTML, the issue was with public network access (security group or server name). If it doesn't, check Nginx's error logs again for clues about why it can't connect to Puma.
内容的提问来源于stack exchange,提问作者yogeshmanjhi

