--- title: Simple nixos config for vps static site date: 2023-01-29 tags: - nixos draft: false --- Setting up a little static site is something I've done a few different times on a few different operating systems. It's a slightly fiddly task with a few disparate jobs that all need looking after: ssh, let's encrypt, nginx. In my opinion, it is one of the moments where consolidating all the little bits and bobs you need to setup into one common configuration is very useful. I'm going to go through a bit of the nixos config I've got for my vps. ### SSH Having a way to to get into your server is useful. Managing ssh on nix is very simple; this enables the ssh daemon, tells it what port to run on, disables plain text passwords, and disables root login. ```nix services.openssh = { enable = true; ports = [ 69 ]; settings = { passwordAuthentication = false; permitRootLogin = "no"; }; }; ``` ### ADDING A USER Generally, it's nice to have a user so you're not just rawdogging everything as root. This adds a user called ronald, sets their default shell, and adds them to some useful groups. You can even add your public ssh keys here for ultimate convenience. ```nix users.users = { ronald = { isNormalUser = true; shell = pkgs.fish; extraGroups = [ "wheel" "nginx" ]; openssh.authorizedKeys.keyFiles = [ "/path/to/public/key/file" ] }; }; ``` ### NGINX I use nginx to serve my sites. Compared to the nginx config I used to mess around with, the equivalent nix config is very clean. This chunk tells nginx to serve the contents of `/var/www/example-site` at `example-site.here`. It also opens the ports for http and https in the firewall. ```nix services.nginx = { enable = true; virtualHosts."example-site.here" = { enableACME = true; forceSSL = true; root = "/var/www/example-site/"; }; }; networking.firewall.allowedTCPPorts = [ 80 443 ]; ``` ### HTTPS You can also make nix deal with all the let's encrypt certbot stuff. It looks like this: ```nix security.acme = { acceptTerms = true; defaults.email = "ronald@email.yes"; }; ``` This will set up certificates for any sites you set the `enableAMCE` to true option for. ### CRON This is one final little tidbit I set up the other day. I had got bored of having to ssh into my server to manually copy my updated site to the website root. The problem was I would need root privileges on the server to rsync the files to the website root. This seemed like a whole minefield I didn't want to mess with. Instead I set up a little cron job which copies a directory from my home to the website root every hour. ```nix services.cron = { enable = true; systemCronJobs = [ "@hourly root cp -r /home/ronald/example-site /var/www/" ]; }; ``` This means I can just rsync the updated site from my laptop to the server and it'll be updated within the hour. Good enough for me.