From d1c2735ba8fc71b462ccc6a5126a635fc577665e Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Sat, 5 Aug 2023 14:18:39 +0200 Subject: [PATCH 1/6] Fixed indentation --- flake.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 5e2828657..ede5a703e 100644 --- a/flake.nix +++ b/flake.nix @@ -31,11 +31,11 @@ flake = { flakeModules.default = flake-parts-lib.importApply ./flake-module.nix { inherit inputs; }; templates.default = { - path = inputs.ihp-boilerplate; - description = "Template for an IHP project"; - welcomeText = '' - TODO this is shown when running nix init, could contain instruction to get started - ''; + path = inputs.ihp-boilerplate; + description = "Template for an IHP project"; + welcomeText = '' + TODO this is shown when running nix init, could contain instruction to get started + ''; }; }; } From de4d55776a89e246c5a2257bc6588611d42207a6 Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Sat, 5 Aug 2023 18:21:10 +0200 Subject: [PATCH 2/6] Added deploy-to-nixos command Added nix flake based deployment --- Guide/deployment.markdown | 66 +++++++++++++++ NixSupport/nixosModules/app.nix | 25 ++++++ NixSupport/nixosModules/appWithPostgres.nix | 84 ++++++++++++++++++++ NixSupport/nixosModules/options.nix | 69 ++++++++++++++++ NixSupport/nixosModules/services/app.nix | 29 +++++++ NixSupport/nixosModules/services/migrate.nix | 27 +++++++ NixSupport/nixosModules/services/worker.nix | 28 +++++++ flake-module.nix | 7 ++ flake.nix | 9 +++ 9 files changed, 344 insertions(+) create mode 100644 NixSupport/nixosModules/app.nix create mode 100644 NixSupport/nixosModules/appWithPostgres.nix create mode 100644 NixSupport/nixosModules/options.nix create mode 100644 NixSupport/nixosModules/services/app.nix create mode 100644 NixSupport/nixosModules/services/migrate.nix create mode 100644 NixSupport/nixosModules/services/worker.nix diff --git a/Guide/deployment.markdown b/Guide/deployment.markdown index 7bb6c37be..15b2b9ddc 100644 --- a/Guide/deployment.markdown +++ b/Guide/deployment.markdown @@ -4,6 +4,72 @@ ``` +## Deploying with `deploy-to-nixos` + +IHP comes with a standard command called `deploy-to-nixos`. This tool is a little wrapper around `nixos-rebuild` and allows you to deploy IHP apps to a NixOS server. With `deploy-to-nixos` you can manage your servers in a fully declarative way and keep the full configuration in your git repository. + +AWS EC2 is a good choice for deploying IHP in a professional setup. + +### Creating a new EC2 Instance + +Start a new EC2 instance and use the official NixOS AMI `NixOS-23.05.426.afc48694f2a-x86_64-linux`. You can find the latest NixOS AMI at https://nixos.org/download#nixos-amazon + +Make sure to attach SSH keys to the instance at creation time. + +### Connecting to the EC2 Instance + +After you've created the instance, configure your local SSH settings to point to the instance. + +In your `~/.ssh/config` you typically add something like this: + +``` +Host ihp-app + HostName ec2-.....compute.amazonaws.com + User root + IdentityFile /Users/marc/.ssh/ihp-app.pem +``` + +Now you can connect to the instance using `ssh ihp-app`. + +### Configuring the Instance + +In your `flake.nix` add the following configuration: + +```nix +flake.nixosConfigurations."ihp-app" = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + specialArgs = inputs; + modules = [ + "${nixpkgs}/nixos/modules/virtualisation/amazon-image.nix" + ihp.nixosModules.appWithPostgres + ({ ... }: { + security.acme.defaults.email = "me@example.com"; + + services.ihp = { + domain = "myihpapp.com"; + migrations = ./Application/Migration; + schema = ./Application/Schema.sql; + fixtures = ./Application/Fixtures.sql; + sessionSecret = "xxx"; + }; + }) + ]; +}; +``` + +In the first line the `"ihp-app"` needs to be the same as your SSH name from the previous section. + + +### Deploying the App + +Now you can deploy the app using `deploy-to-nixos` (which is just a small wrapper around nixos-rebuild): + +```bash +deploy-to-nixos ihp-app +``` + +This will connect to the server via SSH and apply the NixOS configuration to the server. + ## Deploying with Shipnix Shipnix is a service for deploying NixOS web servers on DigitalOcean with first-class support for IHP. diff --git a/NixSupport/nixosModules/app.nix b/NixSupport/nixosModules/app.nix new file mode 100644 index 000000000..8610f0252 --- /dev/null +++ b/NixSupport/nixosModules/app.nix @@ -0,0 +1,25 @@ +# Running an IHP web server + Worker +{ config, pkgs, modulesPath, lib, ihp, ihpApp, ... }: +let cfg = config.services.ihp; +in +{ + imports = [ + ihp.nixosModules.options + ihp.nixosModules.services_app + ihp.nixosModules.services_worker + ihp.nixosModules.services_migrate + ]; + + # Speed up builds with the IHP binary cache + nix.settings.substituters = [ "https://digitallyinduced.cachix.org" ]; + nix.settings.trusted-public-keys = [ "digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE=" ]; + + # Add swap to avoid running out of memory during builds + swapDevices = [ { device = "/swapfile"; size = 8192; } ]; + + # Pin the nixpkgs to the IHP nixpkgs + nix.registry.nixpkgs.flake = nixpkgs; + + system.stateVersion = "23.05"; +} + diff --git a/NixSupport/nixosModules/appWithPostgres.nix b/NixSupport/nixosModules/appWithPostgres.nix new file mode 100644 index 000000000..ac34b756c --- /dev/null +++ b/NixSupport/nixosModules/appWithPostgres.nix @@ -0,0 +1,84 @@ +# Running IHP app + a local Postgres connected to it +{ config, pkgs, modulesPath, lib, ihp, ihpApp, ... }: +let cfg = config.services.ihp; +in +{ + imports = [ + ihp.nixosModules.options + ihp.nixosModules.services_app + ihp.nixosModules.services_worker + ihp.nixosModules.services_migrate + ]; + + # Speed up builds with the IHP binary cache + nix.settings.substituters = [ "https://digitallyinduced.cachix.org" ]; + nix.settings.trusted-public-keys = [ "digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE=" ]; + + # Add swap to avoid running out of memory during builds + swapDevices = [ { device = "/swapfile"; size = 8192; } ]; + + # Vim and psql commands are helpful when accessing the server + environment.systemPackages = with pkgs; [ vim postgresql ]; + programs.vim.defaultEditor = true; + + system.stateVersion = "23.05"; + + # Allow public access + networking.firewall.enable = true; + networking.firewall.allowedTCPPorts = [ 80 22 ]; + + # Enable Letsencrypt + # TODO security.acme.defaults.email = email; + security.acme.acceptTerms = true; + + # Add a loadbalancer + services.nginx = { + enable = true; + enableReload = true; + recommendedProxySettings = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + }; + + # Setup the domain + services.nginx.virtualHosts = { + "${cfg.domain}" = { + serverAliases = [ ]; + enableACME = cfg.httpsEnabled; + forceSSL = cfg.httpsEnabled; + locations = { + "/" = { + proxyPass = "http://localhost:8000"; + proxyWebsockets = true; + extraConfig = + # required when the target is also TLS server with multiple hosts + "proxy_ssl_server_name on;" + + # required when the server wants to use HTTP Authentication + "proxy_pass_header Authorization;"; + }; + }; + }; + }; + + # Postgres + services.postgresql = { + enable = true; + ensureDatabases = [ cfg.databaseName ]; + ensureUsers = [ + { + name = cfg.databaseUser; + ensurePermissions = { + "DATABASE ${cfg.databaseName}" = "ALL PRIVILEGES"; + }; + } + ]; + initialScript = pkgs.writeText "ihp-initScript" '' + CREATE TABLE IF NOT EXISTS schema_migrations (revision BIGINT NOT NULL UNIQUE); + \i ${ihp}/lib/IHP/IHPSchema.sql + \i ${cfg.schema} + \i ${cfg.fixtures} + ''; + }; +} + diff --git a/NixSupport/nixosModules/options.nix b/NixSupport/nixosModules/options.nix new file mode 100644 index 000000000..7e3a7e40c --- /dev/null +++ b/NixSupport/nixosModules/options.nix @@ -0,0 +1,69 @@ +# Running IHP app + a local Postgres connected to it +{ config, pkgs, modulesPath, lib, ihpApp, ... }: +{ + options.services.ihp = { + enable = mkEnableOption "IHP"; + domain = mkOption { + type = types.str; + default = "localhost"; + }; + + migrations = mkOption { + type = types.path; + }; + + schema = mkOption { + type = types.path; + }; + + fixtures = mkOption { + type = types.path; + }; + + httpsEnabled = mkOption { + type = types.boolean; + default = true; + }; + + databaseName = mkOption { + type = types.str; + default = "app"; + }; + + databaseUser = mkOption { + type = types.str; + default = "ihp"; + }; + + # https://ihp.digitallyinduced.com/Guide/database-migrations.html#skipping-old-migrations + minimumRevision = mkOption { + type = types.int; + default = 0; + }; + + ihpEnv = mkOption { + type = types.str; + default = "Production"; + }; + + appPort = mkOption { + type = types.int; + default = 8000; + }; + + requestLoggerIPAddrSource = mkOption { + type = types.str; + default = "FromHeader"; + }; + + sessionSecret = mkOption { + type = types.str; + }; + + addionalEnvVars = mkOption { + type = types.attrs; + default = {}; + }; + }; +} + diff --git a/NixSupport/nixosModules/services/app.nix b/NixSupport/nixosModules/services/app.nix new file mode 100644 index 000000000..dc7cb8019 --- /dev/null +++ b/NixSupport/nixosModules/services/app.nix @@ -0,0 +1,29 @@ +{ config, pkgs, modulesPath, lib, ihpApp, migrate, migrations, ... }: +let cfg = config.services.ihp; +in +{ + systemd.services.app = { + description = "IHP App"; + enable = true; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + Restart = "always"; + WorkingDirectory = "${ihpApp}/lib"; + ExecStart = "${ihpApp}/bin/RunProdServer"; + }; + environment = + let + defaultEnv = { + PORT = cfg.appPort; + IHP_ENV = cfg.ihpEnv; + IHP_BASEURL = cfg.baseUrl; + IHP_REQUEST_LOGGER_IP_ADDR_SOURCE = cfg.requestLoggerIPAddrSource; + DATABASE_RUL = cfg.databaseUrl; + IHP_SESSION_SECRET = cfg.sessionSecret; + }; + in + defaultEnv // cfg.additionalEnvVars; + }; +} \ No newline at end of file diff --git a/NixSupport/nixosModules/services/migrate.nix b/NixSupport/nixosModules/services/migrate.nix new file mode 100644 index 000000000..3156cb677 --- /dev/null +++ b/NixSupport/nixosModules/services/migrate.nix @@ -0,0 +1,27 @@ +{ config, pkgs, ... }: +let cfg = config.services.ihp; +in +{ + systemd.services.migrate = + let migrateApp = pkgs.stdenv.mkDerivation { + name = "migrate-app"; + src = cfg.migrations; + buildPhase = '' + mkdir -p $out/Application/Migration + cp $src/* $out/Application/Migration + ''; + }; + in { + serviceConfig = { + Type = "oneshot"; + }; + script = '' + cd ${migrateApp} + ${self.packages.x86_64-linux.migrate}/bin/migrate + ''; + environment = { + DATABASE_URL = cfg.databaseUrl; + MINIMUM_REVISION = "${cfg.minimumRevision}"; + }; + }; +} \ No newline at end of file diff --git a/NixSupport/nixosModules/services/worker.nix b/NixSupport/nixosModules/services/worker.nix new file mode 100644 index 000000000..a704ae757 --- /dev/null +++ b/NixSupport/nixosModules/services/worker.nix @@ -0,0 +1,28 @@ +{ config, pkgs, modulesPath, lib, ihpApp, migrate, migrations, ... }: +let cfg = config.services.ihp; +in +{ + systemd.services.worker = { + enable = true; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + Restart = "always"; + WorkingDirectory = "${ihpApp}/lib"; + ExecStart = "${ihpApp}/bin/RunJobs"; + }; + environment = + let + defaultEnv = { + PORT = cfg.port; + IHP_ENV = cfg.ihpEnv; + IHP_BASEURL = cfg.baseUrl; + IHP_REQUEST_LOGGER_IP_ADDR_SOURCE = cfg.requestLoggerIPAddrSource; + DATABASE_RUL = cfg.databaseUrl; + IHP_SESSION_SECRET = cfg.sessionSecret; + }; + in + defaultEnv // cfg.additionalEnvVars; + }; +} \ No newline at end of file diff --git a/flake-module.nix b/flake-module.nix index 3ba77abcd..9e2333419 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -192,6 +192,13 @@ ihpFlake: env.IHP_LIB = "${ihp}/lib/IHP"; env.IHP = "${ihp}/lib/IHP"; # Used in the Makefile + + scripts.deploy-to-nixos.exec = '' + echo "usage: deploy-to-nixos " + echo "example: deploy-to-nixos stagging.example.com" + nix shell nixpkgs#nixos-rebuild --command bash -c "nixos-rebuild switch -j auto --use-substitutes --fast --flake .#$1 --target-host $1 --build-host $1 --option substituters https://digitallyinduced.cachix.org --option trusted-public-keys digitallyinduced.cachix.org:digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE=" + # ssh ihp-deploy-test systemctl start migrate + ''; }; }; diff --git a/flake.nix b/flake.nix index ede5a703e..6da538a52 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,15 @@ TODO this is shown when running nix init, could contain instruction to get started ''; }; + nixosModules = { + app = ./NixSupport/nixosModules/app.nix; + appWithPostgres = ./NixSupport/nixosModules/appWithPostgres.nix; + + services_app = ./NixSupport/nixosModules/services/app.nix; + services_worker = ./NixSupport/nixosModules/services/worker.nix; + services_migrate = ./NixSupport/nixosModules/services/migrate.nix; + options = ./NixSupport/nixosModules/options.nix; + }; }; } ); From d4a77c6dacb65bf0ca45489231dd42dc2a06948d Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Sat, 5 Aug 2023 23:10:12 +0200 Subject: [PATCH 3/6] Fixed many runtime errors --- NixSupport/mkGhcCompiler.nix | 3 +- NixSupport/nixosModules/app.nix | 2 +- NixSupport/nixosModules/appWithPostgres.nix | 4 +- NixSupport/nixosModules/options.nix | 16 +- NixSupport/nixosModules/services/app.nix | 7 +- NixSupport/nixosModules/services/migrate.nix | 24 +- NixSupport/nixosModules/services/worker.nix | 7 +- devenv-module.nix | 24 +- flake-module.nix | 6 +- flake.lock | 352 ++++++++++++++++++- flake.nix | 6 +- ihp.nix | 3 +- 12 files changed, 411 insertions(+), 43 deletions(-) diff --git a/NixSupport/mkGhcCompiler.nix b/NixSupport/mkGhcCompiler.nix index aec43013c..fd73940af 100644 --- a/NixSupport/mkGhcCompiler.nix +++ b/NixSupport/mkGhcCompiler.nix @@ -6,6 +6,7 @@ , dontHaddockPackages ? [] , manualOverrides ? _: _: { } , haskellPackagesDir ? ./haskell-packages +, filter , ... }: let @@ -20,7 +21,7 @@ let }; makePackageSet = dir: pkgs.lib.mapAttrs' (toPackage dir) (builtins.readDir dir); in { - "ihp" = ((haskellPackagesNew.callPackage "${toString ihp}/ihp.nix") { }); + "ihp" = ((haskellPackagesNew.callPackage "${toString ihp}/ihp.nix") { inherit filter; }); } // (makePackageSet haskellPackagesDir) // (makePackageSet "${ihp}/NixSupport/haskell-packages/."); makeOverrides = diff --git a/NixSupport/nixosModules/app.nix b/NixSupport/nixosModules/app.nix index 8610f0252..ec3091ec2 100644 --- a/NixSupport/nixosModules/app.nix +++ b/NixSupport/nixosModules/app.nix @@ -1,5 +1,5 @@ # Running an IHP web server + Worker -{ config, pkgs, modulesPath, lib, ihp, ihpApp, ... }: +{ config, pkgs, modulesPath, lib, ihp, ... }: let cfg = config.services.ihp; in { diff --git a/NixSupport/nixosModules/appWithPostgres.nix b/NixSupport/nixosModules/appWithPostgres.nix index ac34b756c..eb39fdef1 100644 --- a/NixSupport/nixosModules/appWithPostgres.nix +++ b/NixSupport/nixosModules/appWithPostgres.nix @@ -1,5 +1,5 @@ # Running IHP app + a local Postgres connected to it -{ config, pkgs, modulesPath, lib, ihp, ihpApp, ... }: +{ config, pkgs, modulesPath, lib, ihp, ... }: let cfg = config.services.ihp; in { @@ -80,5 +80,7 @@ in \i ${cfg.fixtures} ''; }; + + services.ihp.databaseUrl = ""; # TODO: Set this to some real value } diff --git a/NixSupport/nixosModules/options.nix b/NixSupport/nixosModules/options.nix index 7e3a7e40c..b9bcc7fca 100644 --- a/NixSupport/nixosModules/options.nix +++ b/NixSupport/nixosModules/options.nix @@ -1,5 +1,6 @@ # Running IHP app + a local Postgres connected to it -{ config, pkgs, modulesPath, lib, ihpApp, ... }: +{ config, pkgs, modulesPath, lib, ... }: +with lib; { options.services.ihp = { enable = mkEnableOption "IHP"; @@ -7,6 +8,11 @@ type = types.str; default = "localhost"; }; + + baseUrl = mkOption { + type = types.str; + default = "https://${config.services.ihp.domain}"; + }; migrations = mkOption { type = types.path; @@ -21,7 +27,7 @@ }; httpsEnabled = mkOption { - type = types.boolean; + type = types.bool; default = true; }; @@ -35,6 +41,10 @@ default = "ihp"; }; + databaseUrl = mkOption { + type = types.str; + }; + # https://ihp.digitallyinduced.com/Guide/database-migrations.html#skipping-old-migrations minimumRevision = mkOption { type = types.int; @@ -60,7 +70,7 @@ type = types.str; }; - addionalEnvVars = mkOption { + additionalEnvVars = mkOption { type = types.attrs; default = {}; }; diff --git a/NixSupport/nixosModules/services/app.nix b/NixSupport/nixosModules/services/app.nix index dc7cb8019..7039f32ca 100644 --- a/NixSupport/nixosModules/services/app.nix +++ b/NixSupport/nixosModules/services/app.nix @@ -1,5 +1,6 @@ -{ config, pkgs, modulesPath, lib, ihpApp, migrate, migrations, ... }: -let cfg = config.services.ihp; +{ config, pkgs, modulesPath, lib, ihpApp, ... }: +let + cfg = config.services.ihp; in { systemd.services.app = { @@ -16,7 +17,7 @@ in environment = let defaultEnv = { - PORT = cfg.appPort; + PORT = "${toString cfg.appPort}"; IHP_ENV = cfg.ihpEnv; IHP_BASEURL = cfg.baseUrl; IHP_REQUEST_LOGGER_IP_ADDR_SOURCE = cfg.requestLoggerIPAddrSource; diff --git a/NixSupport/nixosModules/services/migrate.nix b/NixSupport/nixosModules/services/migrate.nix index 3156cb677..595f03ce2 100644 --- a/NixSupport/nixosModules/services/migrate.nix +++ b/NixSupport/nixosModules/services/migrate.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, pkgs, ihp, ... }: let cfg = config.services.ihp; in { @@ -12,16 +12,16 @@ in ''; }; in { - serviceConfig = { - Type = "oneshot"; - }; - script = '' - cd ${migrateApp} - ${self.packages.x86_64-linux.migrate}/bin/migrate - ''; - environment = { - DATABASE_URL = cfg.databaseUrl; - MINIMUM_REVISION = "${cfg.minimumRevision}"; - }; + serviceConfig = { + Type = "oneshot"; + }; + script = '' + cd ${migrateApp} + ${ihp.apps.x86_64-linux.migrate.program} + ''; + environment = { + DATABASE_URL = cfg.databaseUrl; + MINIMUM_REVISION = "${toString cfg.minimumRevision}"; + }; }; } \ No newline at end of file diff --git a/NixSupport/nixosModules/services/worker.nix b/NixSupport/nixosModules/services/worker.nix index a704ae757..d32c0dce4 100644 --- a/NixSupport/nixosModules/services/worker.nix +++ b/NixSupport/nixosModules/services/worker.nix @@ -1,5 +1,6 @@ -{ config, pkgs, modulesPath, lib, ihpApp, migrate, migrations, ... }: -let cfg = config.services.ihp; +{ config, pkgs, ihpApp, lib, ... }: +let + cfg = config.services.ihp; in { systemd.services.worker = { @@ -15,7 +16,7 @@ in environment = let defaultEnv = { - PORT = cfg.port; + PORT = "${toString cfg.appPort}"; IHP_ENV = cfg.ihpEnv; IHP_BASEURL = cfg.baseUrl; IHP_REQUEST_LOGGER_IP_ADDR_SOURCE = cfg.requestLoggerIPAddrSource; diff --git a/devenv-module.nix b/devenv-module.nix index cb34a17ff..8e2489de0 100644 --- a/devenv-module.nix +++ b/devenv-module.nix @@ -3,22 +3,28 @@ flake-parts module for setting the local IHP devenv shell this is different from the devenv environment used by IHP apps! that is defined in flake-module.nix */ - +{ inputs }: { - perSystem = { pkgs, lib, ... }: { + perSystem = { nix-filter, pkgs, lib, ... }: let + ghcCompiler = import ./NixSupport/mkGhcCompiler.nix { + inherit pkgs; + ghcCompiler = pkgs.haskell.packages.ghc944; + ihp = ./.; + filter = inputs.nix-filter.lib; + }; + in { + + apps.migrate = { + type = "app"; + program = "${ghcCompiler.ihp}/bin/migrate"; + }; + devenv.shells.default = { packages = with pkgs; [ entr nodejs-18_x ]; containers = lib.mkForce {}; # https://github.com/cachix/devenv/issues/528 languages.haskell.enable = true; languages.haskell.package = - let - ghcCompiler = import ./NixSupport/mkGhcCompiler.nix { - inherit pkgs; - ghcCompiler = pkgs.haskell.packages.ghc944; - ihp = ./.; - }; - in ghcCompiler.ghc.withPackages (p: with p; [ # Copied from ihp.nix base diff --git a/flake-module.nix b/flake-module.nix index 9e2333419..783d4aece 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -95,6 +95,7 @@ ihpFlake: inherit (cfg) ghcCompiler dontCheckPackages doJailbreakPackages dontHaddockPackages; ihp = ihp; haskellPackagesDir = cfg.projectPath + "/Config/nix/haskell-packages"; + filter = ihpFlake.inputs.nix-filter.lib; }; in lib.mkIf cfg.enable { # release build package @@ -125,11 +126,6 @@ ihpFlake: pkgs = pkgs; }; - - migrate = pkgs.writeScriptBin "migrate" '' - ${ghcCompiler.ihp}/bin/migrate - ''; - ihp-schema = pkgs.stdenv.mkDerivation { name = "ihp-schema"; src = ihp; diff --git a/flake.lock b/flake.lock index 701d4615e..08788ca7f 100644 --- a/flake.lock +++ b/flake.lock @@ -9,6 +9,31 @@ ], "pre-commit-hooks": "pre-commit-hooks" }, + "locked": { + "lastModified": 1690831896, + "narHash": "sha256-k4Cb2/Yx2kL8TFuVejwEk4R0J+5sxbydAj2IZBKZg7o=", + "owner": "cachix", + "repo": "devenv", + "rev": "e91205acb792f6a49ea53ab04c04fbc2a85039cd", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "nix": "nix_2", + "nixpkgs": [ + "ihp-boilerplate", + "ihp", + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks_2" + }, "locked": { "lastModified": 1686054274, "narHash": "sha256-93aebyN7EMmeFFXisFIvp28UEbrozu79vd3pKPjvNR0=", @@ -39,10 +64,44 @@ "type": "github" } }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, + "locked": { + "lastModified": 1690933134, + "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, "locked": { "lastModified": 1685662779, "narHash": "sha256-cKDDciXGpMEjP1n6HlzKinN0H+oLmNpgeCTzYnsA2po=", @@ -58,6 +117,24 @@ } }, "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "locked": { "lastModified": 1667395993, "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", @@ -94,7 +171,92 @@ "type": "github" } }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "ihp-boilerplate", + "ihp", + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "ihp": { + "inputs": { + "devenv": "devenv_2", + "flake-parts": "flake-parts_2", + "ihp-boilerplate": "ihp-boilerplate_2", + "nixpkgs": "nixpkgs", + "systems": "systems_2" + }, + "locked": { + "lastModified": 1689949405, + "narHash": "sha256-o0ZSDaDFgwbXqozHfcXKxW4FeF7JqaGprAh6r7NhvhE=", + "owner": "digitallyinduced", + "repo": "ihp", + "rev": "e6c6eaf1d089423a03e586cd25d1eda39f5a6b11", + "type": "github" + }, + "original": { + "owner": "digitallyinduced", + "ref": "v1.1", + "repo": "ihp", + "type": "github" + } + }, "ihp-boilerplate": { + "inputs": { + "devenv": [ + "ihp-boilerplate", + "ihp", + "devenv" + ], + "flake-parts": [ + "ihp-boilerplate", + "ihp", + "flake-parts" + ], + "ihp": "ihp", + "nixpkgs": [ + "ihp-boilerplate", + "ihp", + "nixpkgs" + ], + "systems": [ + "ihp-boilerplate", + "ihp", + "systems" + ] + }, + "locked": { + "lastModified": 1689954789, + "narHash": "sha256-RsgD1YGSlx+K/GkTspOdg/tz47PyZZDc66PzfFZvqBk=", + "owner": "digitallyinduced", + "repo": "ihp-boilerplate", + "rev": "832d1a5aed4dc3625486c82b06a1d07024267680", + "type": "github" + }, + "original": { + "owner": "digitallyinduced", + "repo": "ihp-boilerplate", + "type": "github" + } + }, + "ihp-boilerplate_2": { "flake": false, "locked": { "lastModified": 1686165507, @@ -127,6 +289,22 @@ "type": "github" } }, + "lowdown-src_2": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, "nix": { "inputs": { "lowdown-src": "lowdown-src", @@ -151,6 +329,47 @@ "type": "github" } }, + "nix-filter": { + "locked": { + "lastModified": 1687178632, + "narHash": "sha256-HS7YR5erss0JCaUijPeyg2XrisEb959FIct3n2TMGbE=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "d90c75e8319d0dd9be67d933d8eb9d0894ec9174", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nix_2": { + "inputs": { + "lowdown-src": "lowdown-src_2", + "nixpkgs": [ + "ihp-boilerplate", + "ihp", + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression_2" + }, + "locked": { + "lastModified": 1676545802, + "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "owner": "domenkozar", + "repo": "nix", + "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1681488673, @@ -168,6 +387,24 @@ } }, "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1690881714, + "narHash": "sha256-h/nXluEqdiQHs1oSgkOOWF+j8gcJMWhwnZ9PFabN6q0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9e1960bc196baf6881340d53dccb203a951745a2", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib_2": { "locked": { "dir": "lib", "lastModified": 1685564631, @@ -201,7 +438,39 @@ "type": "github" } }, + "nixpkgs-regression_2": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, "nixpkgs-stable": { + "locked": { + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { "locked": { "lastModified": 1678872516, "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=", @@ -217,6 +486,22 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1681488673, + "narHash": "sha256-PmojOyePBNvbY3snYE7NAQHTLB53t7Ro+pgiJ4wPCuk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a95ed9fe764c3ba2bf2d2fa223012c379cd6b32e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a95ed9fe764c3ba2bf2d2fa223012c379cd6b32e", + "type": "github" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": [ @@ -231,6 +516,38 @@ ], "nixpkgs-stable": "nixpkgs-stable" }, + "locked": { + "lastModified": 1688056373, + "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_2": { + "inputs": { + "flake-compat": [ + "ihp-boilerplate", + "ihp", + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils_2", + "gitignore": "gitignore_2", + "nixpkgs": [ + "ihp-boilerplate", + "ihp", + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, "locked": { "lastModified": 1682596858, "narHash": "sha256-Hf9XVpqaGqe/4oDGr30W8HlsWvJXtMsEPHDqHZA6dDg=", @@ -250,8 +567,9 @@ "devenv": "devenv", "flake-parts": "flake-parts", "ihp-boilerplate": "ihp-boilerplate", - "nixpkgs": "nixpkgs", - "systems": "systems" + "nix-filter": "nix-filter", + "nixpkgs": "nixpkgs_2", + "systems": "systems_3" } }, "systems": { @@ -268,6 +586,36 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 6da538a52..38e75d7c5 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,9 @@ # TODO use a corresponding release branch # import ihp-boilerplate for the templates - ihp-boilerplate.url = "github:digitallyinduced/ihp-boilerplate/nicolas/flake"; + ihp-boilerplate.url = "github:digitallyinduced/ihp-boilerplate"; + + nix-filter.url = "github:numtide/nix-filter"; }; outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } ( @@ -25,7 +27,7 @@ systems = import inputs.systems; imports = [ inputs.devenv.flakeModule - ./devenv-module.nix + (flake-parts-lib.importApply ./devenv-module.nix { inherit inputs; }) ]; flake = { diff --git a/ihp.nix b/ihp.nix index 894ea3f30..ea13e9e48 100644 --- a/ihp.nix +++ b/ihp.nix @@ -65,11 +65,12 @@ , ihp-hsx , ihp-postgresql-simple-extra , nix-gitignore +, filter }: mkDerivation { pname = "ihp"; version = "v1.1.0"; - src = nix-gitignore.gitignoreSource [ ] ./.; + src = filter { root = ./.; include = ["IHP" "ihp.cabal" "exe" "LICENSE" "lib"]; }; isLibrary = true; isExecutable = true; allowInconsistentDependencies = true; From 09190ecad5c8e2d33369868a6f79c14115ad9d3b Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Tue, 22 Aug 2023 21:11:35 -0700 Subject: [PATCH 4/6] Enable automatic nix gc for appWithPostgres --- NixSupport/nixosModules/appWithPostgres.nix | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/NixSupport/nixosModules/appWithPostgres.nix b/NixSupport/nixosModules/appWithPostgres.nix index eb39fdef1..c732c4581 100644 --- a/NixSupport/nixosModules/appWithPostgres.nix +++ b/NixSupport/nixosModules/appWithPostgres.nix @@ -82,5 +82,19 @@ in }; services.ihp.databaseUrl = ""; # TODO: Set this to some real value + + # Enable automatic GC to avoid the disk from filling up + # + # https://github.com/digitallyinduced/ihp/pull/1792#pullrequestreview-1570755863 + # + # " It's was a recurring problem on Shipnix that people ran out of disk space and the database service crashed without this" + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + + # Saves disk space by detecting and handling identical contents in the Nix Store + nix.settings.auto-optimise-store = true; } From 642b1599e0669d4b214f848105617ccae3ca87c7 Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Tue, 22 Aug 2023 21:13:06 -0700 Subject: [PATCH 5/6] Move swap settings to the user configuration --- Guide/deployment.markdown | 4 ++++ NixSupport/nixosModules/app.nix | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Guide/deployment.markdown b/Guide/deployment.markdown index 15b2b9ddc..44e1232cd 100644 --- a/Guide/deployment.markdown +++ b/Guide/deployment.markdown @@ -52,6 +52,10 @@ flake.nixosConfigurations."ihp-app" = nixpkgs.lib.nixosSystem { fixtures = ./Application/Fixtures.sql; sessionSecret = "xxx"; }; + + # Add swap to avoid running out of memory during builds + # Useful if your server have less than 4GB memory + swapDevices = [ { device = "/swapfile"; size = 8192; } ]; }) ]; }; diff --git a/NixSupport/nixosModules/app.nix b/NixSupport/nixosModules/app.nix index ec3091ec2..9e93fc2fc 100644 --- a/NixSupport/nixosModules/app.nix +++ b/NixSupport/nixosModules/app.nix @@ -13,9 +13,6 @@ in # Speed up builds with the IHP binary cache nix.settings.substituters = [ "https://digitallyinduced.cachix.org" ]; nix.settings.trusted-public-keys = [ "digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE=" ]; - - # Add swap to avoid running out of memory during builds - swapDevices = [ { device = "/swapfile"; size = 8192; } ]; # Pin the nixpkgs to the IHP nixpkgs nix.registry.nixpkgs.flake = nixpkgs; From f2ce1c528736d5ca41e5895b9f8c84013304dabf Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Tue, 22 Aug 2023 21:16:32 -0700 Subject: [PATCH 6/6] Move system.stateVersion to the user config --- Guide/deployment.markdown | 5 +++++ NixSupport/nixosModules/app.nix | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Guide/deployment.markdown b/Guide/deployment.markdown index 44e1232cd..f67ac5007 100644 --- a/Guide/deployment.markdown +++ b/Guide/deployment.markdown @@ -56,6 +56,11 @@ flake.nixosConfigurations."ihp-app" = nixpkgs.lib.nixosSystem { # Add swap to avoid running out of memory during builds # Useful if your server have less than 4GB memory swapDevices = [ { device = "/swapfile"; size = 8192; } ]; + + # This should reflect the nixos version from the NixOS AMI initally installed + # After the initial install, it should not be changed. Otherwise e.g. the postgres + # server might need a manual data migration if NixOS changes the default postgres version + system.stateVersion = "23.05"; }) ]; }; diff --git a/NixSupport/nixosModules/app.nix b/NixSupport/nixosModules/app.nix index 9e93fc2fc..9e4d637ac 100644 --- a/NixSupport/nixosModules/app.nix +++ b/NixSupport/nixosModules/app.nix @@ -16,7 +16,5 @@ in # Pin the nixpkgs to the IHP nixpkgs nix.registry.nixpkgs.flake = nixpkgs; - - system.stateVersion = "23.05"; }