249 lines
6.4 KiB
Markdown
249 lines
6.4 KiB
Markdown
|
---
|
||
|
#title: Getting started with remote deployment on NixOs
|
||
|
title: Remote deployments on NixOs
|
||
|
description: A quick and dirty guide to get started with building systems to remote instances
|
||
|
date: 2024-05-04 00:00:00+0000
|
||
|
image: taylor-vick-M5tzZtFCOfs-unsplash.jpg
|
||
|
categories:
|
||
|
- Nix
|
||
|
- Guide
|
||
|
- Sysadmin
|
||
|
|
||
|
tags:
|
||
|
- Nix
|
||
|
- NixOs
|
||
|
- Server Management
|
||
|
|
||
|
draft: false
|
||
|
---
|
||
|
|
||
|
With the capabilities of Nix & Nixos, we can tailor-make services on our local computer,
|
||
|
build the system, and then transmit it to a remote server using the `--target-host` argument for `nixos-rebuild`
|
||
|
command. This is an efficient method of deploying services to distant servers because you
|
||
|
don't have to connect to the machine via SSH and set up the files locally before building
|
||
|
them there.
|
||
|
|
||
|
## How remote deployments work
|
||
|
|
||
|
![](diagram1.svg)
|
||
|
|
||
|
NixOS allows for a seamless build process, where you can create the system on your local computer and then use
|
||
|
SSH to transfer the configuration files to a remote machine where the services are deployed.
|
||
|
This process is easy to manage and streamline. Ez to learn!
|
||
|
|
||
|
## Getting started
|
||
|
|
||
|
First you will need a machine running NixOs. Duh. But also you will need to have root access to it in some way.
|
||
|
If you have the root user and its password then you are set to go and can skip to the section where [I explain how to get ready for remote deployment](#first-boot)
|
||
|
|
||
|
### Setting up NixOs on a server.
|
||
|
|
||
|
#### Installing
|
||
|
|
||
|
I assume if you are reading this article you know how to install an operating system.
|
||
|
|
||
|
You will need to flash an usb drive with NixOs, for the sake of an easy install I will use `latest-nixos-plasma5-x86_64-linux.iso` since It comes with a fearly easy to use Calamares installer.
|
||
|
|
||
|
![Installer](nixosinstaller.png)
|
||
|
You can go ahead and click through it and it will install.
|
||
|
|
||
|
## First boot
|
||
|
|
||
|
For remote deployment to work you will need to enable ssh and configure some parameters for it to work.
|
||
|
We are enabling root login and also sftp for file transfer.
|
||
|
|
||
|
```nix
|
||
|
# configuration.nix
|
||
|
services.openssh = {
|
||
|
enable = true;
|
||
|
allowSFTP = true;
|
||
|
settings = {
|
||
|
PasswordAuthentication = true;
|
||
|
PermitRootLogin = "yes";
|
||
|
};
|
||
|
};
|
||
|
networking.hostName = "server1";
|
||
|
networking.domain = "localhost";
|
||
|
```
|
||
|
|
||
|
**Rebuild the system**
|
||
|
|
||
|
```zsh
|
||
|
sudo nixos-rebuild switch
|
||
|
```
|
||
|
|
||
|
## Setting up key auth
|
||
|
|
||
|
To facilitate easy deployments, you can transfer your public SSH key to the remote machine, allowing you to log
|
||
|
in without having to enter the password for each rebuild. This method is both more convenient and safe
|
||
|
|
||
|
```bash
|
||
|
ssh-copy-id root@server
|
||
|
```
|
||
|
|
||
|
## Create a directory for the remote
|
||
|
|
||
|
On your local machine, it's important to organize your files into a directory, particularly when working with
|
||
|
multiple servers. This is demonstrated below, where I showcase my personal file
|
||
|
organization method.
|
||
|
|
||
|
{{< filetree/container >}}
|
||
|
{{< filetree/folder name="servers" >}}
|
||
|
|
||
|
{{< filetree/folder name="server1" state="closed" >}}
|
||
|
{{< filetree/file name="configuration.nix" >}}
|
||
|
{{< filetree/file name="flake.nix" >}}
|
||
|
{{< filetree/file name="flake.lock" >}}
|
||
|
{{< /filetree/folder >}}
|
||
|
|
||
|
{{< filetree/folder name="server2" state="closed" >}}
|
||
|
{{< filetree/file name="configuration.nix" >}}
|
||
|
{{< filetree/folder name="services" state="closed" >}}
|
||
|
{{< filetree/file name="matrix.nix" >}}
|
||
|
{{< filetree/file name="webserver.nix" >}}
|
||
|
{{< /filetree/folder >}}
|
||
|
{{< filetree/file name="flake.nix" >}}
|
||
|
{{< filetree/file name="flake.lock" >}}
|
||
|
{{< /filetree/folder >}}
|
||
|
{{< /filetree/folder >}}
|
||
|
|
||
|
{{< /filetree/container >}}
|
||
|
|
||
|
## Copying essential files from remote
|
||
|
|
||
|
NixOS does not support partial builds, so you will need to transfer all the necessary files from `/etc/nixos` to
|
||
|
your local machine. This includes files such as `hardware-configuration.nix` and `configuration.nix`.
|
||
|
|
||
|
```bash
|
||
|
scp configuration.nix root@server:/etc/nixos
|
||
|
```
|
||
|
|
||
|
```bash
|
||
|
scp hardware-configuration.nix root@server:/etc/nixos
|
||
|
```
|
||
|
|
||
|
## Create flakes
|
||
|
|
||
|
You can create a file called `flake.nix` or use `nix` to do so.
|
||
|
|
||
|
```bash
|
||
|
nix flake init .
|
||
|
```
|
||
|
|
||
|
Paste the following in the file.
|
||
|
|
||
|
```nix
|
||
|
# flake.nix
|
||
|
{
|
||
|
description = "Server1 deployments";
|
||
|
|
||
|
inputs = {
|
||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||
|
};
|
||
|
|
||
|
outputs =
|
||
|
{ self
|
||
|
, nixpkgs
|
||
|
, ...
|
||
|
}:
|
||
|
let
|
||
|
system = "x86_64-linux";
|
||
|
in
|
||
|
{
|
||
|
nixosConfigurations.server1 = nixpkgs.lib.nixosSystem {
|
||
|
inherit system;
|
||
|
modules = [
|
||
|
./configuration.nix
|
||
|
];
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Here is an example of how your `configuration.nix` should look like.
|
||
|
|
||
|
```nix
|
||
|
# configuration.nix
|
||
|
|
||
|
{ config, pkgs, ... }:
|
||
|
|
||
|
{
|
||
|
imports =
|
||
|
[
|
||
|
./hardware-configuration.nix
|
||
|
];
|
||
|
|
||
|
networking.hostName = "server1";
|
||
|
networking.domain = "example.com";
|
||
|
|
||
|
services.openssh = {
|
||
|
enable = true;
|
||
|
allowSFTP = true;
|
||
|
settings = {
|
||
|
PasswordAuthentication = true;
|
||
|
PermitRootLogin = "yes";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
```
|
||
|
|
||
|
## Set up a service
|
||
|
|
||
|
This little example shows a dummy nginx service.
|
||
|
|
||
|
```nix
|
||
|
# nginx.nix
|
||
|
services.nginx = {
|
||
|
enable = true;
|
||
|
virtualHosts = {
|
||
|
"example.com" = {
|
||
|
locations."/" = {
|
||
|
# ...
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Insert it in the configuration.nix `imports` section.
|
||
|
|
||
|
```nix
|
||
|
imports = [
|
||
|
./hardware-configuration.nix
|
||
|
./nginx.nix
|
||
|
];
|
||
|
```
|
||
|
|
||
|
## Deploy!
|
||
|
|
||
|
After all this we can just go ahead and execute a rebuild like we would do on our local machine. Except in this case we have to add the `--flake` to the rebuild command and also add the hostname we are building for.
|
||
|
|
||
|
```bash
|
||
|
nixos-rebuild switch --flake .#server1 --target-host root@server --show-trace
|
||
|
```
|
||
|
|
||
|
## Service management
|
||
|
|
||
|
Since NixOs uses systemd we can utilize its tools such as `journalctl` or `systemcl` to check up on how our services are doing.
|
||
|
Here are a few commands I recommend using
|
||
|
|
||
|
Prints the last 100 logs of nginx
|
||
|
|
||
|
```bash
|
||
|
journalctl -u nginx.service -n 200
|
||
|
```
|
||
|
|
||
|
Displays the status of the service
|
||
|
|
||
|
```bash
|
||
|
systemctl status nginx.service
|
||
|
```
|
||
|
|
||
|
## Afterthoughts
|
||
|
|
||
|
The first-boot section could be skipped if you [create a custom nixos installation media](https://wiki.nixos.org/wiki/Creating_a_NixOS_live_CD) then flash that to the server. With a custom media you can define ssh to already have these options enabled and also can add your public key.
|
||
|
This is how I've been doing my deployments for the past 1 month for the 4 of my servers. It's much easier than my old-school method of ssh-ing into my alpine machines and manage my deployments with `docker-compose`
|