Introduced a new example-build-local.nix file to facilitate machine-specific web-app builds, enhancing the deployment process. Updated the .gitignore to include build-local.nix, ensuring user-specific configurations remain untracked. Revised the DEPLOYMENT-GUIDE.md to reflect the addition of build-local.nix and provide clearer instructions for setting up configuration files, improving the onboarding experience for new users.
343 lines
10 KiB
Markdown
343 lines
10 KiB
Markdown
# Web-App Deployment Guide
|
|
|
|
## Overview
|
|
|
|
This setup builds the web-app **locally** with machine-specific configuration, then deploys the built artifacts to each target machine. Each machine gets its own customized build with:
|
|
|
|
- Machine-specific `.env` files
|
|
- Machine-specific images in the `public` folder
|
|
|
|
## Initial Setup
|
|
|
|
When you first clone this repository, you need to set up your local configuration:
|
|
|
|
### 1. Create your configuration files
|
|
|
|
```bash
|
|
# Copy the example templates
|
|
cp example-krops.nix krops.nix
|
|
cp example-build-local.nix build-local.nix
|
|
```
|
|
|
|
### 2. Create your first machine configuration
|
|
|
|
```bash
|
|
# Copy the example machine template
|
|
cp -r config/machines/example-machine config/machines/my-machine
|
|
|
|
# Edit the configuration
|
|
# - Change the domain in configuration.nix
|
|
# - Add your hardware-configuration.nix (from nixos-generate-config)
|
|
```
|
|
|
|
### 3. Create machine-specific web-app assets (if deploying web-app)
|
|
|
|
```bash
|
|
mkdir -p machine-specific/my-machine/env
|
|
mkdir -p machine-specific/my-machine/images
|
|
|
|
# Add your .env file and images
|
|
# See machine-specific/example-machine/ for reference
|
|
```
|
|
|
|
### 4. Update krops.nix and build-local.nix
|
|
|
|
**In `krops.nix`:**
|
|
- Replace `example-machine` with your machine name
|
|
- Update the SSH target (`root@your-host`)
|
|
- Add to the `inherit` list and `all` script
|
|
|
|
**In `build-local.nix`:**
|
|
- Replace `example-machine` with your machine name
|
|
- Add to the `all` build script
|
|
|
|
### 5. Build and deploy!
|
|
|
|
```bash
|
|
# Build web-app locally (if using web-app)
|
|
nix-build ./build-local.nix -A my-machine && ./result/bin/build-my-machine
|
|
|
|
# Deploy to target machine
|
|
nix-build ./krops.nix -A my-machine && ./result
|
|
```
|
|
|
|
**Note:** Your `krops.nix`, `build-local.nix`, and machine configs in `config/machines/*` are gitignored. You can safely pull updates without overwriting your local configuration.
|
|
|
|
## Structure
|
|
|
|
```
|
|
.
|
|
├── config/ # NixOS configuration files
|
|
│ ├── shared.nix # Shared config for all machines
|
|
│ ├── nginx.nix # Nginx configuration
|
|
│ ├── lnbits.nix # LNBits configuration
|
|
│ ├── pict-rs.nix # Pict-rs configuration
|
|
│ └── machines/ # Machine-specific configs (gitignored)
|
|
│ ├── example-machine/ # Template (committed to git)
|
|
│ │ ├── configuration.nix # Main config entry point
|
|
│ │ ├── boot.nix # Bootloader settings
|
|
│ │ └── example-service.nix # Service examples
|
|
│ ├── machine1/ # Your machines (gitignored)
|
|
│ └── machine2/ # Your machines (gitignored)
|
|
├── web-app/ # Shared web-app source (symlink)
|
|
├── machine-specific/ # Machine-specific web-app assets (symlink)
|
|
├── lnbits/ # LNBits source (symlink)
|
|
├── secrets/ # Encrypted secrets
|
|
│ ├── example-machine/
|
|
│ │ └── README.md # Secrets usage guide
|
|
│ ├── machine1/ # Machine-specific secrets
|
|
│ │ └── *.age # Encrypted with age
|
|
│ └── machine2/
|
|
├── build/ # Generated locally (gitignored)
|
|
├── build-local.nix # Local build scripts
|
|
└── krops.nix # Deployment configuration
|
|
```
|
|
|
|
## How It Works
|
|
|
|
### 1. Build Locally
|
|
|
|
First, build the web-app for each machine **on your local machine**:
|
|
|
|
```bash
|
|
# Build for a specific machine
|
|
nix-build ./build-local.nix -A machine1 && ./result/bin/build-machine1
|
|
|
|
# Or build for all machines
|
|
nix-build ./build-local.nix -A all && ./result/bin/build-all
|
|
```
|
|
|
|
This:
|
|
|
|
1. Copies web-app source to `./build/{machine}/`
|
|
2. Copies machine-specific `.env` file
|
|
3. Copies machine-specific images to `public/`
|
|
4. Runs `npm run build`
|
|
5. Creates `./build/{machine}/dist/` with the built app
|
|
|
|
### 2. Deploy Built Artifacts
|
|
|
|
After building, deploy to target machines:
|
|
|
|
```bash
|
|
# Deploy to specific machine
|
|
nix-build ./krops.nix -A machine1 && ./result
|
|
|
|
# Deploy to all machines
|
|
nix-build ./krops.nix -A all && ./result
|
|
```
|
|
|
|
The built files from `./build/{machine}/dist/` are copied to `/var/src/web-app-dist/` on each target machine.
|
|
|
|
## Complete Workflow
|
|
|
|
```bash
|
|
# 1. Build locally for all machines
|
|
nix-build ./build-local.nix -A all && ./result/bin/build-all
|
|
|
|
# 2. Deploy to all machines
|
|
nix-build ./krops.nix -A all && ./result
|
|
```
|
|
|
|
## Customization
|
|
|
|
### Add a new machine
|
|
|
|
1. **Copy the example template:**
|
|
```bash
|
|
cp -r config/machines/example-machine config/machines/my-new-machine
|
|
```
|
|
|
|
2. **Edit the configuration:**
|
|
- Open `config/machines/my-new-machine/configuration.nix`
|
|
- Change `domain = "example.com"` to your domain
|
|
- Add your `hardware-configuration.nix` (from `nixos-generate-config`)
|
|
|
|
3. **Create machine-specific web-app assets** (if using web-app):
|
|
```bash
|
|
mkdir -p machine-specific/my-new-machine/env
|
|
mkdir -p machine-specific/my-new-machine/images
|
|
# Add .env file and images
|
|
```
|
|
|
|
4. **Add to krops.nix and build-local.nix:**
|
|
- Add `my-new-machine` configuration to both files
|
|
|
|
5. **Build and deploy:**
|
|
```bash
|
|
nix-build ./build-local.nix -A my-new-machine && ./result/bin/build-my-new-machine
|
|
nix-build ./krops.nix -A my-new-machine && ./result
|
|
```
|
|
|
|
### Update environment variables
|
|
|
|
Edit `.env` in `machine-specific/{machine-name}/env/.env`, then rebuild locally
|
|
|
|
### Update images
|
|
|
|
Replace files in `machine-specific/{machine-name}/images/`, then rebuild locally
|
|
|
|
### Update web-app code
|
|
|
|
Edit files in `web-app/`, then rebuild locally
|
|
|
|
After any changes: rebuild locally, then redeploy.
|
|
|
|
## Adding Machine-Specific Services
|
|
|
|
Sometimes you need services that only run on certain machines (e.g., WireGuard on machine1 but not machine2).
|
|
|
|
### Using the Example Template
|
|
|
|
A complete example machine configuration is provided in `config/example-machine/`:
|
|
|
|
```
|
|
config/example-machine/
|
|
├── configuration.nix # Template with domain parameter
|
|
├── boot.nix # Bootloader configuration examples
|
|
└── example-service.nix # WireGuard and other service examples
|
|
```
|
|
|
|
**To use the template:**
|
|
1. Copy the `example-machine` directory to your new machine name:
|
|
```bash
|
|
cp -r config/example-machine config/my-new-machine
|
|
```
|
|
2. Edit `configuration.nix` to set your domain
|
|
3. Copy your `hardware-configuration.nix` from `nixos-generate-config`
|
|
4. Customize `boot.nix` for your bootloader (UEFI or BIOS)
|
|
5. Modify or remove `example-service.nix` as needed
|
|
6. Add the machine to `build-local.nix` and `krops.nix`
|
|
|
|
### Example: Machine1 has WireGuard
|
|
|
|
**Structure:**
|
|
```
|
|
config/
|
|
├── shared.nix # Shared config for all machines
|
|
├── machine1/
|
|
│ ├── configuration.nix # Imports shared.nix + machine-specific modules
|
|
│ ├── wireguard.nix # Machine1-specific service
|
|
│ ├── hardware-configuration.nix
|
|
│ └── boot.nix
|
|
└── machine2/
|
|
├── configuration.nix # Only imports shared.nix
|
|
├── hardware-configuration.nix
|
|
└── boot.nix
|
|
```
|
|
|
|
### Steps to Add a Machine-Specific Service
|
|
|
|
1. **Create a service configuration file** in the machine's directory:
|
|
```bash
|
|
# Example: config/machine1/wireguard.nix
|
|
{ config, lib, pkgs, ... }:
|
|
{
|
|
networking.wireguard.interfaces = {
|
|
wg0 = {
|
|
privateKeyFile = "/etc/wireguard/privatekey";
|
|
ips = [ "10.0.0.2/24" ];
|
|
peers = [ ... ];
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
2. **Import it in the machine's configuration.nix**:
|
|
```nix
|
|
# config/machine1/configuration.nix
|
|
{ config, pkgs, ... }:
|
|
{
|
|
imports = [
|
|
(import /var/src/config-shared {
|
|
inherit config pkgs;
|
|
domain = "4lpaca.io";
|
|
})
|
|
./hardware-configuration.nix
|
|
./boot.nix
|
|
./wireguard.nix # ← Add your service here
|
|
];
|
|
}
|
|
```
|
|
|
|
3. **Deploy** - the service will only be deployed to that specific machine:
|
|
```bash
|
|
nix-build ./krops.nix -A machine1 && ./result
|
|
```
|
|
|
|
### Common Machine-Specific Services
|
|
|
|
- **WireGuard VPN** - Only on machines that need VPN access
|
|
- **Backup services** - Different backup targets per machine
|
|
- **Development tools** - Extra packages for staging vs production
|
|
- **Custom hardware drivers** - GPU drivers, specific hardware support
|
|
|
|
The key is that each machine's `configuration.nix` can import different modules while still sharing common configuration through `shared.nix`.
|
|
|
|
## Deploying LNBits Extensions
|
|
|
|
You can deploy custom LNBits extensions to `/var/lib/lnbits/extensions` on your target machines.
|
|
|
|
### Setup
|
|
|
|
**1. Create extensions directory:**
|
|
```bash
|
|
mkdir -p lnbits-extensions
|
|
```
|
|
|
|
**2. Add your custom extensions:**
|
|
```bash
|
|
# Example: Clone a custom extension
|
|
git clone https://github.com/your-org/custom-extension lnbits-extensions/custom-extension
|
|
```
|
|
|
|
**3. Enable in krops.nix:**
|
|
Uncomment the lnbits-extensions line:
|
|
```nix
|
|
lnbits-extensions.file = toString ./lnbits-extensions;
|
|
```
|
|
|
|
**4. Enable in config/lnbits.nix:**
|
|
|
|
Choose one of two options:
|
|
|
|
**Option 1: Replace extensions directory** (use if you manage ALL extensions via deployment)
|
|
```nix
|
|
systemd.tmpfiles.rules = [
|
|
"L+ /var/lib/lnbits/extensions - - - - /var/src/lnbits-extensions"
|
|
];
|
|
```
|
|
⚠️ **Warning:** This will DELETE any extensions installed via the LNBits UI!
|
|
|
|
**Option 2: Merge deployed extensions** (safer - keeps UI-installed extensions)
|
|
```nix
|
|
systemd.services.lnbits-copy-extensions = {
|
|
description = "Copy deployed LNBits extensions";
|
|
before = [ "lnbits.service" ];
|
|
wantedBy = [ "lnbits.service" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
ExecStart = "${pkgs.rsync}/bin/rsync -av /var/src/lnbits-extensions/ /var/lib/lnbits/extensions/";
|
|
};
|
|
};
|
|
```
|
|
|
|
**5. Deploy:**
|
|
```bash
|
|
nix-build ./krops.nix -A machine1 && ./result
|
|
```
|
|
|
|
### How It Works
|
|
|
|
**Option 1 (Symlink):**
|
|
- Your `./lnbits-extensions` directory is deployed to `/var/src/lnbits-extensions`
|
|
- A symlink replaces `/var/lib/lnbits/extensions` → `/var/src/lnbits-extensions`
|
|
- Any existing extensions directory is deleted
|
|
- All extensions must be managed via deployment
|
|
|
|
**Option 2 (Copy/Merge):**
|
|
- Your `./lnbits-extensions` directory is deployed to `/var/src/lnbits-extensions`
|
|
- Deployed extensions are copied into `/var/lib/lnbits/extensions/`
|
|
- Existing UI-installed extensions are preserved
|
|
- You can mix deployed extensions with UI-installed ones
|
|
|