-
-
Notifications
You must be signed in to change notification settings - Fork 300
/
blogs.xml
1259 lines (1009 loc) · 146 KB
/
blogs.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>NixOS Planet</title>
<link>https://planet.nixos.org</link>
<language>en</language>
<description>NixOS Planet - https://planet.nixos.org</description>
<atom:link rel="self" href="https://planet.nixos.org/rss20.xml" type="application/rss+xml"/>
<item>
<title>Craige McWhirter: Building Daedalus Flight on NixOS</title>
<guid isPermaLink="true">http://mcwhirter.com.au//craige/blog/2020/Building_Daedalus_Flight_on_NixOS/</guid>
<link>http://mcwhirter.com.au//craige/blog/2020/Building_Daedalus_Flight_on_NixOS/</link>
<description><p><img alt="NixOS Daedalus Gears by Craige McWhirter" src="http://mcwhirter.com.au/files/NixOS_Daedalus_Gears.png" title="NixOS Daedalus Gears by Craige McWhirter" /></p>
<p><a href="https://daedaluswallet.io/en/flight/">Daedalus Flight</a> was recently released
and this is how you can build and run this version of
<a href="https://daedaluswallet.io/">Deadalus</a> on <a href="https://nixos.org/">NixOS</a>.</p>
<p>If you want to speed the build process up, you can add the
<a href="https://iohk.io/">IOHK</a> <a href="https://nixos.org/nix/">Nix</a> cache to your own NixOS configuration:</p>
<p><a href="https://source.mcwhirter.io/craige/mio-ops/src/branch/master/roles/iohk.nix">iohk.nix</a>:</p>
<pre><code class="nix">nix.binaryCaches = [
"https://cache.nixos.org"
"https://hydra.iohk.io"
];
nix.binaryCachePublicKeys = [
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
</code></pre>
<p>If you haven't already, you can clone the <a href="https://github.com/input-output-hk/daedalus">Daedalus
repo</a> and specifically the
1.0.0 tagged commit:</p>
<pre><code>$ git clone --branch 1.0.0 https://github.com/input-output-hk/daedalus.git
</code></pre>
<p>Once you've cloned the repo and checked you're on the 1.0.0 tagged commit,
you can build Daedalus flight with the following command:</p>
<pre><code>$ nix build -f . daedalus --argstr cluster mainnet_flight
</code></pre>
<p>Once the build completes, you're ready to launch Daedalus Flight:</p>
<pre><code>$ ./result/bin/daedalus
</code></pre>
<p>To verify that you have in fact built Daedalus Flight, first head to the
<code>Daedalus</code> menu then <code>About Daedalus</code>. You should see a title such as
"DAEDALUS 1.0.0". The second check, is to press <code>[Ctl]+d</code> to access <code>Daedalus
Diagnostocs</code> and your <code>Daedalus state directory</code> should have <code>mainnet_flight</code>
at the end of the path.</p>
<p>If you've got these, give yourself a pat on the back and grab yourself a
refreshing bevvy while you wait for blocks to sync.</p>
<p><img alt="Daedalus FC1 screenshot" src="http://mcwhirter.com.au/files/Daedalus_FC1.png" title="Daedalus FC1 screenshot" /></p></description>
<pubDate>Thu, 23 Apr 2020 23:28:59 +0000</pubDate>
</item>
<item>
<title>nixbuild.net: Binary Cache Support</title>
<guid isPermaLink="true">https://blog.nixbuild.net/posts/2020-04-18-binary-cache-support.html</guid>
<link>https://blog.nixbuild.net/posts/2020-04-18-binary-cache-support.html</link>
<description><p>Up until now, nixbuild.net has not supported directly fetching build dependencies from binary caches like <a href="https://cache.nixos.org">cache.nixos.org</a> or <a href="https://cachix.org">Cachix</a>. All build dependencies have instead been uploaded from the user’s local machine to nixbuild.net the first time they’ve been needed.</p>
<p>Today, this bottleneck has been removed, since nixbuild.net now can fetch build dependencies directly from binary caches, without taxing users’ upload bandwidth.</p>
<p>By default, the official Nix binary cache (<a href="https://cache.nixos.org">cache.nixos.org</a>) is added to all nixbuild.net accounts, but a nixbuild.net user can freely decide on which caches that should be queried for build dependencies (including <a href="https://cachix.org">Cachix</a> caches).</p>
<p>An additional benefit of the new support for binary caches is that users that trust the same binary caches automatically share build dependencies from those caches. This means that if one user’s build has triggered a download from for example cache.nixos.org, the next user that comes along and needs the same build dependency doesn’t have to spend time on downloading that dependency.</p>
<p>For more information on how to use binary caches with nixbuild.net, see the <a href="https://docs.nixbuild.net/getting-started/">documentation</a>.</p></description>
<pubDate>Sat, 18 Apr 2020 00:00:00 +0000</pubDate>
<author>support@nixbuild.net (nixbuild.net)</author>
</item>
<item>
<title>Graham Christensen: Erase your darlings</title>
<guid isPermaLink="false">http://grahamc.com//blog/erase-your-darlings</guid>
<link>http://grahamc.com/blog/erase-your-darlings</link>
<description><p>I erase my systems at every boot.</p>
<p>Over time, a system collects state on its root partition. This state
lives in assorted directories like <code class="highlighter-rouge">/etc</code> and <code class="highlighter-rouge">/var</code>, and represents
every under-documented or out-of-order step in bringing up the
services.</p>
<blockquote>
<p>“Right, run <code class="highlighter-rouge">myapp-init</code>.”</p>
</blockquote>
<p>These small, inconsequential “oh, oops” steps are the pieces that get
lost and don’t appear in your runbooks.</p>
<blockquote>
<p>“Just download ca-certificates to … to fix …”</p>
</blockquote>
<p>Each of these quick fixes leaves you doomed to repeat history in three
years when you’re finally doing that dreaded RHEL 7 to RHEL 8 upgrade.</p>
<blockquote>
<p>“Oh, <code class="highlighter-rouge">touch /etc/ipsec.secrets</code> or the l2tp tunnel won’t work.”</p>
</blockquote>
<h3 id="immutable-infrastructure-gets-us-so-close">Immutable infrastructure gets us <em>so</em> close</h3>
<p>Immutable infrastructure is a wonderfully effective method of
eliminating so many of these forgotten steps. Leaning in to the pain
by deleting and replacing your servers on a weekly or monthly basis
means you are constantly testing and exercising your automation and
runbooks.</p>
<p>The nugget here is the regular and indiscriminate removal of system
state. Destroying the whole server doesn’t leave you much room to
forget the little tweaks you made along the way.</p>
<p>These techniques work great when you meet two requirements:</p>
<ul>
<li>you can provision and destroy servers with an API call</li>
<li>the servers aren’t inherently stateful</li>
</ul>
<h4 id="long-running-servers">Long running servers</h4>
<p>There are lots of cases in which immutable infrastructure <em>doesn’t</em>
work, and the dirty secret is <strong>those servers need good tools the
most.</strong></p>
<p>Long-running servers cause long outages. Their runbooks are outdated
and incomplete. They accrete tweaks and turn in to an ossified,
brittle snowflake — except its arms are load-bearing.</p>
<p>Let’s bring the ideas of immutable infrastructure to these systems
too. Whether this system is embedded in a stadium’s jumbotron, in a
datacenter, or under your desk, we <em>can</em> keep the state under control.</p>
<h4 id="fhs-isnt-enough">FHS isn’t enough</h4>
<p>The hard part about applying immutable techniques to long running
servers is knowing exactly where your application state ends and the
operating system, software, and configuration begin.</p>
<p>This is hard because legacy operating systems and the Filesystem
Hierarchy Standard poorly separate these areas of concern. For
example, <code class="highlighter-rouge">/var/lib</code> is for state information, but how much of this do
you actually care about tracking? What did you configure in <code class="highlighter-rouge">/etc</code> on
purpose?</p>
<p>The answer is probably not a lot.</p>
<p>You may not care, but all of this accumulation of junk is a tarpit.
Everything becomes harder: replicating production, testing changes,
undoing mistakes.</p>
<h3 id="new-computer-smell">New computer smell</h3>
<p>Getting a new computer is this moment of cleanliness. The keycaps
don’t have oils on them, the screen is perfect, and the hard drive
is fresh and unspoiled — for about an hour or so.</p>
<p>Let’s get back to that.</p>
<h2 id="how-is-this-possible">How is this possible?</h2>
<p>NixOS can boot with only two directories: <code class="highlighter-rouge">/boot</code>, and <code class="highlighter-rouge">/nix</code>.</p>
<p><code class="highlighter-rouge">/nix</code> contains read-only system configurations, which are specified
by your <code class="highlighter-rouge">configuration.nix</code> and are built and tracked as system
generations. These never change. Once the files are created in <code class="highlighter-rouge">/nix</code>,
the only way to change the config’s contents is to build a new system
configuration with the contents you want.</p>
<p>Any configuration or files created on the drive outside of <code class="highlighter-rouge">/nix</code> is
state and cruft. We can lose everything outside of <code class="highlighter-rouge">/nix</code> and <code class="highlighter-rouge">/boot</code>
and have a healthy system. My technique is to explicitly opt in and
<em>choose</em> which state is important, and only keep that.</p>
<p>How this is possible comes down to the boot sequence.</p>
<p>For NixOS, the bootloader follows the same basic steps as a standard
Linux distribution: the kernel starts with an initial ramdisk, and the
initial ramdisk mounts the system disks.</p>
<p>And here is where the similarities end.</p>
<h3 id="nixoss-early-startup">NixOS’s early startup</h3>
<p>NixOS configures the bootloader to pass some extra information: a
specific system configuration. This is the secret to NixOS’s
bootloader rollbacks, and also the key to erasing our disk on each
boot. The parameter is named <code class="highlighter-rouge">systemConfig</code>.</p>
<p>On every startup the very early boot stage knows what the system’s
configuration should be: the entire system configuration is stored in
the read-only <code class="highlighter-rouge">/nix/store</code>, and the directory passed through
<code class="highlighter-rouge">systemConfig</code> has a reference to the config. Early boot then
manipulates <code class="highlighter-rouge">/etc</code> and <code class="highlighter-rouge">/run</code> to match the chosen setup. Usually this
involves swapping out a few symlinks.</p>
<p>If <code class="highlighter-rouge">/etc</code> simply doesn’t exist, however, early boot <em>creates</em> <code class="highlighter-rouge">/etc</code>
and moves on like it were any other boot. It also <em>creates</em> <code class="highlighter-rouge">/var</code>,
<code class="highlighter-rouge">/dev</code>, <code class="highlighter-rouge">/home</code>, and any other core directories that must be present.</p>
<p>Simply speaking, an empty <code class="highlighter-rouge">/</code> is <em>not surprising</em> to NixOS. In fact,
the NixOS netboot, EC2, and installation media all start out this way.</p>
<h2 id="opting-out">Opting out</h2>
<p>Before we can opt in to saving data, we must opt out of saving data
<em>by default</em>. I do this by setting up my filesystem in a way that
lets me easily and safely erase the unwanted data, while preserving
the data I do want to keep.</p>
<p>My preferred method for this is using a ZFS dataset and rolling it
back to a blank snapshot before it is mounted. A partition of any
other filesystem would work just as well too, running <code class="highlighter-rouge">mkfs</code> at boot,
or something similar. If you have a lot of RAM, you could skip the
erase step and make <code class="highlighter-rouge">/</code> a tmpfs.</p>
<h3 id="opting-out-with-zfs">Opting out with ZFS</h3>
<p>When installing NixOS, I partition my disk with two partitions, one
for the boot partition, and another for a ZFS pool. Then I create and
mount a few datasets.</p>
<p>My root dataset:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># zfs create -p -o mountpoint=legacy rpool/local/root
</code></pre></div></div>
<p>Before I even mount it, I <strong>create a snapshot while it is totally
blank</strong>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># zfs snapshot rpool/local/root@blank
</code></pre></div></div>
<p>And then mount it:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mount -t zfs rpool/local/root /mnt
</code></pre></div></div>
<p>Then I mount the partition I created for the <code class="highlighter-rouge">/boot</code>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mkdir /mnt/boot
# mount /dev/the-boot-partition /mnt/boot
</code></pre></div></div>
<p>Create and mount a dataset for <code class="highlighter-rouge">/nix</code>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># zfs create -p -o mountpoint=legacy rpool/local/nix
# mkdir /mnt/nix
# mount -t zfs rpool/local/nix /mnt/nix
</code></pre></div></div>
<p>And a dataset for <code class="highlighter-rouge">/home</code>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># zfs create -p -o mountpoint=legacy rpool/safe/home
# mkdir /mnt/home
# mount -t zfs rpool/safe/home /mnt/home
</code></pre></div></div>
<p>And finally, a dataset explicitly for state I want to persist between
boots:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># zfs create -p -o mountpoint=legacy rpool/safe/persist
# mkdir /mnt/persist
# mount -t zfs rpool/safe/persist /mnt/persist
</code></pre></div></div>
<blockquote>
<p><em>Note:</em> in my systems, datasets under <code class="highlighter-rouge">rpool/local</code> are never backed
up, and datasets under <code class="highlighter-rouge">rpool/safe</code> are.</p>
</blockquote>
<p>And now safely erasing the root dataset on each boot is very easy:
after devices are made available, roll back to the blank snapshot:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
<span class="nv">boot</span><span class="o">.</span><span class="nv">initrd</span><span class="o">.</span><span class="nv">postDeviceCommands</span> <span class="o">=</span> <span class="nv">lib</span><span class="o">.</span><span class="nv">mkAfter</span> <span class="s2">''</span><span class="err">
</span><span class="s2"> zfs rollback -r rpool/local/root@blank</span><span class="err">
</span><span class="s2"> ''</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>I then finish the installation as normal. If all goes well, your
next boot will start with an empty root partition but otherwise be
configured exactly as you specified.</p>
<h2 id="opting-in">Opting in</h2>
<p>Now that I’m keeping no state, it is time to specify what I do want
to keep. My choices here are different based on the role of the
system: a laptop has different state than a server.</p>
<p>Here are some different pieces of state and how I preserve them. These
examples largely use reconfiguration or symlinks, but using ZFS
datasets and mount points would work too.</p>
<h4 id="wireguard-private-keys">Wireguard private keys</h4>
<p>Create a directory under <code class="highlighter-rouge">/persist</code> for the key:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mkdir -p /persist/etc/wireguard/
</code></pre></div></div>
<p>And use Nix’s wireguard module to generate the key there:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
<span class="nv">networking</span><span class="o">.</span><span class="nv">wireguard</span><span class="o">.</span><span class="nv">interfaces</span><span class="o">.</span><span class="nv">wg0</span> <span class="o">=</span> <span class="p">{</span>
<span class="nv">generatePrivateKeyFile</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nv">privateKeyFile</span> <span class="o">=</span> <span class="s2">"/persist/etc/wireguard/wg0"</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="networkmanager-connections">NetworkManager connections</h4>
<p>Create a directory under <code class="highlighter-rouge">/persist</code>, mirroring the <code class="highlighter-rouge">/etc</code> structure:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mkdir -p /persist/etc/NetworkManager/system-connections
</code></pre></div></div>
<p>And use Nix’s <code class="highlighter-rouge">etc</code> module to set up the symlink:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
<span class="nv">etc</span><span class="o">.</span><span class="s2">"NetworkManager/system-connections"</span> <span class="o">=</span> <span class="p">{</span>
<span class="nv">source</span> <span class="o">=</span> <span class="s2">"/persist/etc/NetworkManager/system-connections/"</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="bluetooth-devices">Bluetooth devices</h4>
<p>Create a directory under <code class="highlighter-rouge">/persist</code>, mirroring the <code class="highlighter-rouge">/var</code> structure:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mkdir -p /persist/var/lib/bluetooth
</code></pre></div></div>
<p>And then use systemd’s tmpfiles.d rules to create a symlink from
<code class="highlighter-rouge">/var/lib/bluetooth</code> to my persisted directory:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
<span class="nv">systemd</span><span class="o">.</span><span class="nv">tmpfiles</span><span class="o">.</span><span class="nv">rules</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">"L /var/lib/bluetooth - - - - /persist/var/lib/bluetooth"</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="ssh-host-keys">SSH host keys</h4>
<p>Create a directory under <code class="highlighter-rouge">/persist</code>, mirroring the <code class="highlighter-rouge">/etc</code> structure:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mkdir -p /persist/etc/ssh
</code></pre></div></div>
<p>And use Nix’s openssh module to create and use the keys in that
directory:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
<span class="nv">services</span><span class="o">.</span><span class="nv">openssh</span> <span class="o">=</span> <span class="p">{</span>
<span class="nv">enable</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nv">hostKeys</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nv">path</span> <span class="o">=</span> <span class="s2">"/persist/ssh/ssh_host_ed25519_key"</span><span class="p">;</span>
<span class="nv">type</span> <span class="o">=</span> <span class="s2">"ed25519"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">{</span>
<span class="nv">path</span> <span class="o">=</span> <span class="s2">"/persist/ssh/ssh_host_rsa_key"</span><span class="p">;</span>
<span class="nv">type</span> <span class="o">=</span> <span class="s2">"rsa"</span><span class="p">;</span>
<span class="nv">bits</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">];</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="acme-certificates">ACME certificates</h4>
<p>Create a directory under <code class="highlighter-rouge">/persist</code>, mirroring the <code class="highlighter-rouge">/var</code> structure:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># mkdir -p /persist/var/lib/acme
</code></pre></div></div>
<p>And then use systemd’s tmpfiles.d rules to create a symlink from
<code class="highlighter-rouge">/var/lib/acme</code> to my persisted directory:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
<span class="nv">systemd</span><span class="o">.</span><span class="nv">tmpfiles</span><span class="o">.</span><span class="nv">rules</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">"L /var/lib/acme - - - - /persist/var/lib/acme"</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="answering-the-question-what-am-i-about-to-lose">Answering the question “what am I about to lose?”</h3>
<p>I found this process a bit scary for the first few weeks: was I losing
important data each reboot? No, I wasn’t.</p>
<p>If you’re worried and want to know what state you’ll lose on the next
boot, you can list the files on your root filesystem and see if you’re
missing something important:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># tree -x /
├── bin
│ └── sh -&gt; /nix/store/97zzcs494vn5k2yw-dash-0.5.10.2/bin/dash
├── boot
├── dev
├── etc
│ ├── asound.conf -&gt; /etc/static/asound.conf
... snip ...
</code></pre></div></div>
<p>ZFS can give you a similar answer:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># zfs diff rpool/local/root@blank
M /
+ /nix
+ /etc
+ /root
+ /var/lib/is-nix-channel-up-to-date
+ /etc/pki/fwupd
+ /etc/pki/fwupd-metadata
... snip ...
</code></pre></div></div>
<h2 id="your-stateless-future">Your stateless future</h2>
<p>You may bump in to new state you meant to be preserving. When I’m
adding new services, I think about the state it is writing and whether
I care about it or not. If I care, I find a way to redirect its state
to <code class="highlighter-rouge">/persist</code>.</p>
<p>Take care to reboot these machines on a somewhat regular basis. It
will keep things agile, proving your system state is tracked
correctly.</p>
<p>This technique has given me the “new computer smell” on every boot
without the datacenter full of hardware, and even on systems that do
carry important state. I have deployed this strategy to systems in the
large and small: build farm servers, database servers, my NAS and home
server, my raspberry pi garage door opener, and laptops.</p>
<p>NixOS enables powerful new deployment models in so many ways, allowing
for systems of all shapes and sizes to be managed properly and
consistently. I think this model of ephemeral roots is yet
another example of this flexibility and power. I would like to see
this partitioning scheme become a reference architecture and take us
out of this eternal tarpit of legacy.</p></description>
<pubDate>Mon, 13 Apr 2020 00:00:00 +0000</pubDate>
</item>
<item>
<title>Graham Christensen: ZFS Datasets for NixOS</title>
<guid isPermaLink="false">http://grahamc.com//blog/nixos-on-zfs</guid>
<link>http://grahamc.com/blog/nixos-on-zfs</link>
<description><p>The outdated and historical nature of the <a href="https://grahamc.com/feed/fhs">Filesystem Hierarchy
Standard</a> means traditional Linux distributions have to go to great
lengths to separate “user data” from “system data.”</p>
<p>NixOS’s filesystem architecture does cleanly separate user data from
system data, and has a much easier job to do.</p>
<h3 id="traditional-linuxes">Traditional Linuxes</h3>
<p>Because FHS mixes these two concerns across the entire hierarchy,
splitting these concerns requires identifying every point across
dozens of directories where the data is the system’s or the user’s.
When adding ZFS to the mix, the installers typically have to create
over a dozen datasets to accomplish this.</p>
<p>For example, Ubuntu’s upcoming ZFS support creates 16 datasets:</p>
<pre><code class="language-tree">rpool/
├── ROOT
│ └── ubuntu_lwmk7c
│ ├── log
│ ├── mail
│ ├── snap
│ ├── spool
│ ├── srv
│ ├── usr
│ │ └── local
│ ├── var
│ │ ├── games
│ │ └── lib
│ │ ├── AccountServices
│ │ ├── apt
│ │ ├── dpkg
│ │ └── NetworkManager
│ └── www
└── USERDATA
</code></pre>
<p>Going through the great pains of separating this data comes with
significant advantages: a recursive snapshot at any point in the tree
will create an atomic, point-in-time snapshot of every dataset below.</p>
<p>This means in order to create a consistent snapshot of the system
data, an administrator would only need to take a recursive snapshot
at <code class="highlighter-rouge">ROOT</code>. The same is true for user data: take a recursive snapshot of
<code class="highlighter-rouge">USERDATA</code> and all user data is saved.</p>
<h3 id="nixos">NixOS</h3>
<p>Because Nix stores all of its build products in <code class="highlighter-rouge">/nix/store</code>, NixOS
doesn’t mingle these two concerns. NixOS’s runtime system, installed
packages, and rollback targets are all stored in <code class="highlighter-rouge">/nix</code>.</p>
<p>User data is not.</p>
<p>This removes the entire complicated tree of datasets to facilitate
FHS, and leaves us with only a few needed datasets.</p>
<h2 id="datasets">Datasets</h2>
<p>Design for the atomic, recursive snapshots when laying out the
datasets.</p>
<p>In particular, I don’t back up the <code class="highlighter-rouge">/nix</code> directory. This entire
directory can always be rebuilt later from the system’s
<code class="highlighter-rouge">configuration.nix</code>, and isn’t worth the space.</p>
<p>One way to model this might be splitting up the data into three
top-level datasets:</p>
<pre><code class="language-tree">tank/
├── local
│ └── nix
├── system
│ └── root
└── user
└── home
</code></pre>
<p>In <code class="highlighter-rouge">tank/local</code>, I would store datasets that should almost never be
snapshotted or backed up. <code class="highlighter-rouge">tank/system</code> would store data that I would
want periodic snapshots for. Most importantly, <code class="highlighter-rouge">tank/user</code> would
contain data I want regular snapshots and backups for, with a long
retention policy.</p>
<p>From here, you could add a ZFS dataset per user:</p>
<pre><code class="language-tree">tank/
├── local
│ └── nix
├── system
│ └── root
└── user
└── home
├── grahamc
└── gustav
</code></pre>
<p>Or a separate dataset for <code class="highlighter-rouge">/var</code>:</p>
<pre><code class="language-tree">tank/
├── local
│ └── nix
├── system
│ ├── var
│ └── root
└── user
</code></pre>
<p>Importantly, this gives you three buckets for independent and
regular snapshots.</p>
<p>The important part is having <code class="highlighter-rouge">/nix</code> under its own top-level dataset.
This makes it a “cousin” to the data you <em>do</em> want backup coverage on,
making it easier to take deep, recursive snapshots atomically.</p>
<h2 id="properties">Properties</h2>
<ul>
<li>Enable compression with <code class="highlighter-rouge">compression=on</code>. Specifying <code class="highlighter-rouge">on</code> instead of
<code class="highlighter-rouge">lz4</code> or another specific algorithm will always pick the best
available compression algorithm.</li>
<li>The dataset containing journald’s logs (where <code class="highlighter-rouge">/var</code> lives) should
have <code class="highlighter-rouge">xattr=sa</code> and <code class="highlighter-rouge">acltype=posixacl</code> set to allow regular users to
read their journal.</li>
<li>Nix doesn’t use <code class="highlighter-rouge">atime</code>, so <code class="highlighter-rouge">atime=off</code> on the <code class="highlighter-rouge">/nix</code> dataset is
fine.</li>
<li>NixOS requires (as of 2020-04-11) <code class="highlighter-rouge">mountpoint=legacy</code> for all
datasets. NixOS does not yet have tooling to require implicitly
created ZFS mounts to settle before booting, and <code class="highlighter-rouge">mountpoint=legacy</code>
plus explicit mount points in <code class="highlighter-rouge">hardware-configuration.nix</code> will
ensure all your datasets are mounted at the right time.</li>
</ul>
<p>I don’t know how to pick <code class="highlighter-rouge">ashift</code>, and usually just allow ZFS to guess
on my behalf.</p>
<h2 id="partitioning">Partitioning</h2>
<p>I only create two partitions:</p>
<ol>
<li><code class="highlighter-rouge">/boot</code> formatted <code class="highlighter-rouge">vfat</code> for EFI, or <code class="highlighter-rouge">ext4</code> for BIOS</li>
<li>The ZFS dataset partition.</li>
</ol>
<p>There are spooky articles saying only give ZFS entire disks. The
truth is, you shouldn’t split a disk into two active partitions.
Splitting the disk this way is just fine, since <code class="highlighter-rouge">/boot</code> is rarely
read or written.</p>
<blockquote>
<p><em>Note:</em> If you do partition the disk, make sure you set the disk’s
scheduler to <code class="highlighter-rouge">none</code>. ZFS takes this step automatically if it does
control the entire disk.</p>
<p>On NixOS, you an set your scheduler to <code class="highlighter-rouge">none</code> via:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> <span class="nv">boot</span><span class="o">.</span><span class="nv">kernelParams</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">"elevator=none"</span> <span class="p">];</span> <span class="p">}</span>
</code></pre></div> </div>
</blockquote>
<h1 id="clean-isolation">Clean isolation</h1>
<p>NixOS’s clean separation of concerns reduces the amount of complexity
we need to track when considering and planning our datasets. This
gives us flexibility later, and enables some superpowers like erasing
my computer on every boot, which I’ll write about on Monday.</p></description>
<pubDate>Sat, 11 Apr 2020 00:00:00 +0000</pubDate>
</item>
<item>
<title>nixbuild.net: New nixbuild.net Resources</title>
<guid isPermaLink="true">https://blog.nixbuild.net/posts/2020-03-27-nixbuild-net-beta.html</guid>
<link>https://blog.nixbuild.net/posts/2020-03-27-nixbuild-net-beta.html</link>
<description><p>On the support side of the nixbuild.net service, two new resources have been published:</p>
<ul>
<li><p><a href="https://docs.nixbuild.net">docs.nixbuild.net</a>, collecting all available documentation for nixbuild.net users.</p></li>
<li><p>The <a href="https://github.com/nixbuild/feedback">nixbuild.net feedback</a> repository on GitHub, providing a way to report issues or ask questions related to the service.</p></li>
</ul>
<p>These resources are mainly useful for nixbuild.net beta users, but they are open to anyone. And anyone is of course welcome to request a free beta account for evaluating nixbuild.net, by just <a href="mailto:rickard@nixbuild.net">sending me an email</a>.</p></description>
<pubDate>Fri, 27 Mar 2020 00:00:00 +0000</pubDate>
<author>support@nixbuild.net (nixbuild.net)</author>
</item>
<item>
<title>Matthew Bauer: Announcing Nixiosk</title>
<guid isPermaLink="true">https://matthewbauer.us/blog/nixiosk.html</guid>
<link>https://matthewbauer.us/blog/nixiosk.html</link>
<description><p>
Today I’m announcing a project I’ve been working on for the last few
weeks. I’m calling it Nixiosk which is kind of a smashing together of
the words NixOS and Kiosk. The idea is to have an easy way to make
locked down, declarative systems
</p>
<p>
My main application of this is my two Raspberry Pi systems that I own.
Quite a few people have installed NixOS on these systems, but usually
they are starting from some prebuilt image. A major goal of this
project is to make it easy to build these images yourself. For this to
work, I’ve had to make lots of changes to NixOS cross-compilation
ecosystem, but the results seem to be very positive. I also want the
system to be locked down so that no user can login directly on the
machine. Instead, all administration is done on a remote machine, and
deployed through SSH and Nix remote builders.
</p>
<p>
Right now, I have RetroArch (a frontend for a bunch of emulators) on
my Raspberry Pi 4, and Epiphany (a web browser) on my Raspberry Pi 0.
Both systems seem to be working pretty well.
</p>
<p>
GitHub: <a href="https://github.com/matthewbauer/nixiosk">https://github.com/matthewbauer/nixiosk</a>
</p>
<div class="outline-2" id="outline-container-org11baea3">
<h2 id="org11baea3"><span class="section-number-2">1</span> Deploying</h2>
<div class="outline-text-2" id="text-1">
</div>
<div class="outline-3" id="outline-container-org3936587">
<h3 id="org3936587"><span class="section-number-3">1.1</span> Install Nix</h3>
<div class="outline-text-3" id="text-1-1">
<p>
If you haven’t already, you need to install Nix. This can be done
through the installer:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ bash &lt;(curl -L https://nixos.org/nix/install)
</pre>
</div>
</div>
</div>
<div class="outline-3" id="outline-container-org9c45d30">
<h3 id="org9c45d30"><span class="section-number-3">1.2</span> Cache</h3>
<div class="outline-text-3" id="text-1-2">
<p>
To speed things up, you should setup a binary cache for nixiosk. This
can be done easily through <a href="https://nixiosk.cachix.org/">Cachix</a>. First, install Cachix:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ nix-env -iA cachix -f https://cachix.org/api/v1/install
</pre>
</div>
<p>
Then, use the nixiosk cache:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ cachix use nixiosk
</pre>
</div>
</div>
</div>
<div class="outline-3" id="outline-container-org16dc38e">
<h3 id="org16dc38e"><span class="section-number-3">1.3</span> Configuration</h3>
<div class="outline-text-3" id="text-1-3">
<p>
To make things simple, it just reads from an ad-hoc JSON file that
describe the hardware plus some other customizations. It looks like
this:
</p>
<div class="org-src-container">
<pre class="src src-json">{
<span class="org-keyword">"hostName"</span>: <span class="org-string">"nixiosk"</span>,
<span class="org-keyword">"hardware"</span>: <span class="org-string">"raspberryPi4"</span>,
<span class="org-keyword">"authorizedKeys"</span>: [],
<span class="org-keyword">"program"</span>: {
<span class="org-keyword">"package"</span>: <span class="org-string">"epiphany"</span>,
<span class="org-keyword">"executable"</span>: <span class="org-string">"/bin/epiphany"</span>,
<span class="org-keyword">"args"</span>: [<span class="org-string">"https://en.wikipedia.org/"</span>]
},
<span class="org-keyword">"networks"</span>: {
<span class="org-keyword">"my-router"</span>: <span class="org-string">"0000000000000000000000000000000000000000000000000000000000000000"</span>,
},
<span class="org-keyword">"locale"</span>: {
<span class="org-keyword">"timeZone"</span>: <span class="org-string">"America/New_York"</span>,
<span class="org-keyword">"regDom"</span>: <span class="org-string">"US"</span>,
<span class="org-keyword">"lang"</span>: <span class="org-string">"en_US.UTF-8"</span>
},
<span class="org-keyword">"localSystem"</span>: {
<span class="org-keyword">"system"</span>: <span class="org-string">"x86_64-linux"</span>,
<span class="org-keyword">"sshUser"</span>: <span class="org-string">"me"</span>,
<span class="org-keyword">"hostName"</span>: <span class="org-string">"my-laptop-host"</span>,
}
}
</pre>
</div>
<p>
Here’s a basic idea of what each of these fields do:
</p>
<ul class="org-ul">
<li>hostName: Name of the host to use. If mDNS is configured on your
network, this can be used to identify the IP address of the device
via “&lt;hostName&gt;.local”.</li>
<li>hardware: A string describing what hardware we are using. Valid
values currently are “raspberryPi0”, “raspberryPi1”, “raspberryPi2”,
“raspberryPi3”, “raspberryPi4”.</li>
<li>authorizedKeys: A list of SSH public keys that are authorized to
make changes to your device. Note this is required because no
passwords will be set for this system.</li>
<li>program: What to do in the kiosk. This should be a Nixpkgs attribute
(<b>package</b>), an <b>executable</b> in that package, and a list of <b>args</b>.</li>
<li>networks: This is a name/value pairing of SSIDs to PSK passphrases.
This can be found with the wpa_passphrase(8) command from
wpa_supplicant.</li>
<li>locale: This provides some information of what localizations to use.
You can set <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">regulation domain</a>, <a href="https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html#Locale-Names">language</a>, <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">time zone</a> via “regDom”,
“lang”, and “timeZone”. If unspecified, defaults to US / English /
New York.</li>
<li>localSystem: Information on system to use for <a href="https://github.com/matthewbauer/nixiosk#remote-builder-optional">remote builder</a>.
Optional.</li>
</ul>
</div>
</div>
<div class="outline-3" id="outline-container-orgddeb048">
<h3 id="orgddeb048"><span class="section-number-3">1.4</span> Initial deployment</h3>
<div class="outline-text-3" id="text-1-4">
<p>
The deployment is pretty easy provided you have <a href="https://nixos.org/nix/">Nix installed</a>. Here
are some steps:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ git clone https://github.com/matthewbauer/nixiosk.git
$ cd nixiosk/
$ cp nixiosk.json.sample nixiosk.json
</pre>
</div>
<p>
Now you need to make some changes to nixiosk.json to reflect what you
want your system to do. The important ones are ‘authorizedKeys’ and
‘networks’ so that your systems can startup and you can connect to it.
</p>
<p>
If you have an SSH key setup, you can get its value with:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ cat $<span class="org-variable-name">HOME</span>/.ssh/id_rsa.pub
<span class="org-whitespace-line">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC050iPG8ckY/dj2O3ol20G2lTdr7ERFz4LD3R4yqoT5W0THjNFdCqavvduCIAtF1Xx/OmTISblnGKf10rYLNzDdyMMFy7tUSiC7/T37EW0s+EFGhS9yOcjCVvHYwgnGZCF4ec33toE8Htq2UKBVgtE0PMwPAyCGYhFxFLYN8J8/xnMNGqNE6iTGbK5qb4yg3rwyrKMXLNGVNsPVcMfdyk3xqUilDp4U7HHQpqX0wKrUvrBZ87LnO9z3X/QIRVQhS5GqnIjRYe4L9yxZtTjW5HdwIq1jcvZc/1Uu7bkMh3gkCwbrpmudSGpdUlyEreaHOJf3XH4psr6IMGVJvxnGiV9 mbauer@dellbook</span>
</pre>
</div>
<p>
which will give you a line for “authorizedKeys” like:
</p>
<div class="org-src-container">
<pre class="src src-json"><span class="org-keyword"><span class="org-whitespace-line">"authorizedKeys"</span></span><span class="org-whitespace-line">: [</span><span class="org-string"><span class="org-whitespace-line">"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC050iPG8ckY/dj2O3ol20G2lTdr7ERFz4LD3R4yqoT5W0THjNFdCqavvduCIAtF1Xx/OmTISblnGKf10rYLNzDdyMMFy7tUSiC7/T37EW0s+EFGhS9yOcjCVvHYwgnGZCF4ec33toE8Htq2UKBVgtE0PMwPAyCGYhFxFLYN8J8/xnMNGqNE6iTGbK5qb4yg3rwyrKMXLNGVNsPVcMfdyk3xqUilDp4U7HHQpqX0wKrUvrBZ87LnO9z3X/QIRVQhS5GqnIjRYe4L9yxZtTjW5HdwIq1jcvZc/1Uu7bkMh3gkCwbrpmudSGpdUlyEreaHOJf3XH4psr6IMGVJvxnGiV9 mbauer@dellbook"</span></span><span class="org-whitespace-line">],</span>
</pre>
</div>
<p>
and you can get a PSK value for your WiFi network with:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ nix run nixpkgs.wpa_supplicant -c wpa_passphrase my-network
<span class="org-variable-name">network</span>={
<span class="org-variable-name">ssid</span>=<span class="org-string">"my-network"</span>
<span class="org-comment-delimiter">#</span><span class="org-comment">psk="abcdefgh"</span>
<span class="org-variable-name">psk</span>=17e76a6490ac112dbeba996caa7cd1387c6ebf6ce721ef704f92b681bb2e9000
}
</pre>
</div>
<p>
so your .json file looks like:
</p>
<div class="org-src-container">
<pre class="src src-json"><span class="org-keyword">"networks"</span>: {
<span class="org-keyword">"my-network"</span>: <span class="org-string">"17e76a6490ac112dbeba996caa7cd1387c6ebf6ce721ef704f92b681bb2e9000"</span>,
},
</pre>
</div>
<p>
Now, after inserting your Raspberry Pi SD card into the primary slot,
you can deploy to it with:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ ./deploy.sh /dev/mmcblk0
</pre>
</div>
<p>
You can now eject your SD card and insert it into your Raspberry Pi.
It will boot immediately to an Epiphany browser, loading
en.wikipedia.org.
</p>
<p>
<a href="https://github.com/matthewbauer/nixiosk#troubleshooting">Troubleshooting steps</a> can be found in the README.
</p>
</div>
</div>
<div class="outline-3" id="outline-container-orgefabaf8">
<h3 id="orgefabaf8"><span class="section-number-3">1.5</span> Redeployments</h3>
<div class="outline-text-3" id="text-1-5">
<p>
You can pretty easily make changes to a running system given you have
SSH access. This is as easy as cloning the running config:
</p>
<div class="org-src-container">
<pre class="src src-sh">$ git clone ssh://root@nixiosk.local/etc/nixos/configuration.git nixiosk-configuration
$ cd nixiosk-configuration
</pre>
</div>
<p>
Then, make some changes in your repo. After your done, you can just
run ‘git push’ to redeploy.
</p>
<div class="org-src-container">
<pre class="src src-sh">$ git add .
$ git commit
$ git push
</pre>
</div>
<p>
You’ll see the NixOS switch-to-configuration log in your command
output. If all is successful, the system should immediately reflect
your changes. If not, the output of Git should explain what went
wrong.
</p>
<p>
Note, that some versions of the Raspberry Pi like the 0 and the 1 are
not big enough to redeploy the whole system. You will probably need to
setup remote builders. This is <a href="https://github.com/matthewbauer/nixiosk#remote-builder-optional">described in the README</a>.
</p>
</div>
</div>
</div>
<div class="outline-2" id="outline-container-org6df267f">
<h2 id="org6df267f"><span class="section-number-2">2</span> Technology</h2>
<div class="outline-text-2" id="text-2">
<p>
Here are some of the pieces that make the Kiosk system possible:
</p>
<ul class="org-ul">
<li><a href="https://www.hjdskes.nl/projects/cage/">Cage</a> / <a href="https://wayland.freedesktop.org/">Wayland</a>: Cage is a Wayland compositor that allows only one
application to display at a time. This makes the system a true
Kiosk.</li>
<li><a href="https://nixos.org/">NixOS</a> - A Linux distro built on top of functional package management.</li>
<li><a href="https://gitlab.com/obsidian.systems/basalt/">Basalt</a>: A tool to manage NixOS directly from Git. This allows doing
push-to-deploy directly to NixOS.</li>
<li><a href="https://www.freedesktop.org/wiki/Software/Plymouth/">Plymouth</a>: Nice graphical boot animations. Right now, it uses the
NixOS logo but in the future this should be configurable so that you
can include your own branding.</li>
<li><a href="https://www.openssh.com/">OpenSSH</a>: Since no direct login is available, SSH is required for
remote administration.</li>
<li><a href="http://www.avahi.org/">Avahi</a>: Configures mDNS registration for the system, allowing you to
remember host names instead of IP addresses.</li>
</ul>
<p>
I would also like to include some more tools to make administration
easier:
</p>
<ul class="org-ul">
<li>ddclient / miniupnp: Allow registering external IP address with a
DNS provider. This would enable administration outside of the
device’s immediate network.</li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-org6777f70">
<h2 id="org6777f70"><span class="section-number-2">3</span> Project</h2>
<div class="outline-text-2" id="text-3">
<p>
You can try it out right now if you have an Raspberry Pi system. Other
hardware is probably not too hard, but may require tweaking. The
project page is available at <a href="https://github.com/matthewbauer/nixiosk">https://github.com/matthewbauer/nixiosk</a>
and issues and pull requests are welcomed.
</p>
</div>
</div></description>
<pubDate>Mon, 23 Mar 2020 00:00:00 +0000</pubDate>
</item>
<item>
<title>Cachix: Proposal for improving Nix error messages</title>
<guid isPermaLink="true">https://blog.cachix.org/post/2020-03-18-proposal-for-improving-nix-error-messages/</guid>
<link>https://blog.cachix.org/post/2020-03-18-proposal-for-improving-nix-error-messages/</link>
<description>I’m lucky to be in touch with a lot of people that use Nix day to day.
One of the most occouring annoyances that pops up more frequently with those starting with Nix are confusing error messages.
Since Nix community has previously succesfully stepped up and funded removal of Perl to reduce barriers for source code contributions, I think we ought to do the same for removing barriers when using Nix.</description>
<pubDate>Wed, 18 Mar 2020 08:00:00 +0000</pubDate>
<author>support@cachix.org (Domen Kožar)</author>
</item>
<item>
<title>Flying Circus: Our new NixOS 19.03 Platform Is Ready for Production</title>
<guid isPermaLink="false">http://blog.flyingcircus.io/?p=5295</guid>
<link>https://blog.flyingcircus.io/2020/02/28/our-new-nixos-19-03-platform-is-ready-for-production/</link>
<description><p>We have developed our third-generation platform which is now based on NixOS 19.03. All provided components have been ported to the new platform and VMs are already running in production.</p>
<p>Most of our development work is done for the new platform and new features will be available only for it. We pull in security updates from upstream regularly and will follow new NixOS releases more quickly in the future. The old NixOS 15.09 platform still receives critical security and bug fixes.</p>
<p>Effective March 6, VMs created via customer self-service will use the 19.03 platform.</p>
<p>You can find the documentation for the new platform here:</p>
<p><a href="https://flyingcircus.io/doc/guide/platform_nixos_2/index.html">https://flyingcircus.io/doc/guide/platform_nixos_2/index.html</a></p>
<p>We recommend user profiles (done with buildEnv) in case your application needs specific packages in its environment:</p>
<p><a href="https://flyingcircus.io/doc/guide/platform_nixos_2/user_profile.html">https://flyingcircus.io/doc/guide/platform_nixos_2/user_profile.html</a></p>