Welcome to CCNIX! This repository serves as a meticulously engineered, 100% reproducible declarative NixOS configuration. It utilizes modern Flake inputs, API-first abstraction for all modules, and a clean separation of system hosts and user profiles.
This README is designed to cover every practical action a user might want to perform within this codebase.
Understanding the structure is the key to mastering this configuration:
flake.nix/flake.lock: Entry points. Pins dependencies globally and declares the target machines.hosts/: Contains machine-specific entry points (likeccnixos). Features specifically bound to hardware go inhardware-configuration.nix.profiles/core/: The absolute central hub for activating system-level options (networking, audio, system apps, docker).profiles/kurnias/: Home Manager configurations and user-specific package toggles (themes, games, developer tools).modules/nixos/: Pure API definitions for NixOS features (e.g.,docker.nix,desktop.nix). Defines variables but doesn't activate them.
This setup relies heavily on the nh (Nix Helper) CLI, which simplifies traditional nixos-rebuild commands and tracks flakes effortlessly.
When you modify anything inside hosts/, profiles/core/, or modules/nixos/, rebuild the OS locally using your zsh alias:
nixbuild
# (Which effectively runs: nh os switch ~/CCNIX)When you modify anything inside profiles/kurnias/, rebuild your user space via:
homebuild
# (Which effectively runs: nh home switch ~/CCNIX)If you want to pull the latest versions of your packages from the nixos-unstable channel to upgrade your entire system:
nix flake update
nixbuildRecover disk space safely by clearing unused Nix store paths while preserving the last 3 generations:
nh clean all --keep 3You never need to write heavy .nix logic to turn features on or off. Everything has been wrapped using lib.mkIf and lib.mkOption toggles to create a clean API.
To toggle core features on your environment, open profiles/core/default.nix. You will see a list of logical switches like this:
ccnix.system.boot.enable = true;
ccnix.virtualisation.docker.enable = true;
ccnix.desktop.enable = true;To turn something off globally across the entire OS, just change true to false and run nixbuild.
Networking logic is exposed through a safe API in profiles/core/default.nix:
ccnix.networking = {
enable = true;
hostName = "my-new-machine";
disableFirewall = false; # Set to true to drop the firewall natively via mkDefault overlays
};User-specific applications should be strictly categorized. Edit profiles/kurnias/home.nix to toggle your personal software bundles:
ccnix.userProfile.packages.enableSystemUtilities = true; # wl-clipboard, cliphist, etc.
ccnix.userProfile.packages.enableThemingTools = true; # matugen, cava, sassc
ccnix.userProfile.devTools.enable = true; # vscode, nvim, nodejs, go
ccnix.userProfile.games.enable = false;
ccnix.userProfile.apps.internet.enable = true; # vesktop, zen-browser, firefoxBy ensuring ccnix.virtualisation.docker.enable = true; is active, your system automatically wires up Docker and Arion. Arion uses Nix modules to define docker-compose projects natively within the Nix store.
To construct or edit your running containers, review modules/nixos/docker.nix. An Arion PostgreSQL database is already scaffolded there:
virtualisation.arion = {
backend = "docker";
projects = {
"db".settings.services."db".service = {
restart = "unless-stopped";
environment = { POSTGRES_PASSWORD = "password"; };
};
};
};To ensure extreme reproducibility and prevent merge conflicts if you scale to multiple machines, you must never hardcode programs.<name>.enable = true directly into a profile unless it is wrapped in an option.
Let's assume you want to add an experimental Video Editing module.
- Create the API file (
modules/nixos/video.nix)
{ config, lib, pkgs, ... }:
let
cfg = config.ccnix.multimedia.video;
in {
# Define your custom option API
options.ccnix.multimedia.video = {
enable = lib.mkEnableOption "Enable Davinci Resolve and related video tools";
};
# Inject the exact logic ONLY if `enable` is checked.
config = lib.mkIf cfg.enable {
environment.systemPackages = [
pkgs.davinci-resolve
pkgs.ffmpeg
];
};
}- Register the API (
profiles/core/default.nix) Make sure Nix is aware of your module by adding it to theimportslist:
imports = [
# ...
+ ../../modules/nixos/video.nix
];- Activate the API! (
profiles/core/default.nix) Now, anyone parsing your flake can provision the entire video editing setup cleanly via:
ccnix.multimedia.video.enable = true;- Prevent Scope Leaks: When importing packages inside this repository, do not use
with pkgs;. Always explicitly name the derivation constraint (e.g.,[ pkgs.firefox pkgs.git ]) to ensure airtight builds that don't break as Nixpkgs evolves. - Avoid Hardcoding Default Rejections: If your module wants to turn something off (like printing), use
lib.mkDefault false;so that dependent endpoints can securely flip it back totruewithout fatal evaluation errors.