8 Commits
Author SHA1 Message Date
Lukas Holzner 21c80a4477 docs(images): refresh all documentation screenshots and add high-res logo.png
Test NaxOS Module Configurations / test-modules (push) Successful in 10m12s
2026-09-04 14:08:49 +02:00
Lukas Holzner 4a24d86df0 fix(iso): use lib.mkForce on image.baseName for NixOS 26.05 compatibility
Test NaxOS Module Configurations / test-modules (push) Successful in 9m38s
2026-09-04 13:47:11 +02:00
Lukas Holzner 606f0521aa docs(telemetry): update README and screenshots to reflect seamless UI telemetry and new logo branding
Test NaxOS Module Configurations / test-modules (push) Failing after 40s
2026-09-04 13:44:20 +02:00
Lukas Holzner 27a48795d8 feat(branding): update logo, adopt NixOS 26.05 release across flake and installer
Test NaxOS Module Configurations / test-modules (push) Failing after 46s
2026-09-04 13:33:13 +02:00
Lukas Holzner 88dab86a24 ci: ensure canonical naxos-installer-x86_64-linux.iso is published and attached to release
Test NaxOS Module Configurations / test-modules (push) Successful in 9m1s
2026-09-04 12:27:47 +02:00
Lukas Holzner 508b2f46ec docs: update authentic application screenshots with Homarr dashboard-icons
Test NaxOS Module Configurations / test-modules (push) Successful in 9m8s
2026-09-04 12:16:58 +02:00
Lukas Holzner f9d0f85d92 ci: update build-iso workflow with PACKAGE_TOKEN fallback
Test NaxOS Module Configurations / test-modules (push) Successful in 7m53s
2026-09-04 09:57:52 +02:00
Lukas Holzner bd1772482d feat(installer): deploy naxos-api, ui, and modules during install, and build ISO in CI
Test NaxOS Module Configurations / test-modules (push) Successful in 9m20s
2026-09-04 09:54:08 +02:00
19 changed files with 229 additions and 25 deletions
+21 -3
View File
@@ -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
+55
View File
@@ -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
+24 -8
View File
@@ -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>
[![Gitea Actions](https://git.lholz.de/naxos/naxos-os/actions/workflows/test-modules.yaml/badge.svg)](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 |
| :---: | :---: |
| ![Dashboard Overview](docs/images/dashboard-overview.png) | ![Storage Management](docs/images/storage-management.png) |
| **CNCF Perses Analytics** | **App Store & Runtime** |
| ![Perses Analytics](docs/images/perses-analytics.png) | ![App Store](docs/images/app-store.png) |
| **Live System & Storage Telemetry** | **App Store & Runtime** |
| ![Live System & Storage Telemetry](docs/images/system-telemetry.png) | ![App Store](docs/images/app-store.png) |
## 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.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+62
View File
@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Generated
+4 -4
View File
@@ -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"
}
+1 -1
View File
@@ -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";
};
+4 -3
View File
@@ -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";
}
+57 -5
View File
@@ -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
+1 -1
View File
@@ -78,5 +78,5 @@
};
# Nix System State Version
system.stateVersion = "24.11";
system.stateVersion = "26.05";
}