Updated: 28 September 2026 · Applies to: Nginx on Ubuntu 24.04 and 26.04 LTS

With several IP addresses on one dedicated server you can give each website or application its own address. This is called IP-based hosting. Modern browsers and web servers can share one address for many HTTPS sites (SNI), so you do not need separate addresses for that. Separate addresses are still useful when a partner needs to allow-list one address, when you want separate firewall rules or separate reputations, or when you sell hosting to customers who expect their own IP.

Before you start

  1. The extra addresses are configured and tested (How to add additional IPv4 addresses on Ubuntu with netplan?, How to test that every additional IP address works on your server?).
  2. DNS: each domain has an A record that points to the address it should use.
  3. Nginx is installed: sudo apt install -y nginx.

1. One site file per address

Create /etc/nginx/sites-available/site1.example.com:

server {
    listen 203.0.113.11:80;
    server_name site1.example.com;
    root /var/www/site1;
    index index.html;
}

And a second file for the other address, /etc/nginx/sites-available/site2.example.com:

server {
    listen 203.0.113.12:80;
    server_name site2.example.com;
    root /var/www/site2;
    index index.html;
}

Create the folders and a test page for each: sudo mkdir -p /var/www/site1 /var/www/site2 and write a line of text into index.html of each.

2. Enable the sites and reload

sudo ln -s /etc/nginx/sites-available/site1.example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

3. Add HTTPS

Get a free certificate for each name with Certbot (sudo apt install -y certbot python3-certbot-nginx), then run sudo certbot --nginx -d site1.example.com and the same for the second name. Certbot adds listen 203.0.113.11:443 ssl; to the right file. Check that each file listens only on its own address.

4. Test

sudo ss -ltnp | grep nginx
curl -s http://203.0.113.11 -H "Host: site1.example.com"
curl -s http://203.0.113.12 -H "Host: site2.example.com"

The ss command should show one listening line for each address. The two curl commands must show the two different pages.

A default site for unknown names

Requests to an address without a matching name should not show one of your sites by accident. Add a catch-all that closes the connection:

server {
    listen 203.0.113.10:80 default_server;
    server_name _;
    return 444;
}

Apache and other software

Apache uses <VirtualHost 203.0.113.11:80> for the same idea. Databases and other services can be bound to one address in their own settings (bind-address in MariaDB, listen_addresses in PostgreSQL). Keep databases on 127.0.0.1 unless you really need remote access.

Common problems

  • Nginx fails to start ("Address already in use"): another site or service listens on 0.0.0.0:80. Use sudo ss -ltnp | grep :80 to find it. A generic listen 80; conflicts with address-specific listens only when both target the same address.
  • "Cannot assign requested address": the address is not configured on the server yet.
  • The wrong site appears: check server_name and the listen address of each file.

Frequently asked questions

Do I need a separate address for each SSL certificate?
No, not with SNI. Use separate addresses only for the reasons listed at the top.

How do I set reverse DNS for each address?
How to set reverse DNS (PTR) for many IP addresses and check forward-confirmed rDNS?.

Need a dedicated server, more IP addresses, or a hand with the setup?

Prefer a hand with the setup? Our engineers can do it for you: Hire an Expert, or use our on-demand server management.

Was this answer helpful? 0 Users Found This Useful (0 Votes)