NixOS Docker Build (Optional)
Übersicht
Solar-Log kann mit NixOS Flakes gebaut werden für:
✅ Reproduzierbare Builds - Exakt gleiche Ergebnisse
✅ Dependency Management - Automatische Dependencies
✅ Multi-Platform - Linux x86_64, ARM64
✅ Development Shells - Isolierte Entwicklungsumgebungen
⚠️ macOS Limitation: Nix buildLayeredImage funktioniert nicht auf macOS Sequoia (fakeroot Issue). Verwende Dockerfiles stattdessen.
Installation
Nix Package Manager installieren
# Multi-User Installation (empfohlen)
sh <(curl -L https://nixos.org/nix/install) --daemon
# Flakes aktivieren
mkdir -p ~/.config/nix
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
Setup Script (Automatisch)
# Automated Setup
./deployment/nix/setup-nix.sh
# Was wird gemacht:
# 1. Nix installieren (falls nicht vorhanden)
# 2. Flakes aktivieren
# 3. Git Repository initialisieren
# 4. Docker Images bauen
Flake Structure
Datei: flake.nix
{
description = "Solar-Log Enterprise - NixOS Docker Build";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system: {
packages = {
# Backend Docker Image
backend = /* ... */;
# Frontend Docker Image
frontend = /* ... */;
# PostgreSQL Image
postgres = /* ... */;
# Nginx Proxy
nginx = /* ... */;
# Alle Images bauen
dockerAll = /* ... */;
};
devShells = {
# Python Development Shell
python = /* ... */;
# Node.js Development Shell
nodejs = /* ... */;
# Full Stack Shell
default = /* ... */;
};
});
}
Docker Images bauen
Einzelne Images
# Backend Image
nix build .#backend
docker load < result
# Frontend Image
nix build .#frontend
docker load < result
# PostgreSQL
nix build .#postgres
docker load < result
# Nginx Proxy
nix build .#nginx
docker load < result
Alle Images gleichzeitig
# Alle Images bauen
nix build .#dockerAll
# Images laden
docker load < result-backend
docker load < result-frontend
docker load < result-postgres
docker load < result-nginx
Makefile Commands
# NixOS Builds
make nix-build-backend
make nix-build-frontend
make nix-build-all
# Images laden
make nix-load-images
# Cleanup
make nix-clean
Development Shells
Python Shell
# Python Dev Shell aktivieren
nix develop .#python
# Verfügbare Tools:
python --version # Python 3.11
pip --version
black --version # Code Formatter
flake8 --version # Linter
pytest --version # Test Runner
Node.js Shell
# Node.js Dev Shell aktivieren
nix develop .#nodejs
# Verfügbare Tools:
node --version # Node 20.x
npm --version
eslint --version # Linter
prettier --version # Code Formatter
Full Stack Shell (Default)
# Default Dev Shell
nix develop
# Alle Tools verfügbar:
python --version
node --version
docker --version
docker compose version
flake.nix Details
Backend Image Definition
backend = pkgs.dockerTools.buildLayeredImage {
name = "solarlog-backend";
tag = "latest";
contents = with pkgs; [
python311
python311Packages.pip
postgresql
nmap
curl
];
config = {
Cmd = [ "sh" "-c" "uvicorn app.main:app --host 0.0.0.0 --port 8000" ];
ExposedPorts = { "8000/tcp" = {}; };
Env = [
"PYTHONUNBUFFERED=1"
"DATABASE_URL=postgresql://solarlog:solarlog_secret@postgres:5432/solarlog"
];
WorkingDir = "/app";
User = "1000:1000";
};
extraCommands = ''
mkdir -p app data logs tmp
chmod 755 app data logs tmp
'';
};
Frontend Image Definition
frontend = pkgs.dockerTools.buildLayeredImage {
name = "solarlog-frontend";
tag = "latest";
contents = with pkgs; [
nodejs_20
nginx
wget
];
config = {
Cmd = [ "nginx" "-g" "daemon off;" ];
ExposedPorts = { "80/tcp" = {}; };
WorkingDir = "/usr/share/nginx/html";
};
extraCommands = ''
# Build React App
cd /tmp
npm ci --only=production
npm run build
# Copy to Nginx
cp -r build/* usr/share/nginx/html/
'';
};
Build-Cache
Nix Store
# Store Size prüfen
du -sh /nix/store
# Alte Generationen entfernen
nix-collect-garbage -d
# Store optimieren
nix-store --optimise
Build Cache
Cross-Compilation
ARM64 Builds (z.B. Raspberry Pi)
# ARM64 Backend
nix build .#backend --system aarch64-linux
# Alle ARM64 Images
nix build .#dockerAll --system aarch64-linux
Multi-Platform
# In flake.nix
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ] (system: {
packages = {
backend = /* ... */;
frontend = /* ... */;
};
});
CI/CD Integration
GitHub Actions
name: Build with Nix
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v24
with:
nix_path: nixpkgs=channel:nixos-24.05
- uses: cachix/cachix-action@v12
with:
name: solarlog
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build Docker Images
run: |
nix build .#dockerAll
docker load < result-backend
docker load < result-frontend
- name: Push to Registry
run: |
docker tag solarlog-backend:latest ghcr.io/user/solarlog-backend:latest
docker push ghcr.io/user/solarlog-backend:latest
GitLab CI
build:
image: nixos/nix:latest
script:
- nix build .#dockerAll
- docker load < result-backend
- docker load < result-frontend
artifacts:
paths:
- result-*
Troubleshooting
macOS fakeroot Issue
Problem: fakeroot: symbol not found '_fstat$INODE64'
Lösung: Verwende Dockerfiles statt Nix auf macOS:
Permission Errors
Problem: chown: Operation not permitted
Lösung: Entferne chown aus extraCommands:
Build Errors
# Verbose Build
nix build .#backend --print-build-logs
# Debug Mode
nix build .#backend --show-trace
Cache Issues
# Cache zurücksetzen
nix-collect-garbage -d
rm -rf result*
# Neu bauen
nix build .#backend --rebuild
Performance
Layer Caching
buildLayeredImage erstellt automatisch Layers:
- Base Layer: OS + System Packages
- Dependencies Layer: Python/Node Packages
- App Layer: Application Code
Vorteile: - Schnellere Rebuilds - Kleinere Image Sizes - Besseres Caching
Parallel Builds
# Max 8 parallel Jobs
nix build .#dockerAll --max-jobs 8
# Auto-detect CPU Cores
nix build .#dockerAll --max-jobs auto
Migration zu Nix
Von Docker zu Nix
-
Dockerfile analysieren:
-
In flake.nix übersetzen:
-
Build Commands migrieren:
Best Practices
- Pin Nixpkgs Version: Verwende spezifische Nixpkgs Revision
- Separate Layers: Dependencies und App Code trennen
- Minimal Contents: Nur benötigte Packages einbinden
- Health Checks: In Docker Compose statt Nix
- Secrets: Über Environment Variables, nicht in Nix Store
Comparison: Nix vs Dockerfile
| Feature | Nix | Dockerfile |
|---|---|---|
| Reproduzierbarkeit | ✅ 100% | ⚠️ ~80% |
| Build Cache | ✅ Granular | ⚠️ Layer-basiert |
| Cross-Platform | ✅ Native | ⚠️ QEMU |
| macOS Support | ❌ Limitiert | ✅ Voll |
| Learning Curve | ⚠️ Steil | ✅ Flach |
| Ecosystem | ⚠️ Nix-only | ✅ Standard |
Empfehlung: - Entwicklung: Dockerfiles (macOS kompatibel) - Produktion: Nix auf Linux (reproduzierbar) - CI/CD: Nix (konsistente Builds)