Setting a static IP on Ubuntu Server is editing /etc/netplan/*.yaml with the address, gateway, and DNS, then sudo netplan apply. On cloud-init instances, cloud-init rewrites the YAML on boot - the fix is network: config: disabled in a cloud.cfg.d drop-in. The team that uses Netplan directly on bare metal has no cloud-init issue; the team that runs in the cloud needs the drop-in.
Table of contents
- Why Netplan on Ubuntu Server
- The standard static IP YAML
- Apply and verify
- Cloud-init override
- Multiple IPs on one interface
- FAQ
Why Netplan on Ubuntu Server
Ubuntu Server 18.04+ uses Netplan as the default network configuration tool. Netplan reads YAML from /etc/netplan/ and renders the configuration for either systemd-networkd or NetworkManager as the backend renderer.
The team that runs Ubuntu Server on bare metal uses Netplan with renderer: networkd. The team that runs Ubuntu Desktop (or has a GUI installed) uses Netplan with renderer: NetworkManager - NetworkManager overrides the YAML when it runs, so direct edits to Netplan are not effective on a desktop.
The standard static IP YAML
Edit /etc/netplan/00-installer-config.yaml (or whatever file is there):
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.0.2.50/24
routes:
- to: default
via: 192.0.2.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
Replace enp0s3 with the actual interface name from ip -br link. Replace 192.0.2.50/24 with the static IP and prefix. Replace 192.0.2.1 with the gateway. The team that picks a valid private IP and matching gateway has the right config.
Apply and verify
sudo netplan try
# ... confirm or it rolls back after 120s
sudo netplan apply
ip -br addr show enp0s3
ip route show default
The team that uses try first catches YAML errors before locking out the SSH session. The team that goes straight to apply is debugging over the cloud console.
Cloud-init override
On AWS, GCP, Azure, and other cloud instances, cloud-init may rewrite the Netplan YAML on boot. The fix:
sudo nano /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
Add:
network: { config: disabled }
After that, cloud-init leaves Netplan alone. The team that sets this BEFORE setting the static IP has the right order - if cloud-init has already overwritten the file once, the new static config will be applied on the next reboot but the current boot still has the old config.
Multiple IPs on one interface
A single interface can have multiple IPs:
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.0.2.50/24
- 192.0.2.51/24
- 192.0.2.52/24
routes:
- to: default
via: 192.0.2.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
The team that uses multiple IPs on one interface has a single NIC with several services - common for shared hosting or for the secondary IP that holds TLS certs.
FAQ
Which file should I edit - 00-installer-config.yaml or 50-cloud-init.yaml?
On bare metal, 00-installer-config.yaml is the installer’s default. On cloud instances, 50-cloud-init.yaml is cloud-init managed. Edit whichever is present, or create a new file with a higher number (e.g., 99-static.yaml) that overrides the lower-numbered one.
Why does netplan try time out without confirming?
The SSH connection drops when netplan try activates the new config (because the IP changes). Reconnect with the new IP and confirm within 120 seconds. The team that uses apply instead does not have this issue but loses the rollback safety.
What if my interface has a weird name like eno1np0?
Modern systemd names interfaces based on PCI bus topology. eno1np0 is the first network port on the first NIC. The team that does not like the naming can install biosdevname or use the older eth0 naming with a kernel parameter, but most teams just adapt to the systemd names.
Does setting a static IP break DHCP?
Yes - dhcp4: no disables DHCP on that interface. The team that wants both (a fallback) uses dhcp4: yes and configures the static address as a secondary, or uses a different network manager entirely.
Can I have IPv6 too?
Yes. Add dhcp6: no, accept-ra: true (for SLAAC) or a static addresses: [2001:db8::50/64], and the matching routes for IPv6. Most modern setups have both IPv4 and IPv6 configured.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: