From 2c503a9dcf728910efc2aaabfab0db957064ae4a Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Sun, 12 Nov 2023 21:15:19 +0100 Subject: [PATCH] examples: add persistent container example --- examples/README.md | 6 ++++ examples/container/flake.nix | 70 ++++++++++++++++++++++++++++++++++++ examples/container/usage.sh | 47 ++++++++++++++++++++++++ test/run-tests.sh | 9 +++++ 4 files changed, 132 insertions(+) create mode 100644 examples/container/flake.nix create mode 100644 examples/container/usage.sh diff --git a/examples/README.md b/examples/README.md index 54dd887..26f0a32 100644 --- a/examples/README.md +++ b/examples/README.md @@ -64,6 +64,12 @@ The commands in `shell.nix` allow you to locally run the node in a VM or contain Flakes make it easy to include `nix-bitcoin` in an existing NixOS config. The [flakes example](./flakes/flake.nix) shows how to use `nix-bitcoin` as an input to a system flake. +### Persistent container with Flakes + +The [persistent container](./container) example shows how to run a Flake-based node +in a container.\ +Requires: A systemd-based Linux distro and root privileges. + ### Extending nix-bitcoin with Flakes The [mempool extension flake](https://github.com/fort-nix/nix-bitcoin-mempool) shows how to define new diff --git a/examples/container/flake.nix b/examples/container/flake.nix new file mode 100644 index 0000000..d51d04c --- /dev/null +++ b/examples/container/flake.nix @@ -0,0 +1,70 @@ +# See how this flake is used in ./usage.sh + +# See also: +# https://github.com/erikarvstedt/extra-container +# https://github.com/erikarvstedt/extra-container/blob/master/examples/flake +# Container-related NixOS options +# https://search.nixos.org/options?channel=unstable&query=containers.%3Cname%3E + +{ + description = "A basic nix-bitcoin container node"; + + inputs = { + nix-bitcoin.url = "github:fort-nix/nix-bitcoin/release"; + # You can also use a version branch to track a specific NixOS release + # nix-bitcoin.url = "github:fort-nix/nix-bitcoin/nixos-23.05"; + + nixpkgs.follows = "nix-bitcoin/nixpkgs"; + nixpkgs-unstable.follows = "nix-bitcoin/nixpkgs-unstable"; + extra-container.follows = "nix-bitcoin/extra-container"; + }; + + outputs = { nixpkgs, nix-bitcoin, extra-container, ... }: + extra-container.lib.eachSupportedSystem (system: { + packages.default = extra-container.lib.buildContainers { + inherit system; + + # The container uses the nixpkgs from `nix-bitcoin.inputs.nixpkgs` by default + + # Only set this if the `system.stateVersion` of your container + # host is < 22.05 + # legacyInstallDirs = true; + + config = { + containers.mynode = { + # Always start container along with the container host + autoStart = true; + + # This assigns the following addresses: + # Host IP: 10.250.0.1 + # Container IP: 10.250.0.2 + extra.addressPrefix = "10.250.0"; + + # Enable internet access for the container + extra.enableWAN = true; + + # Map `/my/host/dir` to `/my/mount` in the container + # bindMounts."/my/mount" = { hostPath = "/my/host/dir"; isReadOnly = false; }; + + # Setup port forwarding + # forwardPorts = [ { containerPort = 80; hostPort = 8080; protocol = "tcp";} ]; + + config = { config, pkgs, ... }: { + imports = [ + nix-bitcoin.nixosModules.default + ]; + + # Automatically generate all secrets required by services. + # The secrets are stored in /etc/nix-bitcoin-secrets in the container + nix-bitcoin.generateSecrets = true; + + # Enable some services. + # See ../configuration.nix for all available features. + services.bitcoind.enable = true; + services.electrs.enable = true; + }; + }; + }; + }; + }); +} diff --git a/examples/container/usage.sh b/examples/container/usage.sh new file mode 100644 index 0000000..404c386 --- /dev/null +++ b/examples/container/usage.sh @@ -0,0 +1,47 @@ +# Requirements: +# - A systemd-based Linux distro +# - extra-container (https://github.com/erikarvstedt/extra-container/#install) +# - Nix +# - Root privileges + +#――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― +# Create container + +# Create and start container defined by ./flake.nix +nix run . -- create --start +# You can use the same command to update the (running) container, +# after changing the container configuration. + +# In the default configuration, the container is automatically started on +# system boot (option `autoStart`). + +#――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― +# Use container + +# Run command in container +extra-container run mynode -- hostname +extra-container run mynode -- systemctl status bitcoind +extra-container run mynode -- lightning-cli getinfo +extra-container run mynode -- bash -c 'bitcoin-cli -getinfo && lightning-cli getinfo' + +# Start shell in container +extra-container root-login mynode + +# Show the container filesystem +sudo ls -al /var/lib/nixos-containers/mynode + +#――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― +# Stop container +extra-container stop mynode + +# Resume the container +extra-container start mynode +# You can also use the `create --start` command above + +# Destroy container +nix run . -- destroy + +#――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― +# Inspect container config +nix eval .#default.outPath +nix eval . --apply 'sys: sys.containers.mynode.config.networking.hostName' diff --git a/test/run-tests.sh b/test/run-tests.sh index 223c980..d76f0a6 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -275,6 +275,11 @@ nixosSearch() { "$scriptDir/nixos-search/flake-info-sandboxed.sh" } +persistentContainerExample() { + . "$scriptDir/lib/extra-container-check-version.sh" + nix run "$scriptDir/../examples/container" --override-input nix-bitcoin "$scriptDir/.." -- --run c systemctl status electrs +} + # A basic subset of tests to keep the total runtime within # manageable bounds. # These are also run on the CI server. @@ -310,6 +315,10 @@ examples() { runExample deploy-krops.sh ' (cd "$scriptDir/../examples" && nix-shell --run "$script") + + echo + echo "Running example 'Persistent container'" + persistentContainerExample } shellcheck() {