Featured image of post Nix flakes for Hugo site

Nix flakes for Hugo site

How to use nix to build and deploy hugo-based website

Advantages of managing Hugo website with Nix.

  • Reproducible builds: Nix allows you to reproducible build your Hugo website across multiple machines.
  • Dependency management: Nix makes it easy to manage theme, other dependencies and even Hugo itself for your website.
  • Easy deployment: just set root of your nginx virtualHost to site’s package.

Setup your site.

Write flake.nix.

This is an example of flake.nix I use for this blog, adapt it for your needs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
  description = "AveryanAlex's personal blog";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";

    # Import theme
    stack = {
      url = github:CaiJimmy/hugo-theme-stack;
      flake = false;
    };
  };

  outputs = { self, nixpkgs, flake-utils, stack }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};

        blog = pkgs.stdenv.mkDerivation {
          name = "blog";
          # Exclude themes and public folder from build sources
          src = builtins.filterSource
            (path: type: !(type == "directory" &&
              (baseNameOf path == "themes" ||
                baseNameOf path == "public")))
            ./.;
          # Link theme to themes folder and build
          buildPhase = ''
            mkdir -p themes
            ln -s ${stack} themes/stack
            ${pkgs.hugo}/bin/hugo --minify
          '';
          installPhase = ''
            cp -r public $out
          '';
          meta = with pkgs.lib; {
            description = "AveryanAlex's personal blog";
            platforms = platforms.all;
          };
        };
      in
      {
        packages = {
          blog = blog;
          default = blog;
        };

        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [ hugo ];
          # Link theme to themes folder
          shellHook = ''
            mkdir -p themes
            ln -sf ${stack} themes/stack
          '';
        };
      });
}

Setup direnv.

1
2
3
echo use flake >> .envrc
echo .direnv >> .gitignore
direnv allow

Add result to .gitignore.

Result folder is a symlink to built website created by nix build command.

1
echo result >> .gitignore

Preview and build.

Run development server:

1
hugo server -D

Build production release with nix:

1
nix build

Deploying to nginx webserver.

Now we will create nginx virtualHost config for the site.

Add website to server’s flake inputs:

1
2
3
{
  inputs.blog.url = "github:averyanalex/blog";
}

Setup nginx virtualHost to serve your site:

1
2
3
4
5
6
7
8
9
{ inputs, pkgs, ... }:

{
  services.nginx.virtualHosts."averyan.ru" = {
    root = inputs.blog.defaultPackage.${pkgs.hostPlatform.system};
    useACMEHost = "averyan.ru";
    forceSSL = true;
  };
}
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy