From 210b8a7c1827a99a610e0178a212b89b3fffd963 Mon Sep 17 00:00:00 2001 From: PatMulligan <43773168+PatMulligan@users.noreply.github.com> Date: Fri, 26 Sep 2025 07:47:02 +0200 Subject: [PATCH] FIX: Flake and Module for NixOS deployment (#3363) --- flake.nix | 3 +- nix/modules/README.md | 213 +++++++++++++++++++++++++++++++++ nix/modules/lnbits-service.nix | 15 +-- 3 files changed, 223 insertions(+), 8 deletions(-) create mode 100644 nix/modules/README.md diff --git a/flake.nix b/flake.nix index 3dfc5099c..8f19bcdfa 100644 --- a/flake.nix +++ b/flake.nix @@ -139,9 +139,10 @@ replaceVars = prev.replaceVars or (path: vars: prev.substituteAll ({ src = path; } // vars)); }; + # System-specific nixos modules to avoid circular dependency nixosModules.default = { pkgs, lib, config, ... }: { imports = [ "${./nix/modules/lnbits-service.nix}" ]; - nixpkgs.overlays = [ self.overlays.default ]; + nixpkgs.overlays = [ self.overlays.${system}.default ]; }; checks = { }; diff --git a/nix/modules/README.md b/nix/modules/README.md new file mode 100644 index 000000000..a538f7484 --- /dev/null +++ b/nix/modules/README.md @@ -0,0 +1,213 @@ +# LNBits NixOS Installation Guide + +This guide shows how to install LNBits on a fresh NixOS system. + +## Quick Start (Recommended) + +Add this to your NixOS configuration (`/etc/nixos/configuration.nix`): + +```nix +{ config, lib, pkgs, ... }: + +let + lnbitsFlake = builtins.getFlake "github:lnbits/lnbits"; +in +{ + imports = [ + # Import LNBits service module directly from GitHub + "${lnbitsFlake}/nix/modules/lnbits-service.nix" + ]; + + # Enable flakes (required) + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + # Configure LNBits service + services.lnbits = { + enable = true; + host = "0.0.0.0"; # Listen on all interfaces + port = 5000; # Default port + openFirewall = true; # Open firewall port automatically + + # Use package from the same flake (adjust system architecture as needed) + package = lnbitsFlake.packages.x86_64-linux.lnbits; + + env = { + LNBITS_ADMIN_UI = "true"; + # Configure your Lightning backend: + # LNBITS_BACKEND_WALLET_CLASS = "LndRestWallet"; + # LND_REST_ENDPOINT = "https://localhost:8080"; + # LND_REST_CERT = "/path/to/tls.cert"; + # LND_REST_MACAROON = "/path/to/admin.macaroon"; + }; + }; + + # Rebuild and switch + # sudo nixos-rebuild switch +} +``` + +> **⚠️ System Architecture Note**: The examples above use `x86_64-linux`. Replace this with your system architecture: +> +> - `x86_64-linux` - Intel/AMD 64-bit Linux +> - `aarch64-linux` - ARM 64-bit Linux (e.g., Raspberry Pi 4, Apple Silicon under Linux) +> - `x86_64-darwin` - Intel Mac +> - `aarch64-darwin` - Apple Silicon Mac +> +> You can check your system with: `nix eval --impure --raw --expr 'builtins.currentSystem'` + +## Alternative: Using Your Own Flake + +Create a `flake.nix` for your system configuration: + +```nix +{ + description = "My NixOS configuration with LNBits"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; + lnbits.url = "github:lnbits/lnbits"; + }; + + outputs = { self, nixpkgs, lnbits }: { + nixosConfigurations.myserver = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; # Adjust architecture as needed + modules = [ + ./hardware-configuration.nix + { + services.lnbits = { + enable = true; + host = "0.0.0.0"; + port = 5000; + openFirewall = true; + package = lnbits.packages.x86_64-linux.lnbits; # Adjust architecture as needed + env = { + LNBITS_ADMIN_UI = "true"; + # Add your Lightning backend configuration + }; + }; + } + ]; + }; + }; +} +``` + +Then deploy with: + +```bash +sudo nixos-rebuild switch --flake .#myserver +``` + +## Configuration Options + +### Basic Options + +- `enable`: Enable the LNBits service (default: `false`) +- `host`: Host to bind to (default: `"127.0.0.1"`) +- `port`: Port to run on (default: `8231`) +- `openFirewall`: Automatically open firewall port (default: `false`) +- `user`: User to run as (default: `"lnbits"`) +- `group`: Group to run as (default: `"lnbits"`) +- `stateDir`: State directory (default: `"/var/lib/lnbits"`) + +### Environment Variables + +Configure LNBits through the `env` option. Common variables: + +```nix +services.lnbits.env = { + # Admin UI + LNBITS_ADMIN_UI = "true"; + + # LND Backend Example: + + # LND + LNBITS_BACKEND_WALLET_CLASS = "LndRestWallet"; + LND_REST_ENDPOINT = "https://localhost:8080"; + LND_REST_CERT = "/path/to/tls.cert"; + LND_REST_MACAROON = "/path/to/admin.macaroon"; +}; +``` + +See the [LNBits documentation](https://docs.lnbits.org/guide/wallets.html) for all supported backends. + +## State Directory Structure + +LNBits data is stored in `/var/lib/lnbits` (default) with this structure: + +``` +/var/lib/lnbits/ +├── data/ # Application data +│ ├── database.sqlite3 # Main database +│ ├── ext_.sqlite3 # Extension database +│ ├── images/ # Uploaded images +│ ├── logs/ # Log files +│ └── upgrades/ # Migration files +└── extensions/ # Installed extensions +``` + +## First Time Setup + +1. **Deploy the configuration:** + + ```bash + sudo nixos-rebuild switch + ``` + +2. **Check service status:** + + ```bash + systemctl status lnbits + ``` + +3. **Access the web interface:** + + ``` + http://your-server-ip:5000 + ``` + +4. **Follow the first-time setup wizard** to configure your Lightning backend and create your first wallet. + +5. **Bonus** Add Reverse Proxy with generated SSL Cert + +```nix +{ +# Enable nginx + services.nginx = { + enable = true; + + virtualHosts."lnbits.mydomain.com" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://127.0.0.1:5000"; + proxyWebsockets = true; + }; + }; + }; +} +``` + +## Troubleshooting + +### Service won't start + +```bash +# Check service logs +journalctl -u lnbits -f + +# Check if port is available +ss -tlnp | grep 5000 +``` + +### Can't access web interface + +- Ensure `openFirewall = true` is set +- Check if the port is correct: `services.lnbits.port` +- Verify host binding: `services.lnbits.host = "0.0.0.0"` + +## Further Reading + +- [LNBits Documentation](https://docs.lnbits.org) +- [Lightning Wallet Configuration](https://docs.lnbits.org/guide/wallets.html) +- [LNBits Extensions](https://docs.lnbits.org/devs/extensions.html) diff --git a/nix/modules/lnbits-service.nix b/nix/modules/lnbits-service.nix index e1cedf4a7..358f30047 100644 --- a/nix/modules/lnbits-service.nix +++ b/nix/modules/lnbits-service.nix @@ -35,7 +35,7 @@ in type = types.path; default = "/var/lib/lnbits"; description = '' - The lnbits state directory which LNBITS_DATA_FOLDER will be set to + The lnbits state directory ''; }; host = mkOption { @@ -90,6 +90,7 @@ in systemd.tmpfiles.rules = [ "d ${cfg.stateDir} 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.stateDir}/data 0700 ${cfg.user} ${cfg.group} - -" ]; systemd.services.lnbits = { @@ -99,18 +100,18 @@ in after = [ "network-online.target" ]; environment = lib.mkMerge [ { - LNBITS_DATA_FOLDER = "${cfg.stateDir}"; - LNBITS_EXTENSIONS_PATH = "${cfg.stateDir}/extensions"; - LNBITS_PATH = "${cfg.package.src}"; + LNBITS_DATA_FOLDER = "${cfg.stateDir}/data"; + # LNBits automatically appends '/extensions' to this path + LNBITS_EXTENSIONS_PATH = "${cfg.stateDir}"; } cfg.env ]; serviceConfig = { User = cfg.user; Group = cfg.group; - WorkingDirectory = "${cfg.package.src}"; - StateDirectory = "${cfg.stateDir}"; - ExecStart = "${lib.getExe cfg.package} --port ${toString cfg.port} --host ${cfg.host}"; + WorkingDirectory = "${cfg.package}/lib/python3.12/site-packages"; + StateDirectory = "lnbits"; + ExecStart = "${cfg.package}/bin/lnbits --port ${toString cfg.port} --host ${cfg.host}"; Restart = "always"; PrivateTmp = true; };