Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21c80a4477 | ||
|
|
4a24d86df0 | ||
|
|
606f0521aa | ||
|
|
27a48795d8 | ||
|
|
88dab86a24 | ||
|
|
508b2f46ec | ||
|
|
f9d0f85d92 | ||
|
|
bd1772482d |
@@ -46,10 +46,28 @@ jobs:
|
||||
run: |
|
||||
ISO_FILE="${{ steps.iso-info.outputs.iso_file }}"
|
||||
if [ -f "$ISO_FILE" ]; then
|
||||
curl -s --fail-with-body -X PUT \
|
||||
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
|
||||
TOKEN="${{ secrets.PACKAGE_TOKEN }}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
TOKEN="${{ secrets.GITEA_TOKEN }}"
|
||||
fi
|
||||
ISO_NAME=$(basename "$ISO_FILE")
|
||||
echo "Publishing $ISO_NAME and naxos-installer-x86_64-linux.iso to Gitea Packages..."
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer/latest/$(basename "$ISO_FILE")" || true
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer-iso/1.0.0/naxos-installer-x86_64-linux.iso" || true
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer-iso/1.0.0/$ISO_NAME" || true
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer/latest/naxos-installer-x86_64-linux.iso" || true
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer/latest/$ISO_NAME" || true
|
||||
fi
|
||||
|
||||
- name: Upload ISO Artifact
|
||||
|
||||
@@ -52,3 +52,58 @@ jobs:
|
||||
echo "Failed to publish package to Gitea Packages ($STATUS): $BODY"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build & Publish Bootable Installer ISO
|
||||
run: |
|
||||
echo "Building NaxOS Bootable Installer ISO..."
|
||||
nix build .#iso --option max-jobs auto
|
||||
ISO_FILE=$(ls result/iso/*.iso | head -n 1)
|
||||
echo "Built ISO image: $ISO_FILE ($(du -h "$ISO_FILE" | cut -f1))"
|
||||
sha256sum "$ISO_FILE" > "$ISO_FILE.sha256"
|
||||
|
||||
TOKEN="${{ secrets.PACKAGE_TOKEN }}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
TOKEN="${{ secrets.GITEA_TOKEN }}"
|
||||
fi
|
||||
|
||||
ISO_NAME=$(basename "$ISO_FILE")
|
||||
echo "Publishing $ISO_NAME and naxos-installer-x86_64-linux.iso to Gitea Packages..."
|
||||
|
||||
# Publish canonical ISO name requested by users
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer-iso/1.0.0/naxos-installer-x86_64-linux.iso" || echo "Canonical ISO already exists"
|
||||
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE.sha256" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer-iso/1.0.0/naxos-installer-x86_64-linux.iso.sha256" || echo "Canonical Checksum already exists"
|
||||
|
||||
# Publish versioned Nix-generated filename
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer-iso/1.0.0/$ISO_NAME" || echo "ISO package already exists"
|
||||
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE.sha256" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer-iso/1.0.0/$ISO_NAME.sha256" || echo "Checksum already exists"
|
||||
|
||||
# Publish latest channel
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
--upload-file "$ISO_FILE" \
|
||||
"${{ github.server_url }}/api/packages/naxos/generic/naxos-installer/latest/naxos-installer-x86_64-linux.iso" || true
|
||||
|
||||
# Attach asset to Gitea release v1.0.0 if present
|
||||
RELEASE_ID=$(curl -s -H "Authorization: token ${TOKEN}" "${{ github.server_url }}/api/v1/repos/naxos/naxos-os/releases/tags/v1.0.0" | jq -r '.id // empty')
|
||||
if [ -n "$RELEASE_ID" ]; then
|
||||
echo "Attaching ISO to Gitea Release v1.0.0 (ID: $RELEASE_ID)..."
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
-H "Content-Type: multipart/form-data" \
|
||||
-F "attachment=@$ISO_FILE;filename=naxos-installer-x86_64-linux.iso" \
|
||||
"${{ github.server_url }}/api/v1/repos/naxos/naxos-os/releases/$RELEASE_ID/assets?name=naxos-installer-x86_64-linux.iso" || true
|
||||
fi
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
# NaxOS Core (`naxos-os`)
|
||||
<p align="center">
|
||||
<img src="docs/images/logo.svg" alt="NaxOS Logo" width="140" height="140" />
|
||||
</p>
|
||||
|
||||
[](https://git.lholz.de/naxos/naxos-os/actions)
|
||||
<h1 align="center">NaxOS Core</h1>
|
||||
|
||||
**NaxOS** is a declarative, appliance-like Network Attached Storage (NAS) operating system built on top of **NixOS** and **OpenZFS**.
|
||||
<p align="center">
|
||||
<b>Declarative, Appliance-Like NixOS- & OpenZFS-Based Network Attached Storage</b>
|
||||
<br />
|
||||
Built on NixOS 26.05 & OpenZFS with GitOps-Driven Management
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://git.lholz.de/naxos/naxos-os/actions"><img src="https://git.lholz.de/naxos/naxos-os/actions/workflows/test-modules.yaml/badge.svg" alt="Gitea Actions" /></a>
|
||||
<a href="https://git.lholz.de/naxos/-/packages"><img src="https://img.shields.io/badge/package-gitea%20registry-blue.svg" alt="Gitea Packages" /></a>
|
||||
<a href="https://git.lholz.de/naxos/naxos-os"><img src="https://img.shields.io/badge/nixos-26.05-5277C3.svg?logo=nixos&logoColor=white" alt="NixOS 26.05" /></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**NaxOS** is a declarative, appliance-like Network Attached Storage (NAS) operating system built on top of **NixOS 26.05** and **OpenZFS**.
|
||||
|
||||
## Appliance Interface Preview
|
||||
|
||||
| Overview Dashboard | OpenZFS Storage Engine |
|
||||
| :---: | :---: |
|
||||
|  |  |
|
||||
| **CNCF Perses Analytics** | **App Store & Runtime** |
|
||||
|  |  |
|
||||
| **Live System & Storage Telemetry** | **App Store & Runtime** |
|
||||
|  |  |
|
||||
|
||||
## Architecture & Features
|
||||
|
||||
@@ -28,9 +44,9 @@
|
||||
- Native NixOS systemd services (e.g. Immich with Intel QuickSync / OpenCL hardware transcoding)
|
||||
- Docker Compose with ZFS copy-on-write storage driver
|
||||
- Optional lightweight K3s cluster integration
|
||||
- **Native Observability**:
|
||||
- Embedded **Perses** analytics dashboards (replacing standalone Grafana)
|
||||
- Prometheus TSDB and Node Exporter
|
||||
- **Seamless Native Observability**:
|
||||
- Seamlessly integrated live telemetry and OpenZFS performance metrics
|
||||
- Prometheus TSDB and Node Exporter embedded into the core appliance
|
||||
- **Streamlined Bootable ISO**:
|
||||
- Interactive CLI / TUI wizard (`naxos-installer`) for rapid bare-metal installation and pool import.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 247 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 282 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 170 KiB |
|
After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1,62 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" width="100%" height="100%">
|
||||
<!-- NaxOS Logo with Transparent Background -->
|
||||
|
||||
<!-- 1. Snowflake (Background Layer) -->
|
||||
<g id="snowflake" stroke="#0cb3e5" stroke-width="28" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- Center Vertical Stem -->
|
||||
<line x1="350" y1="336.5" x2="350" y2="162" />
|
||||
<line x1="350" y1="336.5" x2="350" y2="530" />
|
||||
|
||||
<!-- Top Chevron (inside doorway) -->
|
||||
<line x1="350" y1="202" x2="305" y2="162" />
|
||||
<line x1="350" y1="202" x2="395" y2="162" />
|
||||
|
||||
<!-- Bottom Chevron (inside doorway plinth) -->
|
||||
<line x1="350" y1="475" x2="315" y2="510" />
|
||||
<line x1="350" y1="475" x2="385" y2="510" />
|
||||
|
||||
<!-- Upper Left Arm -->
|
||||
<line x1="350" y1="336.5" x2="145" y2="258" />
|
||||
<line x1="145" y1="258" x2="93" y2="215" />
|
||||
<line x1="145" y1="258" x2="93" y2="301" />
|
||||
<line x1="176" y1="242" x2="158" y2="165" />
|
||||
|
||||
<!-- Lower Left Arm -->
|
||||
<line x1="350" y1="336.5" x2="145" y2="416" />
|
||||
<line x1="145" y1="416" x2="93" y2="373" />
|
||||
<line x1="145" y1="416" x2="93" y2="459" />
|
||||
<line x1="176" y1="432" x2="158" y2="510" />
|
||||
|
||||
<!-- Upper Right Arm -->
|
||||
<line x1="350" y1="336.5" x2="555" y2="258" />
|
||||
<line x1="555" y1="258" x2="607" y2="215" />
|
||||
<line x1="555" y1="258" x2="607" y2="301" />
|
||||
<line x1="524" y1="242" x2="542" y2="165" />
|
||||
|
||||
<!-- Lower Right Arm -->
|
||||
<line x1="350" y1="336.5" x2="555" y2="416" />
|
||||
<line x1="555" y1="416" x2="607" y2="373" />
|
||||
<line x1="555" y1="416" x2="607" y2="459" />
|
||||
<line x1="524" y1="432" x2="542" y2="510" />
|
||||
</g>
|
||||
|
||||
<!-- 2. Portara (Middle Layer) -->
|
||||
<g id="portara">
|
||||
<!-- Dark Navy Outer Frame & Stepped Plinth -->
|
||||
<path d="M 180 56 H 520 V 460 L 525 465 V 540 H 380 V 442 H 420 V 162 H 280 V 442 H 320 V 540 H 175 V 465 L 180 460 Z" fill="#0e4079" />
|
||||
<!-- Royal Blue Inset Fill -->
|
||||
<path d="M 200 76 H 500 V 460 L 505 465 V 540 H 400 V 462 H 440 V 142 H 260 V 462 H 300 V 540 H 195 V 465 L 200 460 Z" fill="#2462b3" />
|
||||
</g>
|
||||
|
||||
<!-- 3. Snow Hills (Foreground Layer) -->
|
||||
<g id="snow">
|
||||
<!-- Right Hill Body -->
|
||||
<path d="M 335 536 C 430 508, 600 510, 665 618 H 180 L 335 536 Z" fill="#acc4db" />
|
||||
<!-- Left Hill Body -->
|
||||
<path d="M 35 618 C 80 545, 220 480, 335 536 L 180 618 Z" fill="#acc4db" />
|
||||
|
||||
<!-- White Crests & Dividing Ridge -->
|
||||
<path d="M 335 536 C 430 508, 600 510, 665 618" fill="none" stroke="#ffffff" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M 35 618 C 80 545, 220 480, 335 536 L 180 618" fill="none" stroke="#ffffff" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 312 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 153 KiB |
|
After Width: | Height: | Size: 312 KiB |
@@ -2,16 +2,16 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1751274312,
|
||||
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
|
||||
"lastModified": 1788405554,
|
||||
"narHash": "sha256-r2f1oUwixlgq9zOdYLqJLfS/lWBT60/IITjhTKI59JU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
|
||||
"rev": "a5cc6f2c37bf518436dc8d1c288ccd0c43c2f4c4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11",
|
||||
"ref": "nixos-26.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "NaxOS: Declarative, Appliance-Like NixOS- & ZFS-Based Network Attached Storage";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
|
||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
|
||||
@@ -52,11 +52,12 @@
|
||||
'';
|
||||
|
||||
# ISO Image identification
|
||||
isoImage.isoBaseName = "naxos-installer";
|
||||
isoImage.volumeID = "NAXOS_INSTALL";
|
||||
image.baseName = lib.mkForce "naxos-installer";
|
||||
isoImage.volumeID = lib.mkForce "NAXOS_INSTALL";
|
||||
isoImage.makeEfiBootable = true;
|
||||
isoImage.makeUsbBootable = true;
|
||||
boot.zfs.forceImportRoot = false;
|
||||
|
||||
# State version
|
||||
system.stateVersion = "24.11";
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
|
||||
@@ -143,6 +143,42 @@ if [ "$CREATE_POOL" = true ] && [ -n "${DISK_DEVICES:-}" ]; then
|
||||
zfs create "$POOL_NAME/container"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Install NaxOS System Modules, Web Dashboard & Management API
|
||||
# ------------------------------------------------------------------------------
|
||||
echo -e "\n${BOLD}[*] Deploying NaxOS Core Modules, Management Daemon & Web UI...${NC}"
|
||||
|
||||
mkdir -p /mnt/etc/nixos/naxos-os
|
||||
mkdir -p /mnt/opt/naxos/ui/dist
|
||||
mkdir -p /mnt/opt/naxos/api
|
||||
mkdir -p /mnt/var/lib/naxos
|
||||
mkdir -p /mnt/etc/naxos/repo
|
||||
|
||||
# 1. Install NaxOS NixOS modules
|
||||
echo " -> Deploying NaxOS appliance modules to /etc/nixos/naxos-os..."
|
||||
if [ -d "/etc/naxos/naxos-os/modules" ]; then
|
||||
cp -r /etc/naxos/naxos-os/* /mnt/etc/nixos/naxos-os/
|
||||
else
|
||||
curl -sSL "https://git.lholz.de/api/packages/naxos/generic/naxos-os-modules/1.0.0/naxos-os-modules.tar.gz" | tar -xz -C /mnt/etc/nixos/naxos-os 2>/dev/null || \
|
||||
git clone https://git.lholz.de/naxos/naxos-os.git /mnt/etc/nixos/naxos-os
|
||||
fi
|
||||
|
||||
# 2. Install NaxOS Web Dashboard SPA
|
||||
echo " -> Deploying NaxOS Web Dashboard into /opt/naxos/ui/dist..."
|
||||
if [ -d "/opt/naxos/ui/dist" ]; then
|
||||
cp -r /opt/naxos/ui/dist/* /mnt/opt/naxos/ui/dist/
|
||||
else
|
||||
curl -sSL "https://git.lholz.de/api/packages/naxos/generic/naxos-ui/1.0.0/naxos-ui-dist.tar.gz" | tar -xz -C /mnt/opt/naxos/ui/dist
|
||||
fi
|
||||
|
||||
# 3. Install NaxOS Management API Daemon
|
||||
echo " -> Deploying NaxOS Management Daemon into /opt/naxos/api..."
|
||||
if [ -d "/opt/naxos/api/dist" ]; then
|
||||
cp -r /opt/naxos/api/* /mnt/opt/naxos/api/
|
||||
else
|
||||
curl -sSL "https://git.lholz.de/api/packages/naxos/generic/naxos-api/1.0.0/naxos-api-1.0.0.tgz" | tar -xz --strip-components=1 -C /mnt/opt/naxos/api
|
||||
fi
|
||||
|
||||
# Generate unique hostId
|
||||
HOST_ID=$(head -c4 /dev/urandom | od -A none -t x4 | tr -d ' ')
|
||||
|
||||
@@ -153,20 +189,24 @@ cat << NIXCONFIG > /mnt/etc/nixos/configuration.nix
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./naxos-os/modules
|
||||
./naxos-os/profiles/nas-appliance.nix
|
||||
];
|
||||
|
||||
# Bootloader & Filesystem
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
|
||||
# Appliance Identity & Network
|
||||
networking.hostName = "$HOSTNAME";
|
||||
networking.hostId = "$HOST_ID";
|
||||
networking.useDHCP = lib.mkDefault $([ "$USE_DHCP" = "yes" ] && echo "true" || echo "false");
|
||||
|
||||
# Safe ZFS extra pools
|
||||
# OpenZFS storage pools
|
||||
boot.zfs.extraPools = [ "$POOL_NAME" $([ -n "$IMPORTED_POOL" ] && echo "\"$IMPORTED_POOL\"") ];
|
||||
|
||||
# Administrator user
|
||||
# System Administrator Account
|
||||
users.users.$ADMIN_USER = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "docker" "video" "render" ];
|
||||
@@ -177,8 +217,20 @@ cat << NIXCONFIG > /mnt/etc/nixos/configuration.nix
|
||||
# SSH Access
|
||||
services.openssh.enable = true;
|
||||
|
||||
# NaxOS Services Activation
|
||||
services.naxos.api.enable = true;
|
||||
services.naxos.ui.enable = true;
|
||||
services.naxos.storage.enable = true;
|
||||
services.naxos.monitoring.enable = true;
|
||||
services.naxos.perses.enable = true;
|
||||
services.naxos.shares.samba.enable = true;
|
||||
services.naxos.shares.nfs.enable = true;
|
||||
services.naxos.appEngine.enable = true;
|
||||
services.naxos.gitops.enable = true;
|
||||
services.naxos.selfUpdate.enable = true;
|
||||
|
||||
# State version
|
||||
system.stateVersion = "24.11";
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
NIXCONFIG
|
||||
|
||||
@@ -188,6 +240,6 @@ nixos-install --no-root-passwd
|
||||
echo -e "\n${BOLD}${GREEN}==============================================${NC}"
|
||||
echo -e "${BOLD}${GREEN} NaxOS Installation Complete!${NC}"
|
||||
echo -e "${BOLD}${GREEN} Remove the installation USB/ISO and reboot.${NC}"
|
||||
echo -e "${BOLD}${GREEN} Access Dashboard on: http://$HOSTNAME.local${NC}"
|
||||
echo -e "${BOLD}${GREEN} Access Web Dashboard on: http://$HOSTNAME.local${NC}"
|
||||
echo -e "${BOLD}${GREEN} Management API: http://$HOSTNAME.local/api/v1/system/status${NC}"
|
||||
echo -e "${BOLD}${GREEN}==============================================${NC}"
|
||||
EOF
|
||||
|
||||
@@ -78,5 +78,5 @@
|
||||
};
|
||||
|
||||
# Nix System State Version
|
||||
system.stateVersion = "24.11";
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
|
||||