
Inicie este sitio web por varios motivos. El primero, para tener un espacio profesional en la web con contenido que sea 煤til para otros ingenieros de software y para demostrar a potenciales clientes mi experiencia en el campo. Segundo, como un ejercicio de “reproducibilidad”.
Con “reproducibilidad” me refiero a la capacidad que tiene este sitio web de ser desplegado en cualquier otro lugar y el resultado sea exacto bit por bit al despliegue original. Y no me refiero solo al contenido, sino a toda la pila de tecnolog铆a.
A pesar de mi amplia experiencia con GNU/Linux, no soy un sysadmin y no disfruto mucho realizar ese tipo de tareas por lo que me decantado por NixOS como sistema operativo para el Droplet de Digital Ocean. NixOS no es una distribuci贸n cualquiera de GNU/Linux como Arch o Debian, es una distribuci贸n cuya configuraci贸n se expresa de forma declarativa y permite la “reproducibilidad” a la que alud铆 antes. Por ejemplo, esta fue la forma en la que configur茅 Nginx, Let’s Encrypt y la carpeta donde va el contenido est谩tico:
{
config,
...
}:
{
# ...c贸digo omitido por motivos de brevedad...
systemd.tmpfiles.rules = [
"d /var/www/jorgearaya.dev 0755 nginx nginx -"
];
security.acme = {
acceptTerms = true;
defaults.email = "jorge+dns@esavara.cr";
certs."jorgearaya.dev" = {
dnsProvider = "digitalocean";
environmentFile = config.sops.templates."acme.conf".path;
webroot = null;
};
};
services.nginx = {
enable = true;
commonHttpConfig = ''
map $http_accept_language $preferred_lang {
default en;
~^es es;
~^en en;
}
'';
virtualHosts."jorgearaya.dev" = {
enableACME = true;
forceSSL = true;
root = "/var/www/jorgearaya.dev";
extraConfig = ''
charset utf-8;
error_page 404 = @localized_404;
'';
locations."/" = {
tryFiles = "$uri $uri/ =404";
extraConfig = ''
if ($request_uri = "/") {
return 302 /$preferred_lang/;
}
'';
};
# dynamic 404
locations."@localized_404" = {
extraConfig = ''
if ($uri ~* "^/([a-z]{2})/") {
set $lang $1;
}
if ($lang = "") {
set $lang $preferred_lang;
}
rewrite ^ /$lang/404.html break;
'';
};
};
};
}
Let’s Encrypt y Nginx son expuestos en NixOS como m贸dulos en security.acme
y services.nginx
respectivamente. Algunas propiedades de la configuraci贸n de estos servicios son ofrecidos por los m贸dulos como un set de atributos, algunos atributos como services.nginx.virtualHosts.<sitio>.extraConfig
sirve para definir configuraci贸n adicional que no es ofrecida en el set de atributos del modulo.
Con la configuraci贸n del Droplet declarada es cuesti贸n de utilizar nix run github:serokell/deploy-rs .#
para realizar su despliegue en una nueva generaci贸n. Si algo ha salido mal durante el despliegue (por ejemplo, un error en la configuraci贸n de Nginx que hace fallar la inicializaci贸n del servicio de systemd) el NixOS del Droplet simplemente retornar谩 a la generaci贸n anterior y seguir谩 funcionando como si nada.
Para guardar la llave API del servicio Digital Ocean para el “DNS Challenge” de Let’s Encrypt utilizo sops-nix
, un modulo de NixOS que utiliza sops
para el aprovisionamiento de secretos. El secreto para el “DNS Challenge” esta cifrado y registrado en el repositorio junto con la configuraci贸n del servidor, solamente las llaves publicas age
registradas en la configuraci贸n de sops
pueden descifrar el secreto y hacer uso de 茅l. 隆Todo viene en un mismo envase por lo que es muy practico!
Si quiero mantener mi sistema actualizado a la ultima versi贸n estable del repositorio de software de NixOS todo lo que debo hacer es refrescar las entradas (inputs) con nix flake update
y desplegar la misma configuraci贸n con deploy-rs
. Tener que utilizar solo 2 comandos es muy conveniente para el mantenimiento del servidor.
En el blog espero escribir m谩s sobre Nix y NixOS, para que varios de los t茅rminos que utilic茅 en la descripci贸n del proyecto tengan m谩s sentido para el amigo lector.