Networks
Bridges are what guests attach to, and everything else on this section assumes one exists. Creating external and internal networks, what reconciliation does, and the properties you can only set once.
Every guest attaches to a bridge. The bridge decides which subnet the guest gets an address from, whether that address is handed out by DHCP, what search domain its name lives in, and whether the network is carried across the cluster.
So this page comes first: firewall rules name a bridge, and DNS records are derived from one.
Two kinds of network
The choice is made once, with --type, and it decides who routes the traffic.
--type external |
--type internal |
|
|---|---|---|
| Guests sit on | your physical LAN | a subnet private to this host |
| Addresses | from your existing range | from a range you define |
| Gateway | your existing router | the host itself |
Needs a --child-interface |
yes, the uplink | no |
| Reachable from the LAN | directly | only through the host |
External is a bridge over a real NIC: guests appear on the office network like
physical machines. Internal makes the host the gateway for a private subnet — the
default for guests that should not be visible on the LAN, and what the installer sets up
as hoster-internal.
Internal networks are also the ones worth marking
--route-over-wg,
so a private subnet on one host can reach a private subnet on another.
Looking at what exists
hoster network list # the configured networks
hoster network list --json
hoster network status # desired vs actual, with drift
hoster network status --json
list shows the configuration. status shows the reconciliation state — for each
bridge: whether it should be enabled, whether it actually exists, its operational state,
any drift between the two, and warnings. It ends with the last apply’s timestamp,
mode, and error if there was one.
That distinction is the useful part. list tells you what you asked for; status tells
you what the kernel actually has, and drift is the gap between them.
Take a screenshot of `hoster network list` and `hoster network status` on a host with an internal and an external network, ideally with one bridge showing drift.
Creating a network
An external bridge over a physical NIC:
hoster network create \
--type external \
--name office-lan \
--bridge-address 192.168.118.214 \
--gateway 192.168.118.254 \
--subnet 192.168.118.0/24 \
--range-start 192.168.118.215 \
--range-end 192.168.118.225 \
--child-interface eno1 \
--dns-server 1.1.1.1 \
--dns-server 8.8.8.8 \
--dns-search-domain office.lan \
--description "Office LAN"
An internal, routed one:
hoster network create \
--type internal \
--name hoster-private \
--bridge-address 10.0.5.254 \
--subnet 10.0.5.0/24 \
--range-start 10.0.5.10 \
--range-end 10.0.5.200 \
--dns-search-domain private.lan \
--dhcp \
--route-over-wg \
--description "Private guest network"
--name and --subnet are required; everything else has a default or is optional.
| Flag | Default | Notes |
|---|---|---|
--type |
external |
external or internal |
--name |
— | required; the bridge interface name |
--subnet |
— | required; CIDR, e.g. 10.0.5.0/24 |
--bridge-address |
— | the host’s own address on this network |
--gateway |
— | ignored for internal networks, which gateway themselves |
--range-start / --range-end |
— | the pool guests are allocated from |
--child-interface |
— | uplink; repeat the flag for several |
--dns-server |
— | repeat the flag for several |
--dns-search-domain |
— | the domain guest names live in |
--dhcp |
off | run a DHCP server for this network |
--route-over-wg |
off | carry this network across the cluster mesh |
--default-gateway |
off | make this bridge the host’s default route |
--stp |
off | spanning tree, for a bridge with several uplinks |
--enabled |
on | create it without bringing it up with --enabled=false |
--description |
— | shown in list |
Rules that are checked
Validation runs before anything touches the host, and the messages name the field:
- The bridge name must be a valid Linux interface name — alphanumerics, hyphens and underscores, within the length limit.
- The bridge address, the gateway, and both ends of the range must all fall inside the subnet.
- The range start must come before the range end.
Internal networks gateway themselves
Create one with --type internal and the host becomes the gateway: the network’s gateway
is set to the bridge address, and the address is applied to the bridge whether you asked
for it or not. Passing --gateway on an internal network is pointless — it gets
overwritten.
What create actually does
It is not just a configuration write. In one command:
- Validate the bridge, and the change against the existing configuration.
- Persist it.
- Reconcile the host: create the bridge, enslave the child interfaces, apply addresses, and adjust the default route if this bridge claims it.
- Reload the services that depend on it — DHCP and DNS.
It rolls back if the apply fails
If reconciliation fails partway, the previous configuration is restored, host networking is reverted to it, and the dependent services are reloaded again. You get the original error back. If the rollback itself fails, the error says so explicitly rather than leaving you guessing which state you are in.
That is a real difference from the firewall, which applies immediately with no rollback. Networking gets you back; the firewall does not. Both are still worth a console when you are working over the link you are changing.
For a preview before committing to anything, reconcile everything as a dry run:
hoster network init --dry-run # print the planned changes
hoster network init # bring all configured bridges to their desired state
init is also what makes a fresh boot come up correctly — it reconciles every bridge
from the configuration rather than depending on what survived.
Changing one afterwards
This is the part to read before designing your networks.
hoster network enable office-lan
hoster network disable office-lan
hoster network delete office-lan
hoster network set office-lan --stp=true
hoster network setcan only change STP. It takes exactly one flag,--stp. The subnet, the DHCP range, the DNS search domain, the DNS servers, the child interfaces,--route-over-wg,--default-gatewayand the description are all create-time only on the CLI.
UpdateNetworkBridgeexists inHosterLiband the agent API exposes a full update at/api/v1/host/network/config/, so Control Center can edit any of it. From a terminal, changing a network means editing the host network configuration by hand, or deleting and recreating the bridge — which detaches the guests on it.This bites hardest on the search domain: a bridge with no search domain generates no DNS records at all, and adding one to an existing bridge is the fix — with no CLI to apply it.
Plan the search domain and the routing flags at creation, not afterwards.
One-off addresses outside the range
hoster network add-ip hoster-internal 10.0.5.240
Adds a single allowed address to a bridge without widening the allocation range — for the one guest that has to have a specific address that sits outside the pool. It is idempotent and says so when the address is already allowed.
Where the CLI stops short of the model
Three properties exist in the network model and in the reconciler, with no flag to set them:
Workload isolation has no CLI flag, and CLI-created networks never get it. A network carries an
isolation_modeofdisabled,observeorenforce, with reconciliation and dedicated API endpoints behind it.hoster network createnever writes the field, and the persistence layer only normalises it when it is already set — so a network created from the CLI is persisted with no mode and resolves todisabled. The same network created through Control Center can be typed and enforced.Two paths to the same object with different security postures, and nothing in the CLI output says which one you got.
--typeuses a different vocabulary from the stored model. The flag acceptsinternalorexternal; the model’snetwork_typeisinternal_shared,internal_privateorexternal.createnever writesnetwork_typeat all — it only sets the “I am the gateway” boolean, and the type is inferred back from that, which can only ever produceinternal_shared.internal_privateis unreachable from the CLI.
--vlan-iddoes not exist. The reconciler fully supports an access VLAN — given a VLAN id and exactly one child interface it creates theparent.idinterface and enslaves that — but there is no flag to set the id, so VLAN-backed bridges cannot be created from the CLI.
And one flag that does nothing:
--apply-addressis ignored. Whatever you pass, persistence overwrites it: forced on for internal networks, and set to “is there a bridge address” for external ones.--apply-address=falseon a bridge with an address does not stop the address being applied.
When a network is not working
hoster network status # start here — drift and warnings name the bridge
hoster network init --dry-run # what reconciliation would change
hoster network init # make it so
In order:
- Is the bridge enabled and does it exist?
statusanswers both, separately — a bridge that is desired but absent is a different problem from one that exists and is down. - Does the child interface exist? A bridge with a missing uplink comes up with no path out. VLAN parents are checked by name and fail explicitly.
- Is the address inside the subnet? Validation catches this at create time, but a
hand-edited configuration file will not have been through it — run
hoster network init --dry-run. - Did the last apply fail?
statusprints the last error under the table. - Are guests getting addresses? That is DHCP, which is reloaded when a network
changes —
hoster service restart dhcp. - Do names resolve? See when names do not resolve; the first check there is the search domain that lives on this bridge.
Next
- Firewall — the rules that decide what may cross the network you just built.
- DNS and the WireGuard mesh — where the search
domain and
--route-over-wgset here actually take effect. - Your first VM — attaching a guest with
--network.
Something unclear on this page?
Ask about this specific page and we will come back to you. Your question arrives with a link to it, so you do not have to describe where you were.