summaryrefslogtreecommitdiff
path: root/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx')
-rw-r--r--src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx284
1 files changed, 0 insertions, 284 deletions
diff --git a/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx b/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx
deleted file mode 100644
index 7b8c235..0000000
--- a/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx
+++ /dev/null
@@ -1,284 +0,0 @@
----
-title: "NixOS: The perfect distro for a production server"
-description: My experience using NixOS to manage my production VPS
-date: 2025-01-01
----
-
-NixOS is a linux distribution praised for it's functional-style declarative
-configuration that allows you to manage the entire system through the Nix
-programming language, making your sytem reproducible and more reliable.
-
-This is in contrast to other linux distros that use a more imperative approach
-of managing the system by running commands to install packages, create
-users, etc.
-
-## NixOS as a daily-driver operating system
-
-About half a year ago I started using Windows subsystem for linux which enabled
-me to run a linux distro in the terminal, 6 weeks ago I finally decided to make
-the jump and switch from windows to a full linux desktop experience.
-
-I wanted a linux distro with a large set of latest-version packages but still
-stable without risk of getting my system broken (sorry Arch).
-
-I was considering going with Tumbleweed, a rolling release distro
-by openSUSE which I was already familiar with because I was using it in WSL.
-
-But then I remembered Nix, this weird thing that is an operating system,
-programming language, and a package manager.
-
-Nixpkgs is the the package repository with the most fresh packages (even more than AUR),
-and it has a really cool benefit of being able to install all my packages
-through a config file, similar to NVIM with lazy.nvim or rust with cargo.
-
-Initially I was considering using something like Debian with nixpkgs as I heard
-that was possible, but some people warned me that it's a bad idea to not use
-the native package manager, so I ended up **going with NixOS as my first linux
-distro on desktop**.
-
-I followed a [great video about installing NixOS](https://www.youtube.com/watch?v=a67Sv4Mbxmc) by Vimjoyer
-and was able to get it up and running.
-Although I experienced some issues in the first few days, that was expected
-and I was able to solve all of them.
-
-One trap to be aware of is the nix community is sometimes too enthusiastic and
-will try to convince you to do things "the nix way" like rewriting your
-perfectly fine existing configs in nix or moving from stow to home manager.
-
-In my opinion, I don't want to waste so much time configuring everything,
-I am OK with only configuring system settings and packages while having things
-like other dotfiles or scripts be handled the "normal linux way".
-
-## NixOS as a production server distro
-
-A few days ago I got my first VPS, a RS 1000 from netcup (use code
-`36nc17355743780` for a $5 discount),
-my goal with it was to host my website along with some other self-hosted apps
-including my own server for a terminal-based social media I am working on
-(which I will make a blog post about in the future).
-
-Infrastructure as code (IaC) is the practice of managing servers through
-configuration files rather than manual instructions (such as running commands),
-this has several benefits such as being able to use version control and ensuring
-a more reproducible server that can be easily deployed and updated using these
-files.
-
-This is where NixOS comes in and really shines, all these "nix ways" of
-configuring stuff as a desktop OS seems overkill and time consuming but for a
-server that's exactly the point, to be able to reproduce the entire system
-from only a bunch of nix files.
-
-## Configuring a server with NixOS
-
-After struggling to install NixOS, I discovered [NixOS Anywhere](https://github.com/nix-community/nixos-anywhere)
-which made it very easy to install remotely through SSH.
-
-First thing was setting up proper SSH authentication and security.
-
-Nix makes it really simple to do, just add these 2 lines to enable ssh
-but disable the insecure password authentication
-
-```nix
-services.openssh.enable = true;
-services.openssh.settings.PasswordAuthentication = false;
-```
-
-And to add a public key to connect with to the root user
-
-```nix
-users.users.root.openssh.authorizedKeys.keys = [
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7P9K9D5RkBk+JCRRS6AtHuTAc6cRpXfRfRMg/Kyren"
-];
-```
-
-If you would like to know how I generated a key that ends with `/Kyren` read
-my first blog post - [The search for the perfect ssh key](http://localhost:4321/blogs/the-search-for-the-perfect-ssh-key)
-
-### Managing secrets with sops-nix
-
-Next, before we can get into configuring a webserver, we need a good way
-to store secrets for things like SSL certifications, [sops-nix](https://github.com/Mic92/sops-nix) is a nix module
-that integrates the [sops CLI tool](https://github.com/getsops/sops) into nix.
-
-Rather than having to set up 20 different secrets for each thing, it allows
-us only setup 1 secret that is stored on the server and on the admin's
-system, then, any additional secret can be defined in a file that gets
-encrypted automatically by sops which can safely be committed into version control.
-
-At runtime sops will write all these files to a directory which can then be
-accessed by anything that needs access to that secret, sops also makes it easy
-to let specific users or groups access to a specific secret.
-
-### Setting up automatic updates
-
-We have added sops-nix, but how can we get it into the server?
-
-The simple approach would be to ssh as root into the server, git clone the
-repository with the config and then run
-
-```sh
-nixos-rebuild switch --flake .#default
-```
-
-_assuming you are inside the git directory where your `flake.nix` is and your
-`nixosConfigurations` is called `default`_
-
-While that certainly works, a better approach would be to listen for changes
-to the git repository and automatically pull and rebuild the system.
-
-```nix
-system.autoUpgrade = {
- enable = true;
- flake = "github:kyren223/server#default";
- dates = "minutely"; # Poll interval
- flags = [
- "--no-write-lock-file" # Prevent flake.lock from upgrading
- "--option" "tarball-ttl" "0" # Required for polling below 1h
- ];
-};
-```
-
-This will automatically run every minute to fetch the github repository
-and rebuild the system.
-
-But wait, what if the repository is private? that's where sops-nix comes in!
-
-```nix
-sops.secrets.github-access-token = { };
-nix.extraOptions = "!include /run/secrets/github-access-token";
-```
-
-The first line defines a new `github-access-token` secret, and the second line
-makes sure nix is aware of it so it can use it when trying to fetch the repo.
-
-Of course, make sure to define the secret in your `secrets.yml` file,
-The key would be `gituhb-access-token` and the value would be a github PAT
-token.
-It's recommended to only give the token read-only access to the repo's contents.
-
-## Serving a static website
-
-Now that we have a way to manage our secrets, and continious deployment of our
-nix configuration, we can finally start working on a website.
-
-The plan is to host multiple websites in the future so I'll be using [Nginx](https://nginx.org/en/)
-as a reverse proxy.
-
-```nix
-services.nginx.enable = true;
-services.nginx.virtualHosts."kyren.codes" = {
- useACMEHost = "kyren.codes";
- forceSSL = true;
- locations."/" = {
- index = "index.html";
- root = "/srv/website";
- };
-};
-```
-
-This enables nginx, which installs it on our system then defines a new virtual
-host with the domain `kyren.codes`, later if we were to host other sites, the
-virtualHost can be something like `git.kyren.codes`.
-
-The `locations."/"` sets the base url of our website to `/srv/website` which is
-where I have my website's static files, and nginx will serve `index.html` as
-the default page when you go to that domain, later I will explain how to setup
-continious deployment to automatically update this directory on push to master.
-
-The `useACMEHost` and `forceSSL` makes sure the server uses https, you'd need
-to get a SSL certificate from [Let's Encrypt](https://letsencrypt.org/), once
-again, Nix makes it really simple to do
-
-```nix
-# Define the token using nix, make sure the "acme" user can access it
-sops.secrets.cloudflare-dns-api-token = { mode = "0440"; owner = "acme"; };
-
-security.acme.acceptTerms = true;
-security.acme.defaults.email = "acme@kyren.codes"; # Your email
-
-security.acme.certs."kyren.codes" = {
- domain = "kyren.codes";
- extraDomainNames = [ "*.kyren.codes" ];
- dnsProvider = "cloudflare";
- environmentFile = "${pkgs.writeText "cf-creds" ''
- CF_DNS_API_TOKEN_FILE=${config.sops.secrets.cloudflare-dns-api-token.path}
- ''}";
- webroot = null;
-};
-
-# Allow nginx to access acme certs
-users.users.nginx.extraGroups = [ "acme" ];
-```
-
-This defines a `kyren.codes` entry (which is what `useACMEHost` references)
-I am using cloudflare as my DNS provider, but you can get a full list of
-supported DNS providers at [this link](https://go-acme.github.io/lego/dns/), and
-of course make sure to change the environment variables to match your provider.
-
-Now if we commit and push these changes and wait about a minute for the server
-to pull the changes, we should have a working static site at `kyren.codes`.
-
-### Setting up continious deployment for the website
-
-The way we are going to do this on the server is create a new linux user and
-add to it a public ssh key that will be used for deployments.
-
-It's recommended that the user is restricted as much as possible so in the case
-of a hacker getting access to the key, they won't be able to get into other
-services that are running on the server.
-
-We can create a user declaratively like this
-
-```nix
-users.users.website = {
- isNormalUser = true;
- group = "users";
- openssh.authorizedKeys.keys = [
- # Allow an admin to manually SSH
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7P9K9D5RkBk+JCRRS6AtHuTAc6cRpXfRfRMg/Kyren"
-
- # The deployment public key
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ1B/i/AQLYt6mrz0P/oUJItpvWXp7z0xHNzmcPdtwWd"
- ];
-};
-
-# Make sure the /srv/website always exists
-# Give read and write permissions to the website user
-# Give read permissions to the nginx group (so nginx can serve it)
-systemd.tmpfiles.rules = [
- "d /srv/website 0750 website nginx"
-];
-```
-
-Now all you need to do is have a github action (or similar) that builds your
-website then copies the build output into the server by SSH-ing into it.
-You can take a look at [my github action](https://github.com/Kyren223/website/blob/master/.github/workflows/deploy.yml)
-for my website to see an example of how you can do it.
-
-## Conclusions
-
-NixOS helps system admins and developers achieve infrastructure as code by
-allowing them to declare the entire machine's configuration using the powerful
-Nix programming language.
-
-This makes the state of production machines more consistent and reliable while
-making it easy to reproduce across hundreds of machines.
-
-Compared with the traditional approach of a debian or ubuntu server, where
-system admins would have to painfully manage the state of all machines ensuring
-all the dependencies, firewalls, OS settings, etc are configured properly.
-
-Because of the difficulty, OCI containers such as docker became popular, but
-they come with a cost, mainly performane due to virtualization. NixOS makes it
-easy to configure programs to run on bare-metal making it a better, more
-performant alternative to docker.
-
-**Thanks for reading! wishing you a year full of code, growth and new oppurtunities!**
-
-If you'd like to learn more about NixOS, here are some resources I found useful:
-
-- [NixOS in production](https://github.com/Gabriella439/nixos-in-production)
-- [Vimjoyer's Youtube Channel](https://www.youtube.com/@vimjoyer/videos)
-
-Have questions or just want to chat? feel free to contact me on discord at
-Kyren223 or email me at `contact at kyren.codes`.