From 6f28880d898b820848b88b3158cdec5758a571fb Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 29 Jul 2022 23:42:48 +0800 Subject: [PATCH] initial commit --- .gitignore | 7 ++ LICENSE.md | 22 ++++++ README.org | 38 ++++++++++ flake.lock | 115 ++++++++++++++++++++++++++++++ flake.nix | 58 +++++++++++++++ install.sh | 51 +++++++++++++ nixosModules/admin.nix | 13 ++++ nixosModules/common.nix | 28 ++++++++ nixosModules/docker.nix | 5 ++ nixosModules/hardware-hetzner.nix | 71 ++++++++++++++++++ 10 files changed, 408 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 README.org create mode 100644 flake.lock create mode 100644 flake.nix create mode 100755 install.sh create mode 100644 nixosModules/admin.nix create mode 100644 nixosModules/common.nix create mode 100644 nixosModules/docker.nix create mode 100644 nixosModules/hardware-hetzner.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af4158c --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.vscode +result +.direnv +*.qcow2 +source +.envrc +*.img diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..6669ed1 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,22 @@ +The MIT License (MIT) +===================== + +**Copyright (c) 2022 Fernando Ayats (ayatsfer@gmail.com)** + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.org b/README.org new file mode 100644 index 0000000..aca7e1b --- /dev/null +++ b/README.org @@ -0,0 +1,38 @@ +#+begin_quote +The Golgi apparatus is responsible for transporting, modifying, and packaging +proteins and lipids into vesicles for delivery to targeted destinations. It is +located in the cytoplasm next to the endoplasmic reticulum and near the cell +nucleus. --- Encyclopedia Britanica +#+end_quote + +This server will be an apparatus for better managing my personal projects. It +sits near the idea-generation and idea-translation components of my workflow. It +will be responsible for storing my work as a remote repository, transporting the +work between local development machines, and as a web server to improve the ease +of access of my work, both for myself and anybody curious. + +Let's hope it works well. + +* Setup + +I'm using Hetnezer as a host. Their value for money with VPS offerings is pretty +alluring. + +Additionally I've found a handy [[https://ayats.org/blog/deploy-rs-example/][blog post]] about =deploy-rs= on Hetzner, which is +remarkably convenient. They were even kind enough to link to a [[https://github.com/viperML/deploy-rs-example][repo]] which I've +shamelessly used as a starting point. + + +Unfortunately, Hetnezer doesn't offer a NixOS image, but they do allow you to +mount a NixOS install volume (22.05 as of writing) to your server after creating +it. After doing so, starting the VM we can get it set up simply with: + +#+begin_src shell +sudo -s +nix-shell -p git +git clone https://github.com/tecosaur/golgi +cd golgi +./install.sh +# wait a bit, then create root password +shutdown -h now +#+end_src diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..42b3322 --- /dev/null +++ b/flake.lock @@ -0,0 +1,115 @@ +{ + "nodes": { + "deploy-rs": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1653594315, + "narHash": "sha256-kJ0ENmnQJ4qL2FeYKZba9kvv1KmIuB3NVpBwMeI7AJQ=", + "owner": "serokell", + "repo": "deploy-rs", + "rev": "184349d8149436748986d1bdba087e4149e9c160", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "deploy-rs", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1648199409, + "narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "64a525ee38886ab9028e6f61790de0832aa3ef03", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils-plus": { + "inputs": { + "flake-utils": "flake-utils" + }, + "locked": { + "lastModified": 1657226504, + "narHash": "sha256-GIYNjuq4mJlFgqKsZ+YrgzWm0IpA4axA3MCrdKYj7gs=", + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "2bf0f91643c2e5ae38c1b26893ac2927ac9bd82a", + "type": "github" + }, + "original": { + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1658985539, + "narHash": "sha256-aRVZGndeuUct3S3T6vqOO64D9qY1F7qNTljd0zuwzak=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "174e938d593817f2eb5ae363684dea7c412eb96a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "deploy-rs": "deploy-rs", + "flake-utils-plus": "flake-utils-plus", + "nixpkgs": "nixpkgs" + } + }, + "utils": { + "locked": { + "lastModified": 1648297722, + "narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..bfec544 --- /dev/null +++ b/flake.nix @@ -0,0 +1,58 @@ +{ + description = "My server flake"; + + inputs = { + nixpkgs.url = github:NixOS/nixpkgs/nixos-22.05; + flake-utils-plus.url = github:gytis-ivaskevicius/flake-utils-plus; + deploy-rs = { + url = github:serokell/deploy-rs; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs@{ self, nixpkgs, flake-utils-plus, ... }: + let + nixosModules = flake-utils-plus.lib.exportModules ( + nixpkgs.lib.mapAttrsToList (name: value: ./nixosModules/${name}) (builtins.readDir ./nixosModules) + ); + in + flake-utils-plus.lib.mkFlake { + inherit self inputs nixosModules; + + hosts = { + golgi.modules = with nixosModules; [ + common + admin + hardware-hetzner + # docker + ]; + }; + + deploy.nodes = { + my-node = { + hostname = "5.161.98.27"; + fastConnection = false; + profiles = { + my-profile = { + sshUser = "admin"; + path = + inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.golgi; + user = "root"; + }; + }; + }; + }; + + outputsBuilder = (channels: { + devShell = channels.nixpkgs.mkShell { + name = "my-deploy-shell"; + buildInputs = with channels.nixpkgs; [ + nixUnstable + inputs.deploy-rs.defaultPackage.${system} + ]; + }; + }); + + checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib; + }; +} diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..a270417 --- /dev/null +++ b/install.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p bash gptfdisk util-linux btrfs-progs +set -ex + +if [ "$EUID" -ne 0 ] + then echo "Please run as root for mount permissions!" + exit +fi + +BTRFS_OPTS="compress=zstd,noatime" +MNT="/mnt" +TARGET="/dev/sda" + +# GPT labels +# /dev/sda1 -> BIOS boot +# /dev/sda2 -> BTRFS partition, with +# @rootfs mounted at / +# @nix mounted at /nix +# @boot mounted at /boot +# @swap mounted at /swap + +# Mount everything at /mnt to install the system + +sgdisk --zap-all "${TARGET}" +sgdisk -a1 -n1:2048:4095 -t1:EF02 "${TARGET}" +sgdisk -n2:0:0 -t2:8300 "${TARGET}" + +fdisk -l "${TARGET}" + +mkfs.btrfs -f -L NIXOS "${TARGET}2" + +mkdir -p "${MNT}" +umount -R "${MNT}" || : +mount "${TARGET}2" "${MNT}" +btrfs subvolume create "${MNT}"/@rootfs +btrfs subvolume create "${MNT}"/@nix +btrfs subvolume create "${MNT}"/@boot +btrfs subvolume create "${MNT}"/@swap +umount "${MNT}" + +mount -o "$BTRFS_OPTS,subvol=@rootfs" "${TARGET}2" "${MNT}" +mkdir "${MNT}"/{nix,boot,swap} +mount -o "$BTRFS_OPTS,subvol=@nix" "${TARGET}2" "${MNT}"/nix +mount -o "$BTRFS_OPTS,subvol=@swap" "${TARGET}2" "${MNT}"/swap +mount -o "$BTRFS_OPTS,subvol=@boot" "${TARGET}2" "${MNT}"/boot + +findmnt -R --target "${MNT}" + +# .#golgi is our hostname defined by our flake +nix-shell -p nixUnstable -p git --run "nixos-install --root ${MNT} --flake .#golgi" +umount -R /mnt diff --git a/nixosModules/admin.nix b/nixosModules/admin.nix new file mode 100644 index 0000000..7f730b7 --- /dev/null +++ b/nixosModules/admin.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + users.users.admin = { + name = "admin"; + initialPassword = "1234"; + isNormalUser = true; + extraGroups = [ "wheel" ]; + openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOZZqcJOLdN+QFHKyW8ST2zz750+8TdvO9IT5geXpQVt tec@tranquillity" ]; + }; + security.sudo.wheelNeedsPassword = false; + nix.trustedUsers = [ "@wheel" ]; # https://github.com/serokell/deploy-rs/issues/25 +} diff --git a/nixosModules/common.nix b/nixosModules/common.nix new file mode 100644 index 0000000..7ed19de --- /dev/null +++ b/nixosModules/common.nix @@ -0,0 +1,28 @@ +{ config, pkgs, inputs, ... }: + +{ + time.timeZone = "UTC"; + services.openssh = { enable = true; }; + system.stateVersion = "22.05"; + + nix = { + # Currently needed for flake support, might not be needed in the future + package = pkgs.nixUnstable; + + extraOptions = '' + experimental-features = nix-command flakes + ''; + + # from flake-utils-plus + # Sets NIX_PATH to follow this flake's nix inputs + # So legacy nix-channel is not needed + generateNixPathFromInputs = true; + linkInputs = true; + # Pin our nixpkgs flake to the one used to build the system + generateRegistryFromInputs = true; + }; + + # Set the system revision to the flake revision + # You can query this value with: $ nix-info -m + system.configurationRevision = (if inputs.self ? rev then inputs.self.rev else null); +} diff --git a/nixosModules/docker.nix b/nixosModules/docker.nix new file mode 100644 index 0000000..a11a944 --- /dev/null +++ b/nixosModules/docker.nix @@ -0,0 +1,5 @@ +{ config, pkgs, ... }: +{ + virtualisation.docker.enable = true; + users.users.admin.extraGroups = [ "docker" ]; +} diff --git a/nixosModules/hardware-hetzner.nix b/nixosModules/hardware-hetzner.nix new file mode 100644 index 0000000..55d69dc --- /dev/null +++ b/nixosModules/hardware-hetzner.nix @@ -0,0 +1,71 @@ +{ config, pkgs, modulesPath, ... }: + +{ + networking.networkmanager.enable = true; + + # systemd-timesyncd failed beacuse it didn't wait for network + systemd.services.systemd-timesyncd.after = [ "network-online.target" ]; + systemd.services.systemd-timesyncd.wants = [ "network-online.target" ]; + + boot = { + initrd = { + availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sd_mod" "sr_mod" ]; + kernelModules = [ ]; + }; + kernelModules = [ ]; + extraModulePackages = [ ]; + loader.grub = { + enable = true; + device = "/dev/sda"; + }; + }; + + fileSystems."/" = + { + device = "/dev/disk/by-label/NIXOS"; + fsType = "btrfs"; + options = [ "subvol=@rootfs" "noatime" "compress=zstd" ]; + }; + + fileSystems."/nix" = + { + device = "/dev/disk/by-label/NIXOS"; + fsType = "btrfs"; + options = [ "subvol=@nix" "noatime" "compress=zstd" ]; + }; + + + fileSystems."/boot" = + { + device = "/dev/disk/by-label/NIXOS"; + fsType = "btrfs"; + options = [ "subvol=@boot" "noatime" "compress=zstd" ]; + }; + + fileSystems."/swap" = { + device = "/dev/disk/by-label/NIXOS"; + fsType = "btrfs"; + options = [ "subvol=@swap" "noatime" "compress=zstd" ]; + }; + + systemd.services = { + create-swapfile = { + serviceConfig.Type = "oneshot"; + wantedBy = [ "swap-swapfile.swap" ]; + script = '' + ${pkgs.coreutils}/bin/truncate -s 0 /swap/swapfile + ${pkgs.e2fsprogs}/bin/chattr +C /swap/swapfile + ${pkgs.btrfs-progs}/bin/btrfs property set /swap/swapfile compression none + ''; + }; + }; + + swapDevices = [{ + device = "/swap/swapfile"; + size = (1024 * 2); + }]; + + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; +}