~afontaine/home

66d61cff9839b42edec221968505b47358168fea — Andrew Fontaine 6 months ago ca23de5
First pass at a NixOS Module for Deployment

It should be secret friendly. Does not currently set up databases, etc.,
but should start and stop the service at least!
2 files changed, 78 insertions(+), 7 deletions(-)

M config/releases.exs
M flake.nix
M config/releases.exs => config/releases.exs +12 -6
@@ 4,20 4,26 @@
# remember to add this file to your .gitignore.
import Config

database_url =
  System.get_env("DATABASE_URL") ||
database_socket =
  System.get_env("DATABASE_SOCKET_DIR") ||
    raise """
    environment variable DATABASE_URL is missing.
    For example: ecto://USER:PASS@HOST/DATABASE
    environment variable DATABASE_SOCKET_DIR is missing.
    """

database_name =
  System.get_env("DATABASE_NAME") ||
    raise """
    environment variable DATABASE_NAME is missing.
    """

config :blog, Blog.Repo,
  # ssl: true,
  url: database_url,
  socket_dir: database_socket,
  database: database_name,
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")

secret_key_base =
  System.get_env("SECRET_KEY_BASE") ||
    String.trim(File.read!(System.get_env("SECRET_KEY_BASE_FILE"))) ||
    raise """
    environment variable SECRET_KEY_BASE is missing.
    You can generate one by calling: mix phx.gen.secret

M flake.nix => flake.nix +66 -1
@@ 89,7 89,6 @@
            mixDeps = self.packages.${system}.home-elixir-deps;
            preConfigure = ''
              export NODE_ENV=production
              # export TAILWIND_TOUCH_DIR="$TEMPDIR/.tailwindcss/touch"
              export TAILWIND_DISABLE_TOUCH=true
            '';
            preBuild = ''


@@ 102,5 101,71 @@
            '';
          };
        };
        nixosModule = { config, lib, pkgs, ... }:
          let cfg = config.services.home-web;
          in {
            options = {
              services.home-web = {
                enable = lib.mkEnableOption "home-web";
                port = lib.mkOption {
                  type = lib.types.int;
                  default = 4000;
                  description = "Port to listen on, 4000 by default";
                };
                poolSize = lib.mkOption {
                  type = lib.types.int;
                  default = 10;
                  description = "Connection pool size, 10 by default";
                };
                secretKeyBaseFile = lib.mkOption {
                  type = lib.types.path;
                  description =
                    "A file contianing the Phoenix Secret Key Base. This should be secret, and not kept in the nix store";
                };
                dataDir = lib.mkOption {
                  type = lib.types.path;
                  defaultText = "/var/lib/home-web";
                  description = "The directory to write data to";
                };
                databaseName = lib.mkOption {
                  type = lib.types.str;
                  default = "blog_prod";
                  description = "The name of the database to use";
                };
                databaseSocketDir = lib.mkOption {
                  type = lib.types.path;
                  defaultText = "/var/run/postgres";
                  description =
                    "The directory containing the postgres socket to connect with";
                };
              };
            };
            config = lib.mkIf cfg.enable {
              users.extraUsers.home-web = {
                isSystemUser = true;
                group = "home-web";
                home = cfg.dataDir;
                createhome = true;
              };

              systemd.services.home-web = {
                description = "Home, home on the web";
                wantedBy = [ "multi-user.target" ];
                after = [ "network.target" ];
                script = ''
                  ${self.packages.${system}.home}/bin/home start
                '';
                environment = {
                  RELEASE_TMP = cfg.dataDir;
                  TZ_DATA_DIR = cfg.dataDir;
                  POOL_SIZE = cfg.poolSize;
                  SECRET_KEY_BASE_FILE = cfg.secretKeyBaseFile;
                  PORT = cfg.port;
                  DATABASE_NAME = cfg.databaseName;
                  DATABASE_SOCKET_DIR = cfg.databaseSocketDir;
                };
              };
            };
          };
      });
}