Personal NixOS configuration using flakes, with categorized hosts (laptops, VPS, servers, experiments) and fully automated zero-touch installation. Supports centralized deployment from a main laptop to remote machines without storing git credentials anywhere.
.
├── flake.nix # Main flake configuration
├── mise.toml # Primary task runner (validation/security)
├── justfile # Legacy operational commands (install/deploy)
├── hosts/ # Host-specific configurations by category
│ ├── categories/ # Category-specific base configurations
│ │ ├── laptops.nix # Full workstation config
│ │ ├── vps.nix # Hardened minimal cloud instances
│ │ ├── servers.nix # On-premises server config
│ │ └── experiments.nix # Development/testing config
│ ├── laptops/ # Laptop hosts (bit, spark, hermes)
│ ├── vps/ # VPS hosts
│ ├── servers/ # Server hosts
│ └── experiments/ # Experiment hosts
├── modules/
│ ├── users/ # User-specific configurations (home-manager)
│ │ └── giovanni.nix
│ ├── system/ # System-level modules
│ └── networking/ # Network configuration (Tailscale, firewall, etc.)
├── secrets/ # Encrypted secrets (SOPS)
│ ├── common/ # Shared secrets
│ └── vps/ # VPS-specific secrets (knock sequences)
├── ssh-config/ # SSH configuration examples
└── docs/ # Documentation
├── WORKFLOW.md # Complete workflow guide
├── JUSTFILE_COMMANDS.md # Command reference
├── QUICK_START.md # Quick start guide
├── SOPS_GPG_SETUP.md # Secrets management
└── STRUCTURE_OVERVIEW.md # Architecture overview
- NixOS or Nix with flakes enabled
- Git
- GPG key for secrets encryption
This repo supports user identity overrides without editing module code.
NIXCFG_USER(default:nixos)NIXCFG_GIT_NAME(default:NIXCFG_USER)NIXCFG_GIT_EMAIL(default:<NIXCFG_USER>@localhost)
Example:
export NIXCFG_USER="$USER"
export NIXCFG_GIT_NAME="Your Name"
export NIXCFG_GIT_EMAIL="you@example.com"These values are consumed by flake outputs and Home Manager user module wiring.
📹 New to this setup? Watch the 5-minute quick start tutorial to see the fully automated installation in action.
See docs/WORKFLOW.md for complete installation workflow.
-
Clone this repository:
git clone <your-repo-url> ~/nix-config cd ~/nix-config
-
Install task toolchain and list tasks:
mise install mise tasks ls
-
Enter development environment:
nix develop
-
Set up GPG for secrets:
gpg --full-generate-key # Update .sops.yaml with your GPG fingerprint # See docs/SOPS_GPG_SETUP.md for details
-
Create Tailscale authkey:
# Visit: https://login.tailscale.com/admin/settings/keys # Generate reusable authkey # Add to secrets/common/secrets.yaml sops secrets/common/secrets.yaml
-
Run CI-equivalent validation locally (mise-first):
mise run ci-validate mise run ci-security
-
Install a new host (fully automated):
# Boot NixOS installer on target, note IP # NOTE: currently still routed through legacy just command path just install <hostname> <category> <ip> # Example: Install Framework laptop just install spark laptops 192.168.1.100
That's it! The system installs completely hands-off in ~15 minutes.
# Show available tasks
mise tasks ls
# Formatting
mise run fmt
mise run fmt-check
# Flake validation
mise run flake-check
# Dry-run canonical build target
mise run build-dryrun
# CI-equivalent pipelines
mise run ci-validate
mise run ci-securityEnter the development shell with all tools (deploy-rs, git, sops, etc.):
nix developBuild and switch to new configuration:
sudo nixos-rebuild switch --flake .#laptopBuild without switching (test configuration):
sudo nixos-rebuild build --flake .#laptopUse mise tasks for deploy and secrets workflows.
Deploy to a remote machine:
HOST=<hostname> mise run deploy
# Examples
HOST=spark mise run deploy
HOST=vps-alpha mise run deployPull latest changes and deploy:
HOST=<hostname> mise run pull-deploySync changes made on remote machine back to central repo:
HOST=<hostname> mise run sync-remote
# Then review, commit, and pushmise run update# Still available during migration window:
just --listnix build .#nixosConfigurations.laptop.config.system.build.toplevelFully automated - zero manual steps on target:
# Boot NixOS installer on target machine, note IP
just install <hostname> <category> <ip>
# Examples:
just install spark laptops 192.168.1.100 # Laptop
just install vps-beta vps 203.0.113.50 # VPS
just install server-alpha servers 10.0.0.50 # Server
just install test-vm experiments 192.168.1.200 # ExperimentThe install command automatically:
- Partitions and installs NixOS
- Generates and deploys age encryption key
- Creates host configuration
- Updates .sops.yaml and flake.nix
- Re-encrypts all secrets
- Commits changes to git
- Deploys full configuration
See docs/WORKFLOW.md for complete details.
This repository uses sops-nix with GPG and age for secrets encryption.
mise run secrets # Edit common secrets
FILE=secrets/vps/knock-sequences.yaml mise run secretsFILE=secrets/common/secrets.yaml mise run secrets-viewmise run secrets-updateSee docs/SOPS_GPG_SETUP.md for complete setup guide.
Important: Never commit unencrypted secrets, private keys, or sensitive data to this repository.
Each host category has different security and functionality profiles:
- laptops (bit, spark, hermes): Full workstation with desktop, dev tools, Docker
- vps (vps-alpha, ...): Hardened minimal cloud instances with port knocking, auto-updates
- servers (server-alpha, ...): On-premises servers with Docker, monitoring
- experiments (test-vm, ...): Development/testing with relaxed security
See docs/STRUCTURE_OVERVIEW.md for architecture details.
- Pre-commit hooks validate Nix files and scan for secrets before commits
- GitHub Actions CI runs
misetasks for validation/security on every push - detect-secrets scans for accidentally committed secrets
- sops-nix integration with GPG + age for encrypted secrets management
- Tailscale mesh VPN for secure inter-host communication
- Port knocking for SSH access on VPS hosts
- Hardened kernel and AppArmor on VPS
- fail2ban for SSH brute force protection
- SSH agent forwarding for credential-less git operations on remote machines
mise tasks lsjust rollback <hostname>just generations <hostname>just clean <hostname> # Keep last 30 days
just clean <hostname> 14 # Keep last 14 daysjust dry-run <hostname>just info <hostname>
just tailscale-status <hostname>docs/WORKFLOW.md- Complete hands-off installation and deployment workflowdocs/ARCHITECTURE_FLOWS.md- Layer model and architecture/decision flow diagramsdocs/MISE_TASKS_AND_CI.md- Mise-first task model and CI paritydocs/JUSTFILE_COMMANDS.md- Full command reference with examplesdocs/QUICK_START.md- Quick start guidedocs/SOPS_GPG_SETUP.md- Secrets management with SOPSdocs/STRUCTURE_OVERVIEW.md- Repository architectureAGENTS.md- AI assistant reference guide
# List mise tasks
mise tasks ls
# Run CI-equivalent checks locally
mise run ci-validate
mise run ci-security
# Deploy + sync operations
HOST=<hostname> mise run deploy
HOST=<hostname> mise run pull-deploy
HOST=<hostname> mise run sync-remote
HOST=<hostname> BRANCH=main mise run remote-push
# Secrets operations
mise run secrets
FILE=secrets/common/secrets.yaml mise run secrets-view
mise run secrets-update
# Flake input update
mise run update
# Legacy path for host bootstrap/install (until migrated)
just --list
just install <host> <category> <ip>