diff --git a/flake.nix b/flake.nix index 4afb27a..30fb5cb 100644 --- a/flake.nix +++ b/flake.nix @@ -44,9 +44,24 @@ ./machines ./routers ./inventories + ./overlays + ./tests ./modules/clan/flake-module.nix ./modules/nixos/flake-module.nix ]; + perSystem = + { pkgs, system, ... }: + { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ + inputs.self.overlays.packagesOverlay + ]; + config = { }; + }; + packages.think = pkgs.think-gtcm; + packages.think-be = pkgs.think-backend-gtcm; + }; } ); } diff --git a/modules/nixos/flake-module.nix b/modules/nixos/flake-module.nix index b8a1ffc..2f56f14 100644 --- a/modules/nixos/flake-module.nix +++ b/modules/nixos/flake-module.nix @@ -3,5 +3,8 @@ common = { imports = [ ./common.nix ]; }; + think-gtcm = { + imports = [ ./think-gtcm.nix ]; + }; }; } diff --git a/modules/nixos/think-gtcm.nix b/modules/nixos/think-gtcm.nix new file mode 100644 index 0000000..4748099 --- /dev/null +++ b/modules/nixos/think-gtcm.nix @@ -0,0 +1,256 @@ +{ + config, + pkgs, + lib, + ... +}: +let + cfg = config.services.think-greaterchiangmai; + defaultUser = "gtcm"; + defaultGroup = "gtcm"; +in +{ + options.services.think-greaterchiangmai = { + enable = lib.mkEnableOption "To enable think.greaterchiangmai.com"; + + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/think.greaterchiangmai.com"; + description = ''A place where to store states''; + }; + + user = lib.mkOption { + type = lib.types.str; + default = defaultUser; + description = "User account under which this runs."; + }; + + group = lib.mkOption { + type = lib.types.str; + default = defaultGroup; + defaultText = "${defaultGroup}"; + description = '' + Group under which the website runs. + ''; + }; + + package = lib.mkPackageOption pkgs "think-gtcm" { }; + + packageBackend = lib.mkPackageOption pkgs "think-backend-gtcm" { }; + + domain = lib.mkOption { + type = lib.types.str; + default = "think.greaterchiangmai.com"; + example = "forum.example.com"; + description = "Domain to serve on."; + }; + + backendDomain = lib.mkOption { + type = lib.types.str; + default = "think-backend.greaterchiangmai.com"; + example = "forum.example.com"; + description = "Backend Domain to serve on."; + }; + + settings = lib.mkOption { + default = { }; + description = '' + Options for settings environment variables + ''; + example = lib.literalExpression '' + { + APP_NAME=Laravel + APP_ENV=local + APP_KEY= + APP_DEBUG=true + APP_URL=http://localhost + + LOG_CHANNEL=stack + LOG_DEPRECATIONS_CHANNEL=null + LOG_LEVEL=debug + + DB_CONNECTION=mysql + DB_HOST=127.0.0.1 + DB_PORT=3306 + DB_DATABASE=laravel + DB_USERNAME=root + DB_PASSWORD= + + BROADCAST_DRIVER=log + CACHE_DRIVER=file + FILESYSTEM_DISK=local + QUEUE_CONNECTION=sync + SESSION_DRIVER=file + SESSION_LIFETIME=120 + + MEMCACHED_HOST=127.0.0.1 + + REDIS_HOST=127.0.0.1 + REDIS_PASSWORD=null + REDIS_PORT=6379 + + MAIL_MAILER=smtp + MAIL_HOST=mailpit + MAIL_PORT=1025 + MAIL_USERNAME=null + MAIL_PASSWORD=null + MAIL_ENCRYPTION=null + MAIL_FROM_ADDRESS="hello@example.com" + MAIL_FROM_NAME="''${APP_NAME}" + + AWS_ACCESS_KEY_ID= + AWS_SECRET_ACCESS_KEY= + AWS_DEFAULT_REGION=us-east-1 + AWS_BUCKET= + AWS_USE_PATH_STYLE_ENDPOINT=false + + PUSHER_APP_ID= + PUSHER_APP_KEY= + PUSHER_APP_SECRET= + PUSHER_HOST= + PUSHER_PORT=443 + PUSHER_SCHEME=https + PUSHER_APP_CLUSTER=mt1 + + VITE_APP_NAME="''${APP_NAME}" + VITE_PUSHER_APP_KEY="''${PUSHER_APP_KEY}" + VITE_PUSHER_HOST="''${PUSHER_HOST}" + VITE_PUSHER_PORT="''${PUSHER_PORT}" + VITE_PUSHER_SCHEME="''${PUSHER_SCHEME}" + VITE_PUSHER_APP_CLUSTER="''${PUSHER_APP_CLUSTER}" + } + ''; + type = lib.types.submodule { + freeformType = lib.types.attrsOf ( + lib.types.oneOf [ + lib.types.str + lib.types.int + lib.types.bool + ] + ); + options = { + DB_CONNECTION = lib.mkOption { + type = lib.types.enum [ + "mysql" + ]; + default = "mysql"; + example = "mysql"; + description = '' + The type of database you wish to use. only "mysql". + ''; + }; + DB_HOST = lib.mkOption { + type = lib.types.str; + default = if cfg.settings.DB_CONNECTION == "pgsql" then "/run/postgresql" else "localhost"; + defaultText = '' + "localhost" if DB_CONNECTION is "sqlite" or "mysql", "/run/postgresql" if "pgsql". + ''; + description = '' + The machine which hosts your database. This is left at the + default value for "mysql" because we use the "DB_SOCKET" option + to connect to a unix socket instead. "pgsql" requires that the + unix socket location be specified here instead of at "DB_SOCKET". + This option does not affect "sqlite". + ''; + }; + DB_PORT = lib.mkOption { + type = lib.types.nullOr lib.types.int; + default = + if cfg.settings.DB_CONNECTION == "pgsql" then + 5432 + else if cfg.settings.DB_CONNECTION == "mysql" then + 3306 + else + null; + defaultText = '' + `null` if DB_CONNECTION is "sqlite", `3306` if "mysql", `5432` if "pgsql" + ''; + description = '' + The port your database is listening at. sqlite does not require + this value to be filled. + ''; + }; + DB_DATABASE = lib.mkOption { + type = lib.types.str; + default = "thinkgreatercm"; + }; + DB_USERNAME = lib.mkOption { + type = lib.types.str; + default = "thinkgreatercm"; + }; + DB_PASSWORD = lib.mkOption { + type = lib.types.str; + default = "thinkgreatercm"; + }; + }; + }; + }; + + }; + config = lib.mkIf cfg.enable { + users.users.${cfg.user} = { + isSystemUser = true; + home = cfg.dataDir; + createHome = true; + homeMode = "755"; + group = cfg.group; + }; + users.groups.${cfg.group} = { }; + + services.phpfpm.pools.think-greaterchiangmai = { + inherit (cfg) user group; + settings = { + "listen.owner" = config.services.nginx.user; + "listen.group" = config.services.nginx.group; + "listen.mode" = "0600"; + "pm" = lib.mkDefault "dynamic"; + "pm.max_children" = lib.mkDefault 10; + "pm.max_requests" = lib.mkDefault 500; + "pm.start_servers" = lib.mkDefault 2; + "pm.min_spare_servers" = lib.mkDefault 1; + "pm.max_spare_servers" = lib.mkDefault 3; + }; + phpOptions = '' + error_log = syslog + log_errors = on + ''; + }; + services.nginx = { + enable = true; + virtualHosts."${cfg.domain}" = { + root = "${cfg.package}/share/php/think-gtcm/public"; + locations."~ \\.php$".extraConfig = '' + fastcgi_pass unix:${config.services.phpfpm.pools.think-greaterchiangmai.socket}; + fastcgi_index site.php; + ''; + extraConfig = '' + index index.php; + ''; + }; + virtualHosts."${cfg.backendDomain}" = { + root = "${cfg.packageBackend}/share/php/think-backend-gtcm/public"; + locations."~ \\.php$".extraConfig = '' + fastcgi_pass unix:${config.services.phpfpm.pools.think-greaterchiangmai.socket}; + fastcgi_index site.php; + ''; + extraConfig = '' + index index.php; + ''; + }; + }; + + services.mysql = { + enable = true; + package = pkgs.mariadb; + ensureDatabases = [ cfg.settings.DB_DATABASE ]; + ensureUsers = [ + { + name = cfg.settings.DB_USERNAME; + ensurePermissions = { + "${cfg.settings.DB_DATABASE}.*" = "ALL PRIVILEGES"; + }; + } + ]; + }; + }; +} diff --git a/overlays/default.nix b/overlays/default.nix new file mode 100644 index 0000000..583c8e9 --- /dev/null +++ b/overlays/default.nix @@ -0,0 +1,6 @@ +{ ... }: +{ + flake.overlays = { + packagesOverlay = import ../pkgs/overlay.nix; + }; +} diff --git a/pkgs/overlay.nix b/pkgs/overlay.nix new file mode 100644 index 0000000..d327dd3 --- /dev/null +++ b/pkgs/overlay.nix @@ -0,0 +1,4 @@ +final: prev: { + think-gtcm = final.callPackage ./think-gtcm.nix { }; + think-backend-gtcm = final.callPackage ./think-backend-gtcm.nix { php = final.php83; }; +} diff --git a/pkgs/think-backend-gtcm.nix b/pkgs/think-backend-gtcm.nix new file mode 100644 index 0000000..5deafb4 --- /dev/null +++ b/pkgs/think-backend-gtcm.nix @@ -0,0 +1,21 @@ +{ + fetchgit, + php, +}: +let + repoSrc = fetchgit { + url = "https://git.b4l.co.th/newedge/think-greaterchiangmai"; + rev = "7c17aa78436538241c09fc7d633904d3c063011e"; + hash = "sha256-GDx0+PmuCXC+UPtsvsocCZQiTPcnOZEzJI17sxrVv7Q="; + }; + src = "${repoSrc}/think-backend.greaterchiangmai.com"; +in +php.buildComposerProject2 (finalAttrs: { + pname = "think-backend-gtcm"; + version = "1.0.0"; + + inherit src; + + composerStrictValidation = false; + vendorHash = "sha256-eXm1x3E9KHWojaT2RU4inMdZqQVcWdLCKlvzhOlIZrc="; +}) diff --git a/pkgs/think-gtcm.nix b/pkgs/think-gtcm.nix new file mode 100644 index 0000000..c036f6f --- /dev/null +++ b/pkgs/think-gtcm.nix @@ -0,0 +1,21 @@ +{ + fetchgit, + php, +}: +let + repoSrc = fetchgit { + url = "https://git.b4l.co.th/newedge/think-greaterchiangmai"; + rev = "7c17aa78436538241c09fc7d633904d3c063011e"; + hash = "sha256-GDx0+PmuCXC+UPtsvsocCZQiTPcnOZEzJI17sxrVv7Q="; + }; + src = "${repoSrc}/think.greaterchiangmai.com"; +in +php.buildComposerProject2 (finalAttrs: { + pname = "think-gtcm"; + version = "1.0.0"; + + inherit src; + + composerStrictValidation = false; + vendorHash = "sha256-QV3hR3U3GwCqrCRxfkazmJwDpO1vFyMfA6YqUb4bjMI="; +}) diff --git a/routers/default.nix b/routers/default.nix index 0c5d3c5..cb37001 100644 --- a/routers/default.nix +++ b/routers/default.nix @@ -1,4 +1,4 @@ -{ inputs, ... }: +{ inputs, pkgs, ... }: { flake.legacyPackages = { whitehouse-router = import "${inputs.liminix}/default.nix" { diff --git a/tests/default.nix b/tests/default.nix new file mode 100644 index 0000000..8770e48 --- /dev/null +++ b/tests/default.nix @@ -0,0 +1,16 @@ +{ self, ... }: +{ + perSystem = + { pkgs, ... }: + { + checks = + let + checkArgs = { + inherit pkgs self; + }; + in + { + think-gtcm = import ./tests/think-gtcm.nix checkArgs; + }; + }; +} diff --git a/tests/lib.nix b/tests/lib.nix new file mode 100644 index 0000000..08b33c9 --- /dev/null +++ b/tests/lib.nix @@ -0,0 +1,18 @@ +test: +# These arguments are provided by `flake.nix` on import, see checkArgs +{ pkgs, self }: +let + inherit (pkgs) lib; + # this imports the nixos library that contains our testing framework + nixos-lib = import (pkgs.path + "/nixos/lib") { }; +in +(nixos-lib.runTest { + hostPkgs = pkgs; + # This speeds up the evaluation by skipping evaluating documentation (optional) + defaults.documentation.enable = lib.mkDefault false; + # This makes `self` available in the NixOS configuration of our virtual machines. + # This is useful for referencing modules or packages from your own flake + # as well as importing from other flakes. + node.specialArgs = { inherit self; }; + imports = [ test ]; +}).config.result diff --git a/tests/tests/think-gtcm.nix b/tests/tests/think-gtcm.nix new file mode 100644 index 0000000..8ee2c77 --- /dev/null +++ b/tests/tests/think-gtcm.nix @@ -0,0 +1,23 @@ +(import ../lib.nix) { + name = "think-gtcm"; + nodes = { + # `self` here is set by using specialArgs in `lib.nix` + node1 = + { self, pkgs, ... }: + { + nixpkgs.overlays = [ self.overlays.packagesOverlay ]; + imports = [ self.nixosModules.think-gtcm ]; + services.think-greaterchiangmai = { + enable = true; + }; + }; + }; + # This is the test code that will check if our service is running correctly: + testScript = '' + start_all() + + node1.wait_for_unit("phpfpm-think-greaterchiangmai") + node1.wait_for_open_port(80) + output = node1.succeed("curl localhost") + ''; +}