I am running Ubuntu Hardy 8.04 and nginx 0.7.65, and when I try starting my nginx server:
$ sudo /etc/init.d/nginx start
I get the following error:
Starting nginx: [emerg]: bind() to IP failed (99: Cannot assign requested address)
where "IP" is a placeholder for my IP address. Does anybody know why that error might be happening? This is running on EC2.
My nginx.conf file looks like this:
user www-data www-data;
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /usr/local/nginx/logs/access.log;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 3;
gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml
application/xml+rss text/javascript;
include /usr/local/nginx/sites-enabled/*;
}
and my /usr/local/nginx/sites-enabled/example.com looks like:
server {
listen IP:80;
server_name example.com;
rewrite ^/(.*) https://example.com/$1 permanent;
}
server {
listen IP:443 default ssl;
ssl on;
ssl_certificate /etc/ssl/certs/myssl.crt;
ssl_certificate_key /etc/ssl/private/myssl.key;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP;
server_name example.com;
access_log /home/example/example.com/log/access.log;
error_log /home/example/example.com/log/error.log;
}
With Amazon EC2 and elastic IPs, the server doesn't actually know its IP as with most any other server.
So you need to tell your linux to allow processes to bind to the non-local address. Just add the following line into /etc/sysctl.conf
file:
# allow processes to bind to the non-local address
# (necessary for apache/nginx in Amazon EC2)
net.ipv4.ip_nonlocal_bind = 1
and then reload your sysctl.conf by:
$ sysctl -p /etc/sysctl.conf
which will be fine on reboots.
To avoid hard-coding the IP address in the config, do this:
listen *:80
As kirpit mentioned above you'll want to allow linux processes to bind to a local IP address:
nano /etc/sysctl.conf
# allow processes to bind to the non-local address
net.ipv4.ip_nonlocal_bind = 1
sysctl -p /etc/sysctl.conf
Then you want to add the private ip address that is associated with your elastic ip and add that to your sites config:
nano /etc/nginx/sites-available/example.com
Reload nginx:
service nginx reload
All done!
There might be remaining process/program that's using/listening at port 80.
You can check that using netstat -lp.
Kill that process and start nginx.
With Amazon EC2 and elastic IPs, the server doesn't actually know its IP as with most any other server. So in the apache virtual host files at least you put *:80 rather than your elastic ip :80
Then it works properly. So theoretically, doing *:80 for nginx should work the same but when you do you get [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use). Haven't found a solution yet.
.
For people who might be dealing with this in the future, I just looked up my private IP in the AWS instance and bound to that. I verified that nginx was able to listen publicly and perform my rewrite after that. I could not do *:PORT as I had an internal server I was proxying to.
If you are using Network Manager, you have to wait to raise the network interface before starting the service:
systemctl enable NetworkManager-wait-online.service
For Amazon EC2 and elastic IPs, sysctl.conf
will not work as nginx still not listen on eth0
.
So, you need to listen *;