2021-02-07 03:52:57 +03:00
<!DOCTYPE HTML>
< html lang = "en" class = "sidebar-visible no-js light" >
< head >
<!-- Book generated using mdBook -->
< meta charset = "UTF-8" >
< title > nixflk docs< / title >
< meta name = "robots" content = "noindex" / >
<!-- Custom HTML head -->
< meta content = "text/html; charset=utf-8" http-equiv = "Content-Type" >
< meta name = "description" content = "" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< meta name = "theme-color" content = "#ffffff" / >
< link rel = "icon" href = "favicon.svg" >
< link rel = "shortcut icon" href = "favicon.png" >
< link rel = "stylesheet" href = "css/variables.css" >
< link rel = "stylesheet" href = "css/general.css" >
< link rel = "stylesheet" href = "css/chrome.css" >
< link rel = "stylesheet" href = "css/print.css" media = "print" >
<!-- Fonts -->
< link rel = "stylesheet" href = "FontAwesome/css/font-awesome.css" >
< link rel = "stylesheet" href = "fonts/fonts.css" >
<!-- Highlight.js Stylesheets -->
< link rel = "stylesheet" href = "highlight.css" >
< link rel = "stylesheet" href = "tomorrow-night.css" >
< link rel = "stylesheet" href = "ayu-highlight.css" >
<!-- Custom theme stylesheets -->
< / head >
< body >
<!-- Provide site root to javascript -->
< script type = "text/javascript" >
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
< / script >
<!-- Work around some values being stored in localStorage wrapped in quotes -->
< script type = "text/javascript" >
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') & & theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') & & sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
< / script >
<!-- Set the theme before any content is loaded, prevents flash -->
< script type = "text/javascript" >
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
< / script >
<!-- Hide / unhide sidebar before it is displayed -->
< script type = "text/javascript" >
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
< / script >
< nav id = "sidebar" class = "sidebar" aria-label = "Table of contents" >
< div class = "sidebar-scrollbox" >
2021-02-07 07:13:37 +03:00
< ol class = "chapter" > < li class = "chapter-item expanded " > < a href = "introduction.html" > < strong aria-hidden = "true" > 1.< / strong > Introduction< / a > < / li > < li class = "chapter-item expanded " > < a href = "start/quick-start.html" > < strong aria-hidden = "true" > 2.< / strong > Quick Start< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "start/iso.html" > < strong aria-hidden = "true" > 2.1.< / strong > ISO< / a > < / li > < li class = "chapter-item expanded " > < a href = "start/from-nixos.html" > < strong aria-hidden = "true" > 2.2.< / strong > From NixOS< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "layout/layout.html" > < strong aria-hidden = "true" > 3.< / strong > Layout< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "layout/hosts.html" > < strong aria-hidden = "true" > 3.1.< / strong > Hosts< / a > < / li > < li class = "chapter-item expanded " > < a href = "layout/profiles.html" > < strong aria-hidden = "true" > 3.2.< / strong > Profiles< / a > < / li > < li class = "chapter-item expanded " > < a href = "layout/suites.html" > < strong aria-hidden = "true" > 3.3.< / strong > Suites< / a > < / li > < li class = "chapter-item expanded " > < a href = "layout/users.html" > < strong aria-hidden = "true" > 3.4.< / strong > Users< / a > < / li > < / ol > < / li > < / ol >
2021-02-07 03:52:57 +03:00
< / div >
< div id = "sidebar-resize-handle" class = "sidebar-resize-handle" > < / div >
< / nav >
< div id = "page-wrapper" class = "page-wrapper" >
< div class = "page" >
< div id = "menu-bar-hover-placeholder" > < / div >
< div id = "menu-bar" class = "menu-bar sticky bordered" >
< div class = "left-buttons" >
< button id = "sidebar-toggle" class = "icon-button" type = "button" title = "Toggle Table of Contents" aria-label = "Toggle Table of Contents" aria-controls = "sidebar" >
< i class = "fa fa-bars" > < / i >
< / button >
< button id = "theme-toggle" class = "icon-button" type = "button" title = "Change theme" aria-label = "Change theme" aria-haspopup = "true" aria-expanded = "false" aria-controls = "theme-list" >
< i class = "fa fa-paint-brush" > < / i >
< / button >
< ul id = "theme-list" class = "theme-popup" aria-label = "Themes" role = "menu" >
< li role = "none" > < button role = "menuitem" class = "theme" id = "light" > Light (default)< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "rust" > Rust< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "coal" > Coal< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "navy" > Navy< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "ayu" > Ayu< / button > < / li >
< / ul >
< button id = "search-toggle" class = "icon-button" type = "button" title = "Search. (Shortkey: s)" aria-label = "Toggle Searchbar" aria-expanded = "false" aria-keyshortcuts = "S" aria-controls = "searchbar" >
< i class = "fa fa-search" > < / i >
< / button >
< / div >
< h1 class = "menu-title" > nixflk docs< / h1 >
< div class = "right-buttons" >
< a href = "print.html" title = "Print this book" aria-label = "Print this book" >
< i id = "print-button" class = "fa fa-print" > < / i >
< / a >
< / div >
< / div >
< div id = "search-wrapper" class = "hidden" >
< form id = "searchbar-outer" class = "searchbar-outer" >
< input type = "search" name = "search" id = "searchbar" name = "searchbar" placeholder = "Search this book ..." aria-controls = "searchresults-outer" aria-describedby = "searchresults-header" >
< / form >
< div id = "searchresults-outer" class = "searchresults-outer hidden" >
< div id = "searchresults-header" class = "searchresults-header" > < / div >
< ul id = "searchresults" >
< / ul >
< / div >
< / div >
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
< script type = "text/javascript" >
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
< / script >
< div id = "content" class = "content" >
< main >
< h1 > < a class = "header" href = "#introduction" id = "introduction" > Introduction< / a > < / h1 >
< p > Nixflk is a template which grants a simple way to use, deploy and manage
< a href = "https://nixos.org/manual/nixos/stable" > NixOS< / a > systems for personal and productive use. It does this by
providing a sane repository structure, integrating several popular projects
like < a href = "https://nix-community.github.io/home-manager" > home-manager< / a > , setting clear guidelines, offering useful
conveniences, and eliminating boilerplate so you can focus on deploying your
systems.< / p >
< h2 > < a class = "header" href = "#community-profiles" id = "community-profiles" > Community Profiles< / a > < / h2 >
< p > There are two branches from which to choose: core and community. The commuity
branch builds on core and includes several ready-made profiles for
discretionary employment.< / p >
< h3 > < a class = "header" href = "#-advisory" id = "-advisory" > ⚠ Advisory< / a > < / h3 >
< p > Nixflk leverages the < a href = "https://nixos.wiki/wiki/Flakes" > flakes< / a > feature available via an < em > experimental< / em >
branch of < a href = "https://nixos.org/manual/nix/stable" > nix< / a > . Until nix 3.0 is released, this project should be
considered unstable.< / p >
< h1 > < a class = "header" href = "#license" id = "license" > License< / a > < / h1 >
< p > Nixflk is licensed under the < a href = "https://mit-license.org" > MIT License< / a > .< / p >
< h1 > < a class = "header" href = "#quick-start" id = "quick-start" > Quick Start< / a > < / h1 >
< p > The only dependency is nix, so make sure you have it < a href = "https://nixos.org/manual/nix/stable/#sect-multi-user-installation" > installed< / a > .< / p >
< h2 > < a class = "header" href = "#get-the-template" id = "get-the-template" > Get the Template< / a > < / h2 >
< p > Here is a snippet that will work as long as < code > nix-shell< / code > is in your path:< / p >
< pre > < code class = "language-sh" > nix-shell https://github.com/nrdxp/nixflk/archive/core.tar.gz -A shell \
--run " flk get core"
cd flk
nix-shell
git init
git add .
git commit -m init
< / code > < / pre >
< blockquote >
< p > You can change < code > core< / code > to < code > community< / code > in the call to < code > flk get< / code > < / p >
< / blockquote >
< p > This will place you in a new folder named < code > flk< / code > in the current directory with
git set up, and a nix-shell that provides all the dependencies, including the
required nix version.< / p >
< h2 > < a class = "header" href = "#next-steps" id = "next-steps" > Next Steps:< / a > < / h2 >
< ul >
2021-02-07 05:14:15 +03:00
< li > < a href = "start/./iso.html" > Make installable ISO< / a > < / li >
< li > < a href = "start/./from-nixos.html" > Already on NixOS< / a > < / li >
< li > < a href = "start/./from-linux.html" > Install from Linux< / a > < / li >
2021-02-07 03:52:57 +03:00
< / ul >
< h1 > < a class = "header" href = "#iso" id = "iso" > ISO< / a > < / h1 >
< p > Making and writing an installable iso for < code > hosts/NixOS.nix< / code > is as simple as:< / p >
< pre > < code class = "language-sh" > flk iso NixOS
dd bs=4M if=result/iso/*.iso of=/dev/$your_installation_device \
status=progress oflag=sync
< / code > < / pre >
< p > This works for any file matching < code > hosts/*.nix< / code > excluding < code > default.nix< / code > .< / p >
< h1 > < a class = "header" href = "#from-nixos" id = "from-nixos" > From NixOS< / a > < / h1 >
< h2 > < a class = "header" href = "#generate-configuration" id = "generate-configuration" > Generate Configuration< / a > < / h2 >
< p > Assuming your happy with your existing partition layout, you can generate a
basic NixOS configuration for your system using:< / p >
< pre > < code > flk up
< / code > < / pre >
< p > This will make a new file < code > hosts/up-$(hostname).nix< / code > , which you can edit to
your liking.< / p >
< blockquote >
< p > While the < code > up< / code > sub-command is provided as a convenience to quickly set up and
install a " fresh" NixOS system on current hardware, committing these files is
discouraged.< / p >
< p > They are placed in the git staging area automatically because they would be
invisible to the flake otherwise, but it is best to move what you need from
them directly into a host module of your own making, and commit that instead.< / p >
< / blockquote >
< p > Make sure your < code > i18n.defaultLocale< / code > and < code > time.timeZone< / code > are set properly for
your region. Keep in mind that < code > networking.hostName< / code > with be automatically
set to the filename of your hosts file, so < code > hosts/my-host.nix< / code > will have the
hostname < code > my-host< / code > .< / p >
2021-02-07 06:07:38 +03:00
< p > Now might be a good time to read the docs on < a href = "start/../layout/suites.html" > suites< / a > and
< a href = "start/../layout/profiles.html" > profiles< / a > and add or create any that you need.< / p >
2021-02-07 03:52:57 +03:00
< h1 > < a class = "header" href = "#installation" id = "installation" > Installation< / a > < / h1 >
< p > Once your ready to deploy < code > hosts/my-host.nix< / code > :< / p >
< pre > < code > flk my-host switch
< / code > < / pre >
< blockquote >
< p > Instead of < code > switch< / code > , you can pass < code > build< / code > , < code > test< / code > , < code > boot< / code > , etc just as with
< code > nixos-rebuild< / code > .< / p >
< / blockquote >
< p > This calls < code > nixos-rebuild< / code > with sudo to build and install your configuration.< / p >
< blockquote >
< p > It is convenient to have the template living at < code > /etc/nixos< / code > so you can
simply < code > sudo nixos-rebuild switch< / code > from anywhere on the system, but it is
not required.< / p >
< / blockquote >
< h1 > < a class = "header" href = "#layout" id = "layout" > Layout< / a > < / h1 >
< p > This section describes the layout of nixflk and the purpose of each
subdirectory.< / p >
< h1 > < a class = "header" href = "#hosts" id = "hosts" > Hosts< / a > < / h1 >
< p > Nix flakes contain an output called < code > nixosConfigurations< / code > declaring an
attribute set of valid NixOS systems. To simplify the management and creation
of these hosts, nixflk automatically imports every < code > *.nix< / code > file inside this
directory to the mentioned attribute set, applying the projects defaults to
each. The only hard requirement is that the file contain a valid NixOS module.< / p >
< p > As an example, a file < code > hosts/system.nix< / code > will be available via the flake
output < code > nixosConfigurations.system< / code > . You can have as many hosts as you want
and all of them will be automatically imported based on their name.< / p >
< p > For each host, the configuration automatically sets the < code > networking.hostName< / code >
attribute to the name of the file minus the < code > .nix< / code > extension. This is for
convenience, since < code > nixos-rebuild< / code > automatically searches for a configuration
matching the current systems hostname if one is not specified explicitly.< / p >
< p > It is recommended that the host modules only contain configuration information
specific to a particular piece of hardware. Anything reusable across machines
2021-02-07 05:14:15 +03:00
is best saved for < a href = "layout/./profiles.html" > profile modules< / a > .< / p >
< p > This is a good place to import sets of profiles, called < a href = "layout/./suites.html" > suites< / a > ,
2021-02-07 03:52:57 +03:00
that you intend to use on your machine.< / p >
< p > Additionally, this is the perfect place to import anything you might need from
the < a href = "https://github.com/NixOS/nixos-hardware" > nixos-hardware< / a > repository.< / p >
< h2 > < a class = "header" href = "#example" id = "example" > Example< / a > < / h2 >
< p > < code > hosts/librem.nix< / code > :< / p >
< pre > < code class = "language-nix" > { suites, hardware, ... }:
{
imports = suites.laptop ++ [ hardware.purism-librem-13v3 ];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
fileSystems." /" = { device = " /dev/disk/by-label/nixos" ; };
}
< / code > < / pre >
2021-02-07 06:07:38 +03:00
< h1 > < a class = "header" href = "#profiles" id = "profiles" > Profiles< / a > < / h1 >
< p > Profiles are simply NixOS modules which contain generic expressions suitable
for any host. A good example is the configuration for a text editor, or
window manager. If you need some concrete examples, just checkout the
community < a href = "https://github.com/nrdxp/nixflk/tree/community/profiles" > branch< / a > .< / p >
< h2 > < a class = "header" href = "#constaints" id = "constaints" > Constaints< / a > < / h2 >
< p > For the sake of consistency, there are a few minor constraints. First of all, a
profile should always be defined in a < code > default.nix< / code > , and it should always be a
a function taking a single attribute set as an argument, and returning a NixOS
module which does not define any new module options. If you need to make new
module option declarations, just use < a href = "layout/./modules" > modules< / a > .< / p >
< p > These restrictions help simplify the import logic used to pass profles to
< a href = "layout/./suites" > suites< / a > .< / p >
< h3 > < a class = "header" href = "#example-1" id = "example-1" > Example< / a > < / h3 >
< p > ✔< code > profiles/develop/default.nix< / code > :< / p >
< pre > < code class = "language-nix" > # good profile definition
2021-02-07 06:18:20 +03:00
{ ... }:
2021-02-07 06:07:38 +03:00
{
2021-02-07 06:18:20 +03:00
programs.zsh.enable = true;
2021-02-07 06:07:38 +03:00
}
< / code > < / pre >
< p > ❌< code > profiles/develop.nix< / code > :< / p >
< pre > < code > # bad profile definition
{
options = {};
}
< / code > < / pre >
< h2 > < a class = "header" href = "#subprofiles" id = "subprofiles" > Subprofiles< / a > < / h2 >
< p > Profiles can also define subprofiles. They follow the same constraints outlined
above. A good top level profile should be a high level concern, such a your
personal development environment, and the subprofiles should be more concrete
program configurations such as your text editor, and shell configs. This way,
you can either pull in the whole development profile, or pick and choose
individual programs.< / p >
< h2 > < a class = "header" href = "#conclusion" id = "conclusion" > Conclusion< / a > < / h2 >
< p > Profiles are the most important concept in nixflk. They allow us to keep our
nix expressions self contained and modular. This way we can maximize reuse
while minimizing boilerplate. Always strive to keep your profiles as generic
and modular as possible. Anything machine specific belongs in your
< a href = "layout/./hosts" > host< / a > files.< / p >
2021-02-07 06:26:50 +03:00
< h1 > < a class = "header" href = "#suites" id = "suites" > Suites< / a > < / h1 >
< p > Suites provide a mechanism for users to easily combine and name collecitons of
profiles. For good examples, check out the suites defined in the community
< a href = "https://github.com/nrdxp/nixflk/blob/community/suites/default.nix" > branch< / a > .< / p >
< p > In the future, we will use suites as a mechanism for deploying various machine
types which don't depend on hardware, such as vm's and containers.< / p >
< h2 > < a class = "header" href = "#definition" id = "definition" > Definition< / a > < / h2 >
< pre > < code class = "language-nix" > rec {
workstation = [ profiles.develop profiles.graphical users.nixos ];
mobileWS = workstation ++ [ profiles.laptop ];
}
< / code > < / pre >
< h2 > < a class = "header" href = "#usage" id = "usage" > Usage< / a > < / h2 >
< p > < code > hosts/my-laptop.nix< / code > :< / p >
< pre > < code class = "language-nix" > { suites, ... }:
{
imports = suites.mobileWS;
}
2021-02-07 07:13:37 +03:00
< / code > < / pre >
< h1 > < a class = "header" href = "#users" id = "users" > Users< / a > < / h1 >
< p > Users are a special case of < a href = "layout/./profiles.html" > profiles< / a > that define system users
and < a href = "https://nix-community.github.io/home-manager" > home-manager< / a > configurations. For your convenience, home
manager is wired in by default so all you have to worry about is declaring your
users. For a fully fleshed out example, check out the developers personal
< a href = "https://github.com/nrdxp/nixflk/tree/nrd/users/nrd/default.nix" > branch< / a > .< / p >
< h2 > < a class = "header" href = "#basic-usage" id = "basic-usage" > Basic Usage< / a > < / h2 >
< p > < code > users/myuser/default.nix< / code > :< / p >
< pre > < code class = "language-nix" > { ... }:
{
users.users.myuser = {
isNormalUser = true;
};
home-manager.users.myuser = {
programs.mpv.enable = true;
};
};
< / code > < / pre >
< h2 > < a class = "header" href = "#external-usage" id = "external-usage" > External Usage< / a > < / h2 >
< p > You can easily use the defined home-manager configurations outside of NixOS
using the < code > hmActivations< / code > meta-package defined in the flakes < code > legacyPackages< / code >
output. The < a href = "layout/../flk/flk.html" > flk< / a > helper script makes this even easier. Just
make sure you have home-manager
< a href = "https://nix-community.github.io/home-manager/index.html#ch-installation" > installed< / a > .< / p >
< p > This is great for keeping your environment consistent across Unix systems,
including OSX.< / p >
< h3 > < a class = "header" href = "#from-within-the-projects-devshell" id = "from-within-the-projects-devshell" > From within the projects devshell:< / a > < / h3 >
< pre > < code class = "language-sh" > # builds the nixos user defined in the NixOS host
flk home NixOS nixos
# activate
flk home NixOS nixos switch
< / code > < / pre >
< h3 > < a class = "header" href = "#manually-from-outside-the-project" id = "manually-from-outside-the-project" > Manually from outside the project:< / a > < / h3 >
< pre > < code class = "language-sh" > # build
nix build " github:nrdxp/nixflk#hmActivationPackages.NixOS.nixos"
# activate
./result/activate & & unlink result
2021-02-07 06:26:50 +03:00
< / code > < / pre >
2021-02-07 03:52:57 +03:00
< / main >
< nav class = "nav-wrapper" aria-label = "Page navigation" >
<!-- Mobile navigation buttons -->
< div style = "clear: both" > < / div >
< / nav >
< / div >
< / div >
< nav class = "nav-wide-wrapper" aria-label = "Page navigation" >
< / nav >
< / div >
< script type = "text/javascript" >
window.playground_copyable = true;
< / script >
< script src = "elasticlunr.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "mark.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "searcher.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "clipboard.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "highlight.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "book.js" type = "text/javascript" charset = "utf-8" > < / script >
<!-- Custom JS scripts -->
< script type = "text/javascript" >
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
< / script >
< / body >
< / html >