NixOS Containers: Difference between revisions
Fix headings and formatting, fix →Bridge together two nixos-containers with privateNetwork enabled |
Consistent formatting |
||
| Line 4: | Line 4: | ||
=== Host Configuration === | === Host Configuration === | ||
For all of the examples below to work, you'll have to enable virtualization and the use of containers in your host systems nix configuration.{{file| | For all of the examples below to work, you'll have to enable virtualization and the use of containers in your host systems nix configuration. | ||
boot.enableContainers = true; | {{file|3=boot.enableContainers = true; | ||
virtualisation.containers.enable = true; | virtualisation.containers.enable = true;|name=/etc/nixos/configuration.nix|lang=nix}} | ||
=== Configuration === | === Configuration === | ||
The following example creates a container called webserver running a httpd web server. It will start automatically at boot and has its private network subnet. | The following example creates a container called webserver running a httpd web server. It will start automatically at boot and has its private network subnet. | ||
{{file|3=networking.nat = { | {{file|3=networking.nat = { | ||
enable = true; | enable = true; | ||
| Line 47: | Line 45: | ||
system.stateVersion = "24.11"; | system.stateVersion = "24.11"; | ||
}; | }; | ||
};|name=configuration.nix|lang=nix}} | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
In order to reach the web application on the host system, we have to open [[Firewall]] port 80 and also configure NAT through <code>networking.nat</code>. The web service of the container will be available at http://192.168.100.11 | In order to reach the web application on the host system, we have to open [[Firewall]] port 80 and also configure NAT through <code>networking.nat</code>. The web service of the container will be available at http://192.168.100.11 | ||
| Line 58: | Line 56: | ||
===== NAT (Network Address Translation) ===== | ===== NAT (Network Address Translation) ===== | ||
In order to allow the container to connect to the internet, you have to configure NAT through <code>networking.nat</code>. | |||
{{File|3=networking.nat = { | {{File|3=networking.nat = { | ||
enable = true; | enable = true; | ||
| Line 64: | Line 63: | ||
# Lazy IPv6 connectivity for the container | # Lazy IPv6 connectivity for the container | ||
enableIPv6 = true; | enableIPv6 = true; | ||
};|name=configuration.nix|lang=nix}} | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
===== Bridge ===== | ===== Bridge ===== | ||
Connect a container to a bridge using Network Manager interfaces: | |||
networking = { | {{File|3=networking = { | ||
bridges.br0.interfaces = [ "eth0s31f6" ]; # Adjust interface accordingly | bridges.br0.interfaces = [ "eth0s31f6" ]; # Adjust interface accordingly | ||
| Line 89: | Line 88: | ||
localAddress = "192.168.100.5/24"; | localAddress = "192.168.100.5/24"; | ||
config = { }; | config = { }; | ||
}; | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
===== Without privateNetwork (simpler) ===== | ===== Without privateNetwork (simpler) ===== | ||
If the service can be accessed by changing its port, the private network is not needed necessarily. Be careful to not use occupied ports. This example runs an [[Actual]] server on port 3003. It can be accessed through the host at <code>http://localhost:3003</code>. Since <code>privateNetwork</code> is not defined, it defaults to <code>false</code>. | If the service can be accessed by changing its port, the private network is not needed necessarily. Be careful to not use occupied ports. This example runs an [[Actual]] server on port 3003. It can be accessed through the host at <code>http://localhost:3003</code>. Since <code>privateNetwork</code> is not defined, it defaults to <code>false</code>. | ||
{{File|3=containers.actualContainer = { | |||
containers.actualContainer = { | |||
autoStart = true; | autoStart = true; | ||
config = {...}: { | config = {...}: { | ||
| Line 104: | Line 101: | ||
}; | }; | ||
}; | }; | ||
}; | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
=== Usage === | === Usage === | ||
| Line 135: | Line 131: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
View log for container<syntaxhighlight lang="console"> | View log for container | ||
<syntaxhighlight lang="console"> | |||
# journalctl -M webserver | # journalctl -M webserver | ||
</syntaxhighlight>Further informations are available in the {{manual:nixos|sec=#ch-containers|chapter=NixOS manual}}. | </syntaxhighlight> | ||
Further informations are available in the {{manual:nixos|sec=#ch-containers|chapter=NixOS manual}}. | |||
== Tips and tricks == | == Tips and tricks == | ||
| Line 143: | Line 141: | ||
=== Define and create nixos-container from a Flake file === | === Define and create nixos-container from a Flake file === | ||
We can define and create a custom container called <code>container</code> from a file stored as <code>flake.nix</code>. In this case we use the unstable branch of the nixpkgs repository as a source. | |||
{ | We can define and create a custom container called <code>container</code> from a file stored as <code>flake.nix</code>. In this case we use the unstable branch of the nixpkgs repository as a source. | ||
{{File|3={ | |||
inputs.nixpkgs.url = "nixpkgs/nixos-unstable"; | inputs.nixpkgs.url = "nixpkgs/nixos-unstable"; | ||
| Line 166: | Line 165: | ||
}; | }; | ||
} | }|name=/etc/nixos/configuration.nix|lang=nix}} | ||
To create and run that container, enter following commands. In this example the <code>flake.nix</code> file is in the same directory. | |||
<syntaxhighlight lang="console"> | |||
# nixos-container create flake-test --flake . | # nixos-container create flake-test --flake . | ||
host IP is 10.233.4.1, container IP is 10.233.4.2 | host IP is 10.233.4.1, container IP is 10.233.4.2 | ||
| Line 176: | Line 177: | ||
=== Use agenix secrets in container === | === Use agenix secrets in container === | ||
To add <code>agenix</code> secrets to a container bind mount the <code>ssh-host.key</code> and import the <code>agenix.nixosModule</code> and set <code>age.identityPaths</code> [https://discourse.nixos.org/t/secrets-inside-nixos-containers/34403/6 Source] | |||
{ agenix, ... }: | To add <code>agenix</code> secrets to a container bind mount the <code>ssh-host.key</code> and import the <code>agenix.nixosModule</code> and set <code>age.identityPaths</code> [https://discourse.nixos.org/t/secrets-inside-nixos-containers/34403/6 Source] | ||
{{File|3={ agenix, ... }: | |||
{ | { | ||
| Line 202: | Line 204: | ||
}; | }; | ||
}; | }; | ||
} | }|name=/etc/nixos/configuration.nix|lang=nix}} | ||
=== Bridge together two nixos-containers with privateNetwork enabled === | === Bridge together two nixos-containers with privateNetwork enabled === | ||
'''Target:''' | '''Target:''' | ||
Create two containers, both with <code>privateNetwork = true;</code> | Create two containers, both with <code>privateNetwork = true;</code>: | ||
* <code>containerA</code> at 192.168.100.2 | * <code>containerA</code> at 192.168.100.2 | ||
| Line 215: | Line 216: | ||
** which runs an httpd server at http://localhost:80 | ** which runs an httpd server at http://localhost:80 | ||
They should be connected with a bridge <code>br0</code> and both should have internet address | They should be connected with a bridge <code>br0</code> and both should have internet address. | ||
Assuming Network Manager is used, so the introduction of systemd.network should not interfere with the rest of the setup. | |||
'''Configuration:''' | '''Configuration:''' | ||
Create and configure the | Create and configure the internet connection and the bridge: | ||
{{File|3=# Give containers access to the internet | {{File|3=# Give containers access to the internet | ||
networking.nat = { | networking.nat = { | ||
enable = true; | enable = true; | ||
internalInterfaces = [ "br0" ]; # Connect the bridge to the internet | internalInterfaces = [ "br0" ]; # Connect the bridge to the internet | ||
externalInterface = "wlp5s0"; # Adjust according to your internet interface | externalInterface = "wlp5s0"; # Adjust according to your internet interface | ||
| Line 235: | Line 237: | ||
# set systemd.network.wait-online.enable to false so that boot isn't blocked on connectivity that networkd will never provide. | # set systemd.network.wait-online.enable to false so that boot isn't blocked on connectivity that networkd will never provide. | ||
# https://wiki.nixos.org/wiki/Systemd/networkd#When_to_use | # https://wiki.nixos.org/wiki/Systemd/networkd#When_to_use | ||
systemd.network = { | systemd.network = { | ||
enable = true; | enable = true; | ||
| Line 280: | Line 281: | ||
}; | }; | ||
}; | }; | ||
};|name=configuration.nix|lang=nix}} | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
Create and configure <code>containerA</code> | Create and configure <code>containerA</code>: | ||
{{File|3=containers.containerA = { | {{File|3=containers.containerA = { | ||
autoStart = true; | autoStart = true; | ||
| Line 295: | Line 296: | ||
networking = { | networking = { | ||
# | # Changes the gateway to the Network Address of the bridge, so that it has access to the internet | ||
# | # The bridge has access to the internet | ||
defaultGateway = { | defaultGateway = { | ||
address = "192.168.100.1"; | address = "192.168.100.1"; | ||
| Line 310: | Line 311: | ||
services.resolved.enable = true; | services.resolved.enable = true; | ||
}; | }; | ||
};|name=configuration.nix|lang=nix}} | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
Create and configure <code>containerB</code> | Create and configure <code>containerB</code>: | ||
{{File|3=containers.containerB = { | {{File|3=containers.containerB = { | ||
autoStart = true; | autoStart = true; | ||
| Line 330: | Line 331: | ||
networking = { | networking = { | ||
# | # Changes the gateway to the Network Address of the bridge, so that it has access to the internet | ||
# | # The bridge has access to the internet | ||
defaultGateway = { | defaultGateway = { | ||
address = "192.168.100.1"; | address = "192.168.100.1"; | ||
| Line 346: | Line 347: | ||
services.resolved.enable = true; | services.resolved.enable = true; | ||
}; | }; | ||
};|name=configuration.nix|lang=nix}} | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
You can test the connection by loggining into containerA and pinging containerB, curling to its httpd server or pinging an internet website:<syntaxhighlight lang="console"># nixos-container root-login containerA | You can test the connection by loggining into containerA and pinging containerB, curling to its httpd server or pinging an internet website: | ||
<syntaxhighlight lang="console"> | |||
# nixos-container root-login containerA | |||
[root@containerA:~]# ping 192.168.100.3 -c3 # ping containerB | [root@containerA:~]# ping 192.168.100.3 -c3 # ping containerB | ||
[root@containerA:~]# curl http://192.168.100.3:80 # curl to containerB's httpd server | [root@containerA:~]# curl http://192.168.100.3:80 # curl to containerB's httpd server | ||
[root@containerA:~]# ping nixos.org -c3 # ping an internet website</syntaxhighlight> | [root@containerA:~]# ping nixos.org -c3 # ping an internet website | ||
</syntaxhighlight> | |||
== Troubleshooting == | == Troubleshooting == | ||