commit b5cc516e2041f8e43695efe61fa226d2c617137e
parent b453dc8056b152bfc4f966aae110d1c12c4975f4
Author: Silas Brack <silasbrack@gmail.com>
Date: Wed, 8 Jan 2025 19:52:27 +0100
refactor!: redesign everything
Diffstat:
21 files changed, 297 insertions(+), 856 deletions(-)
diff --git a/README.md b/CHANGELOG.md
diff --git a/README.md b/README.md
@@ -0,0 +1,4 @@
+# My Project
+- `nix develop`
+- `nixos-shell --flake .`
+
diff --git a/apps/my_app/.github/workflows/test.yml b/apps/my_app/.github/workflows/test.yml
@@ -1,23 +0,0 @@
-name: test
-
-on:
- push:
- branches:
- - master
- - main
- pull_request:
-
-jobs:
- test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: erlef/setup-beam@v1
- with:
- otp-version: "26.0.2"
- gleam-version: "1.5.1"
- rebar3-version: "3"
- # elixir-version: "1.15.4"
- - run: gleam deps download
- - run: gleam test
- - run: gleam format --check src test
diff --git a/apps/my_app/.gitignore b/apps/my_app/.gitignore
@@ -1,5 +0,0 @@
-*.beam
-*.ez
-/build
-erl_crash.dump
-nixos.qcow2
diff --git a/apps/my_app/README.md b/apps/my_app/README.md
@@ -1,33 +0,0 @@
-# my_app
-
-[](https://hex.pm/packages/my_app)
-[](https://hexdocs.pm/my_app/)
-
-```sh
-gleam add my_app@1
-```
-```gleam
-import my_app
-
-pub fn main() {
- // TODO: An example of the project in use
-}
-```
-
-Further documentation can be found at <https://hexdocs.pm/my_app>.
-
-## Development
-
-```sh
-gleam run # Run the project
-gleam test # Run the tests
-```
-
-```sh
-#! /usr/bin/env nix-shell
-#! nix-shell -i bash -p gleam
-(cd shared && gleam clean) \
-&& (cd client && gleam clean && gleam run -m lustre/dev build --outdir=../server/priv/static --minify) \
-&& (cd server && gleam deps download && gleam export erlang-shipment && cp -r ./build/erlang-shipment/ ../)
-```
-
diff --git a/apps/my_app/flake.lock b/apps/my_app/flake.lock
@@ -1,111 +0,0 @@
-{
- "nodes": {
- "flake-utils": {
- "inputs": {
- "systems": "systems"
- },
- "locked": {
- "lastModified": 1726560853,
- "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "nix-gleam": {
- "locked": {
- "lastModified": 1717670865,
- "narHash": "sha256-+dAPiKAwCzlKWtx3aIHXfR6jydh1JyangewqZKJx500=",
- "owner": "arnarg",
- "repo": "nix-gleam",
- "rev": "c69abe0e57a01991654d3de63dcd93a8b91b98ff",
- "type": "github"
- },
- "original": {
- "owner": "arnarg",
- "repo": "nix-gleam",
- "type": "github"
- }
- },
- "nixos-shell": {
- "inputs": {
- "nixpkgs": "nixpkgs"
- },
- "locked": {
- "lastModified": 1728308049,
- "narHash": "sha256-wjAkG8f5orZ4+wgXmEaFAJkVJS6ORqfgM0zzLEvbUNw=",
- "owner": "Mic92",
- "repo": "nixos-shell",
- "rev": "9373ca9522f844a3b8029720c74f340e560e4462",
- "type": "github"
- },
- "original": {
- "owner": "Mic92",
- "repo": "nixos-shell",
- "type": "github"
- }
- },
- "nixpkgs": {
- "locked": {
- "lastModified": 1628465643,
- "narHash": "sha256-QSNw9bDq9uGUniQQtakRuw4m21Jxugm23SXLVgEV4DM=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "6ef4f522d63f22b40004319778761040d3197390",
- "type": "github"
- },
- "original": {
- "id": "nixpkgs",
- "ref": "nixos-unstable",
- "type": "indirect"
- }
- },
- "nixpkgs_2": {
- "locked": {
- "lastModified": 1728492678,
- "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "root": {
- "inputs": {
- "flake-utils": "flake-utils",
- "nix-gleam": "nix-gleam",
- "nixos-shell": "nixos-shell",
- "nixpkgs": "nixpkgs_2"
- }
- },
- "systems": {
- "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",
- "version": 7
-}
diff --git a/apps/my_app/flake.nix b/apps/my_app/flake.nix
@@ -1,45 +0,0 @@
-{
- description = "My gleam monorepo";
- inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- flake-utils.url = "github:numtide/flake-utils";
- nix-gleam.url = "github:arnarg/nix-gleam";
- };
-
- outputs =
- {
- nixpkgs,
- flake-utils,
- nix-gleam,
- }:
- (flake-utils.lib.eachDefaultSystem (
- system:
- let
- pkgs = import nixpkgs {
- inherit system;
- overlays = [
- nix-gleam.overlays.default
- ];
- };
- in
- {
- packages.default = pkgs.buildGleamApplication {
- src = ./.;
- erlangPackage = pkgs.erlang_27;
- };
- # apps.default = {
- # type = "app";
- # program = "${}/bin/my";
- # };
- devShells.system.default = {
- buildInputs = [
- pkgs.gleam
- pkgs.erlang_27
- pkgs.rebar3
- pkgs.inotify-tools
- pkgs.nodejs_22
- ];
- };
- }
- ));
-}
diff --git a/apps/my_app/gleam.toml b/apps/my_app/gleam.toml
@@ -1,36 +0,0 @@
-name = "my_app"
-version = "1.0.0"
-target = "erlang"
-
-# Fill out these fields if you intend to generate HTML documentation or publish
-# your project to the Hex package manager.
-#
-# description = ""
-# licences = ["Apache-2.0"]
-# repository = { type = "github", user = "", repo = "" }
-# links = [{ title = "Website", href = "" }]
-#
-# For a full reference of all the available options, you can have a look at
-# https://gleam.run/writing-gleam/gleam-toml/.
-
-[dependencies]
-gleam_json = ">= 1.0.1 and < 2.0.0"
-gleam_stdlib = ">= 0.40.0 and < 1.0.0"
-decipher = ">= 1.2.1 and < 2.0.0"
-decode = ">= 0.3.0 and < 1.0.0"
-glenv = ">= 0.4.0 and < 1.0.0"
-lustre = ">= 4.5.1 and < 5.0.0"
-lustre_http = ">= 0.5.2 and < 1.0.0"
-wisp = ">= 1.2.0 and < 2.0.0"
-# gleam_stdlib = ">= 0.34.0 and < 2.0.0"
-# mist = ">= 3.0.0 and < 4.0.0"
-# gleam_erlang = ">= 0.27.0 and < 1.0.0"
-# gleam_http = ">= 3.7.0 and < 4.0.0"
-# gleam_otp = ">= 0.12.1 and < 1.0.0"
-# wisp = ">= 1.2.0 and < 2.0.0"
-# decode = ">= 0.2.1 and < 1.0.0"
-# glenv = ">= 0.4.0 and < 1.0.0"
-
-[dev-dependencies]
-gleeunit = ">= 1.0.0 and < 2.0.0"
-lustre_dev_tools = ">= 1.6.0 and < 2.0.0"
diff --git a/apps/my_app/manifest.toml b/apps/my_app/manifest.toml
@@ -1,63 +0,0 @@
-# This file was generated by Gleam
-# You typically do not need to edit this file
-
-packages = [
- { name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
- { name = "birl", version = "1.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "5C66647D62BCB11FE327E7A6024907C4A17954EF22865FE0940B54A852446D01" },
- { name = "decipher", version = "1.2.1", build_tools = ["gleam"], requirements = ["birl", "gleam_json", "gleam_stdlib", "stoiridh_version"], otp_app = "decipher", source = "hex", outer_checksum = "4F82516A5FF09BD7DF352DE38F1691C2254508066152F5DEA8665B216A9C9909" },
- { name = "decode", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "decode", source = "hex", outer_checksum = "EE9B979C0D8A5E058E2519EC0EE9CA4C7CEE15B12997BFF50492636CDC53D0C7" },
- { name = "directories", version = "1.1.0", build_tools = ["gleam"], requirements = ["envoy", "gleam_stdlib", "platform", "simplifile"], otp_app = "directories", source = "hex", outer_checksum = "BDA521A4EB9EE3A7894F0DC863797878E91FF5C7826F7084B2E731E208BDB076" },
- { name = "envoy", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "CFAACCCFC47654F7E8B75E614746ED924C65BD08B1DE21101548AC314A8B6A41" },
- { name = "exception", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "F5580D584F16A20B7FCDCABF9E9BE9A2C1F6AC4F9176FA6DD0B63E3B20D450AA" },
- { name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
- { name = "fs", version = "8.6.1", build_tools = ["rebar3"], requirements = [], otp_app = "fs", source = "hex", outer_checksum = "61EA2BDAEDAE4E2024D0D25C63E44DCCF65622D4402DB4A2DF12868D1546503F" },
- { name = "gleam_community_ansi", version = "1.4.1", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "4CD513FC62523053E62ED7BAC2F36136EC17D6A8942728250A9A00A15E340E4B" },
- { name = "gleam_community_colour", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "795964217EBEDB3DA656F5EB8F67D7AD22872EB95182042D3E7AFEF32D3FD2FE" },
- { name = "gleam_crypto", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "8AE56026B3E05EBB1F076778478A762E9EB62B31AEEB4285755452F397029D22" },
- { name = "gleam_erlang", version = "0.27.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "DE468F676D71B313C6C8C5334425CFCF827837333F8AB47B64D8A6D7AA40185D" },
- { name = "gleam_fetch", version = "0.4.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_javascript", "gleam_stdlib"], otp_app = "gleam_fetch", source = "hex", outer_checksum = "7446410A44A1D1328F5BC1FF4FC9CBD1570479EA69349237B3F82E34521CCC10" },
- { name = "gleam_http", version = "3.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "EA66440C2269F7CED0F6845E5BD0DB68095775D627FA709A841CA78A398D6D56" },
- { name = "gleam_httpc", version = "3.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "091CDD2BEC8092E82707BEA03FB5205A2BBBDE4A2F551E3C069E13B8BC0C428E" },
- { name = "gleam_javascript", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "F98328FCF573DA6F3A35D7F6CB3F9FF19FD5224CCBA9151FCBEAA0B983AF2F58" },
- { name = "gleam_json", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "9063D14D25406326C0255BDA0021541E797D8A7A12573D849462CAFED459F6EB" },
- { name = "gleam_otp", version = "0.12.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "BFACC1513410DF5A1617169A9CD7EA334973AC71D860A17574BA7B2EADD89A6F" },
- { name = "gleam_package_interface", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_package_interface", source = "hex", outer_checksum = "CF3BFC5D0997750D9550D8D73A90F4B8D71C6C081B20ED4E70FFBE1E99AFC3C2" },
- { name = "gleam_stdlib", version = "0.40.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86606B75A600BBD05E539EB59FABC6E307EEEA7B1E5865AFB6D980A93BCB2181" },
- { name = "glearray", version = "0.2.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glearray", source = "hex", outer_checksum = "9C207E05F38D724F464FA921378DB3ABC2B0A2F5821116D8BC8B2CACC68930D5" },
- { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
- { name = "glenv", version = "0.4.0", build_tools = ["gleam"], requirements = ["decode", "envoy", "gleam_stdlib"], otp_app = "glenv", source = "hex", outer_checksum = "46164B9FFEB08927FD2CEBD96C3AFBE082AD5CC2C6F2FC4A78EFDA9EB61E3510" },
- { name = "glint", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "A3F1B7C665FD216BE6A886D56537F0E095FB07DF62146074109270B798F8CEC4" },
- { name = "glisten", version = "5.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib", "logging", "telemetry"], otp_app = "glisten", source = "hex", outer_checksum = "48EF7F6D1DCA877C2F49AF35CC33946C7129EEB05A114758A2CC569C708BFAF8" },
- { name = "gramps", version = "2.0.3", build_tools = ["gleam"], requirements = ["gleam_crypto", "gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gramps", source = "hex", outer_checksum = "3CCAA6E081225180D95C79679D383BBF51C8D1FDC1B84DA1DA444F628C373793" },
- { name = "hpack_erl", version = "0.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "hpack", source = "hex", outer_checksum = "D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0" },
- { name = "logging", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "1098FBF10B54B44C2C7FDF0B01C1253CAFACDACABEFB4B0D027803246753E06D" },
- { name = "lustre", version = "4.5.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "B592DA442F6577143CAFA35D4506DB2018DAEED9C707A921E33559E09F001DF1" },
- { name = "lustre_dev_tools", version = "1.6.0", build_tools = ["gleam"], requirements = ["argv", "filepath", "fs", "gleam_community_ansi", "gleam_crypto", "gleam_erlang", "gleam_http", "gleam_httpc", "gleam_json", "gleam_otp", "gleam_package_interface", "gleam_stdlib", "glint", "glisten", "mist", "simplifile", "spinner", "term_size", "tom", "wisp"], otp_app = "lustre_dev_tools", source = "hex", outer_checksum = "5A1C7D20FA2C0D77D59F259EAE0E14BB3F5359CC1DE7C5ED6922B65FFCBD4C31" },
- { name = "lustre_http", version = "0.5.2", build_tools = ["gleam"], requirements = ["gleam_fetch", "gleam_http", "gleam_javascript", "gleam_json", "gleam_stdlib", "lustre"], otp_app = "lustre_http", source = "hex", outer_checksum = "FB0478CBFA6B16DBE8ECA326DAE2EC15645E04900595EF2C4F039ABFA0512ABA" },
- { name = "marceau", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "2D1C27504BEF45005F5DFB18591F8610FB4BFA91744878210BDC464412EC44E9" },
- { name = "mist", version = "2.0.0", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten", "gramps", "hpack_erl", "logging"], otp_app = "mist", source = "hex", outer_checksum = "981F12FC8BA0656B40099EC876D6F2BEE7B95593610F342E9AB0DC4E663A932F" },
- { name = "platform", version = "1.0.0", build_tools = ["gleam"], requirements = [], otp_app = "platform", source = "hex", outer_checksum = "8339420A95AD89AAC0F82F4C3DB8DD401041742D6C3F46132A8739F6AEB75391" },
- { name = "ranger", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "1566C272B1D141B3BBA38B25CB761EF56E312E79EC0E2DFD4D3C19FB0CC1F98C" },
- { name = "repeatedly", version = "2.1.1", build_tools = ["gleam"], requirements = [], otp_app = "repeatedly", source = "hex", outer_checksum = "38808C3EC382B0CD981336D5879C24ECB37FCB9C1D1BD128F7A80B0F74404D79" },
- { name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" },
- { name = "snag", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "54D32E16E33655346AA3E66CBA7E191DE0A8793D2C05284E3EFB90AD2CE92BCC" },
- { name = "spinner", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_erlang", "gleam_stdlib", "glearray", "repeatedly"], otp_app = "spinner", source = "hex", outer_checksum = "200BA3D4A04D468898E63C0D316E23F526E02514BC46454091975CB5BAE41E8F" },
- { name = "stoiridh_version", version = "0.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "stoiridh_version", source = "hex", outer_checksum = "EEF8ADAB9755BD33EB202F169376F1A7797AEF90823FDCA671D8590D04FBF56B" },
- { name = "telemetry", version = "1.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "telemetry", source = "hex", outer_checksum = "7015FC8919DBE63764F4B4B87A95B7C0996BD539E0D499BE6EC9D7F3875B79E6" },
- { name = "term_size", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "term_size", source = "hex", outer_checksum = "D00BD2BC8FB3EBB7E6AE076F3F1FF2AC9D5ED1805F004D0896C784D06C6645F1" },
- { name = "thoas", version = "1.2.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "E38697EDFFD6E91BD12CEA41B155115282630075C2A727E7A6B2947F5408B86A" },
- { name = "tom", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "tom", source = "hex", outer_checksum = "228E667239504B57AD05EC3C332C930391592F6C974D0EFECF32FFD0F3629A27" },
- { name = "wisp", version = "1.2.0", build_tools = ["gleam"], requirements = ["directories", "exception", "gleam_crypto", "gleam_erlang", "gleam_http", "gleam_json", "gleam_stdlib", "logging", "marceau", "mist", "simplifile"], otp_app = "wisp", source = "hex", outer_checksum = "F71265D2F1DE11426535A2FA1DA3B11D2FFB783B116DF9496BC8C41983EBADB4" },
-]
-
-[requirements]
-decipher = { version = ">= 1.2.1 and < 2.0.0" }
-decode = { version = ">= 0.3.0 and < 1.0.0" }
-gleam_json = { version = ">= 1.0.1 and < 2.0.0" }
-gleam_stdlib = { version = ">= 0.40.0 and < 1.0.0" }
-gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
-glenv = { version = ">= 0.4.0 and < 1.0.0" }
-lustre = { version = ">= 4.5.1 and < 5.0.0" }
-lustre_dev_tools = { version = ">= 1.6.0 and < 2.0.0" }
-lustre_http = { version = ">= 0.5.2 and < 1.0.0" }
-wisp = { version = ">= 1.2.0 and < 2.0.0" }
diff --git a/apps/my_app/module.nix b/apps/my_app/module.nix
@@ -1,166 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
- pkg = import ./.;
- migrations = pkg.migrations;
- server = pkg.server;
- cfg = config.services.my_app;
-in {
- options = {
- services.my_app = {
- enable = mkEnableOption "My App";
-
- package = mkOption {
- defaultText = lib.literalMD "`packages.default` from the my_app flake";
- };
-
- environment = mkOption {
- type = types.enum [ "dev" "prod" ];
- default = "dev";
- example = "prod";
- description = "The environment (dev / prod) to deploy as.";
- };
-
- user = mkOption {
- type = types.str;
- default = "my_app_user";
- description = "User account under which my app runs.";
- };
-
- port = mkOption {
- type = types.nullOr types.int;
- default = 3003;
- example = 8080;
- description = ''
- The port to bind my app server to.
- '';
- };
- };
- };
-
- config = mkIf cfg.enable {
- networking.firewall.allowedTCPPorts = [ cfg.port ];
-
- users.groups.${cfg.user} = {};
- users.users.${cfg.user} = {
- name = cfg.user;
- group = cfg.user;
- description = "My app service user";
- isSystemUser = true;
- createHome = false;
- # createHome = true;
- # packages = with pkgs; [
- # gleam
- # erlang_27
- # rebar3
- # ];
- };
-
- systemd.services = {
- # clone-pokemon-app = {
- # wantedBy = [ "multi-user.target" ];
- # description = "Clone Pokemon app.";
- # after = [ "network.target" ];
- # serviceConfig = {
- # Type = "simple";
- # User = "root";
- # ExecStart = "";
- # };
- # script = ''
- # TMP_DIR=$(mktemp)
- # curl --output-dir $TMP_DIR ""
- # unzip
- # '';
- # # script = ''
- # # rsync
- # # '';
- # };
-
- my_app = {
- wantedBy = [ "multi-user.target" ];
- description = "Run my app.";
- after = [ "network.target" ];
- # after = [ "clone-pokemon-app" ];
- # requires = [ "clone-pokemon-app" ];
- serviceConfig = {
- Type = "simple";
- User = cfg.user;
- ExecStart = "${cfg.package}/bin/my_app";
- };
- environment = {
- PORT = builtins.toString cfg.port;
- };
- # path = with pkgs; [ gleam erlang_27 rebar3 ];
- };
-
- # postgres-migration = {
- # description = "Postgres migrations";
- # wantedBy = [ "multi-user.target" ];
- # after = [ "postgresql.service" ];
- # requires = [ "postgresql.service" ];
- # };
- };
-
- # services = mkIf cfg.environment == "dev" {
- # postgresql = {
- # enable = true;
- # enableTCPIP = true;
- # ensureDatabases = [ cfg.user ];
- # ensureUsers = [
- # {
- # name = cfg.user;
- # ensurePermissions = {
- # "DATABASE ${cfg.user}" = "ALL PRIVILEGES";
- # };
- # }
- # ];
- # authentication = pkgs.lib.mkOverride 10 ''
- # local sameuser all peer
- # host sameuser all ::1/32 trust
- # '';
- # };
- # };
-
- # systemd.services = {
- #
- # # db-migration = {
- # # description = "DB migrations script";
- # # wantedBy = [ "multi-user.target" ];
- # # after = [ "postgresql.service" ];
- # # requires = [ "postgresql.service" ];
- # #
- # # environment = {
- # # DATABASE_URL = "postgres://${cfg.user}@localhost:5432/myapp?sslmode=disable";
- # # };
- # #
- # # serviceConfig = {
- # # User = cfg.user;
- # # Type = "oneshot";
- # # ExecStart = "${pkgs.dbmate}/bin/dbmate -d ${migrations} --no-dump-schema up";
- # # };
- # # };
- #
- # myapp = {
- # wantedBy = [ "multi-user.target" ];
- # description = "Start my app server.";
- # after = [ "network.target" ];
- # # requires = [ "db-migration.service" ];
- #
- # # environment = {
- # # APP_PORT = toString cfg.port;
- # # DATABASE_URL = "postgres:///${cfg.user}";
- # # };
- #
- # serviceConfig = {
- # Type = "simple";
- # User = cfg.user;
- # ExecStart = ''${server}/bin/server'';
- # Restart = "always";
- # KillMode = "process";
- # };
- # };
- # };
- };
-}
diff --git a/apps/my_app/src/my_app.gleam b/apps/my_app/src/my_app.gleam
@@ -1,136 +0,0 @@
-import decipher
-import gleam/dynamic
-import gleam/int
-import gleam/list
-import gleam/result
-import lustre
-import lustre/attribute
-import lustre/effect.{type Effect}
-import lustre/element.{type Element}
-import lustre/element/html
-import lustre/event
-
-pub fn main() {
- let app = lustre.application(init, update, view)
- let assert Ok(_) = lustre.start(app, "#app", Nil)
-
- Nil
-}
-
-type Model =
- List(#(String, Int))
-
-fn init(_) -> #(Model, Effect(Msg)) {
- let model = []
- let effect = effect.none()
-
- #(model, effect)
-}
-
-type Msg {
- ServerSavedList(Result(Nil, String))
- UserAddedProduct(name: String)
- UserSavedList
- UserUpdatedQuantity(name: String, amount: Int)
-}
-
-fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
- case msg {
- ServerSavedList(_) -> #(model, effect.none())
- UserAddedProduct(_) -> #(model, effect.none())
- UserSavedList -> #(model, effect.none())
- UserUpdatedQuantity(_, _) -> #(model, effect.none())
- }
-}
-
-fn view(model: Model) -> Element(Msg) {
- let styles = [
- #("max-width", "30ch"),
- #("margin", "0 auto"),
- #("display", "flex"),
- #("flex-direction", "column"),
- #("gap", "1em"),
- ]
-
- html.div([attribute.style(styles)], [
- view_grocery_list(model),
- view_new_item(),
- html.div([], [html.button([], [html.text("Sync")])]),
- ])
-}
-
-fn view_new_item() -> Element(Msg) {
- let handle_click = fn(event) {
- let path = ["target", "previousElementSibling", "value"]
-
- event
- |> decipher.at(path, dynamic.string)
- |> result.map(UserAddedProduct)
- }
-
- html.div([], [
- html.input([]),
- html.button([event.on("click", handle_click)], [html.text("Add")]),
- ])
-}
-
-fn view_grocery_list(model: Model) -> Element(Msg) {
- let styles = [#("display", "flex"), #("flex-direction", "column-reverse")]
-
- element.keyed(html.div([attribute.style(styles)], _), {
- use #(name, quantity) <- list.map(model)
- let item = view_grocery_item(name, quantity)
-
- #(name, item)
- })
-}
-
-fn view_grocery_item(name: String, quantity: Int) -> Element(Msg) {
- let handle_input = fn(e) {
- event.value(e)
- |> result.nil_error
- |> result.then(int.parse)
- |> result.map(UserUpdatedQuantity(name, _))
- |> result.replace_error([])
- }
-
- html.div([attribute.style([#("display", "flex"), #("gap", "1em")])], [
- html.span([attribute.style([#("flex", "1")])], [html.text(name)]),
- html.input([
- attribute.style([#("width", "4em")]),
- attribute.type_("number"),
- attribute.value(int.to_string(quantity)),
- attribute.min("0"),
- event.on("input", handle_input),
- ]),
- ])
-}
-// import gleam/erlang/process
-// import mist
-// import my_app/env
-// import my_app/router
-// import wisp
-// import wisp/wisp_mist
-//
-// pub fn main() {
-// // This sets the logger to print INFO level logs, and other sensible defaults
-// // for a web application.
-// wisp.configure_logger()
-//
-// // Here we generate a secret key, but in a real application you would want to
-// // load this from somewhere so that it is not regenerated on every restart.
-// let secret_key_base = wisp.random_string(64)
-// let env = env.get_env()
-//
-// // Start the Mist web server.
-// let assert Ok(_) =
-// wisp_mist.handler(router.handle_request, secret_key_base)
-// |> mist.new
-// |> mist.bind("0.0.0.0")
-// |> mist.port(env.port)
-// |> mist.start_http
-//
-// // The web server runs in new Erlang process, so put this one to sleep while
-// // it works concurrently.
-// process.sleep_forever()
-// }
diff --git a/apps/my_app/src/my_app/env.gleam b/apps/my_app/src/my_app/env.gleam
@@ -1,21 +0,0 @@
-import decode
-import glenv
-
-pub type Env {
- Env(port: Int)
-}
-
-pub fn get_env() {
- let definitions = [#("PORT", glenv.Int)]
-
- let decoder =
- decode.into({
- use port <- decode.parameter
- Env(port:)
- })
- |> decode.field("PORT", decode.int)
-
- let assert Ok(env) = glenv.load(decoder, definitions)
-
- env
-}
diff --git a/apps/my_app/src/my_app/router.gleam b/apps/my_app/src/my_app/router.gleam
@@ -1,31 +0,0 @@
-// import gleam/string_builder
-// import my_app/web
-// import wisp.{type Request, type Response}
-//
-// pub fn handle_request(req: Request) -> Response {
-// use req <- web.middleware(req)
-// let segments = wisp.path_segments(req)
-// case segments {
-// [] -> {
-// asdf(req)
-// }
-// ["api", ..] -> api_routes(req, segments)
-// _ -> wisp.not_found()
-// }
-// }
-//
-// fn asdf(_req: Request) {
-// let body = string_builder.from_string("<h1>Hello, Silas!</h1>")
-// wisp.html_response(body, 200)
-// }
-//
-// fn api_routes(req: Request, segments: List(String)) {
-// case segments {
-// ["api", "games", game_id] -> get_game_state(game_id)
-// _ -> wisp.not_found()
-// }
-// }
-//
-// fn get_game_state() {
-// todo
-// }
diff --git a/apps/my_app/src/my_app/web.gleam b/apps/my_app/src/my_app/web.gleam
@@ -1,32 +0,0 @@
-import wisp
-
-/// The middleware stack that the request handler uses. The stack is itself a
-/// middleware function!
-///
-/// Middleware wrap each other, so the request travels through the stack from
-/// top to bottom until it reaches the request handler, at which point the
-/// response travels back up through the stack.
-///
-/// The middleware used here are the ones that are suitable for use in your
-/// typical web application.
-///
-pub fn middleware(
- req: wisp.Request,
- handle_request: fn(wisp.Request) -> wisp.Response,
-) -> wisp.Response {
- // Permit browsers to simulate methods other than GET and POST using the
- // `_method` query parameter.
- let req = wisp.method_override(req)
-
- // Log information about the request and response.
- use <- wisp.log_request(req)
-
- // Return a default 500 response if the request handler crashes.
- use <- wisp.rescue_crashes
-
- // Rewrite HEAD requests to GET requests and return an empty body.
- use req <- wisp.handle_head(req)
-
- // Handle the request!
- handle_request(req)
-}
diff --git a/apps/my_app/test/my_app_test.gleam b/apps/my_app/test/my_app_test.gleam
@@ -1,12 +0,0 @@
-import gleeunit
-import gleeunit/should
-
-pub fn main() {
- gleeunit.main()
-}
-
-// gleeunit test functions end in `_test`
-pub fn hello_world_test() {
- 1
- |> should.equal(1)
-}
diff --git a/flake.lock b/flake.lock
@@ -5,11 +5,11 @@
"systems": "systems"
},
"locked": {
- "lastModified": 1726560853,
- "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -22,56 +22,40 @@
"inputs": {
"flake-utils": "flake-utils",
"nix-gleam": "nix-gleam",
- "nixos-shell": "nixos-shell",
- "nixpkgs": "nixpkgs_2"
+ "nixpkgs": "nixpkgs"
},
"locked": {
- "lastModified": 1,
- "narHash": "sha256-tAz9G1582wkIoj+xzShFRUdvbyzfZfH1M4TarGsRylg=",
- "path": "./apps/my_app",
- "type": "path"
+ "lastModified": 1736359505,
+ "narHash": "sha256-G880/uKWddTP2BqxkdpH6ntfn4iCgt87ekDedfCHkNM=",
+ "owner": "silasbrack",
+ "repo": "example-todomvc",
+ "rev": "640a500239558cca94640a381420fae59d3ad9f2",
+ "type": "github"
},
"original": {
- "path": "./apps/my_app",
- "type": "path"
+ "owner": "silasbrack",
+ "repo": "example-todomvc",
+ "type": "github"
}
},
"nix-gleam": {
"locked": {
- "lastModified": 1717670865,
- "narHash": "sha256-+dAPiKAwCzlKWtx3aIHXfR6jydh1JyangewqZKJx500=",
- "owner": "arnarg",
+ "lastModified": 1736073571,
+ "narHash": "sha256-Wq0/08n0P0xISxcjAE90k87gjxWzrgVtMITu4E15yII=",
+ "owner": "silasbrack",
"repo": "nix-gleam",
- "rev": "c69abe0e57a01991654d3de63dcd93a8b91b98ff",
+ "rev": "e9bb1634ab8ce7c014c9b89977f8ab2788ffae34",
"type": "github"
},
"original": {
- "owner": "arnarg",
+ "owner": "silasbrack",
"repo": "nix-gleam",
"type": "github"
}
},
"nixos-shell": {
"inputs": {
- "nixpkgs": "nixpkgs"
- },
- "locked": {
- "lastModified": 1728308049,
- "narHash": "sha256-wjAkG8f5orZ4+wgXmEaFAJkVJS6ORqfgM0zzLEvbUNw=",
- "owner": "Mic92",
- "repo": "nixos-shell",
- "rev": "9373ca9522f844a3b8029720c74f340e560e4462",
- "type": "github"
- },
- "original": {
- "owner": "Mic92",
- "repo": "nixos-shell",
- "type": "github"
- }
- },
- "nixos-shell_2": {
- "inputs": {
- "nixpkgs": "nixpkgs_3"
+ "nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1728308049,
@@ -89,17 +73,18 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1628465643,
- "narHash": "sha256-QSNw9bDq9uGUniQQtakRuw4m21Jxugm23SXLVgEV4DM=",
+ "lastModified": 1735834308,
+ "narHash": "sha256-dklw3AXr3OGO4/XT1Tu3Xz9n/we8GctZZ75ZWVqAVhk=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "6ef4f522d63f22b40004319778761040d3197390",
+ "rev": "6df24922a1400241dae323af55f30e4318a6ca65",
"type": "github"
},
"original": {
- "id": "nixpkgs",
+ "owner": "NixOS",
"ref": "nixos-unstable",
- "type": "indirect"
+ "repo": "nixpkgs",
+ "type": "github"
}
},
"nixpkgs-stable": {
@@ -120,18 +105,17 @@
},
"nixpkgs_2": {
"locked": {
- "lastModified": 1728492678,
- "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=",
+ "lastModified": 1628465643,
+ "narHash": "sha256-QSNw9bDq9uGUniQQtakRuw4m21Jxugm23SXLVgEV4DM=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7",
+ "rev": "6ef4f522d63f22b40004319778761040d3197390",
"type": "github"
},
"original": {
- "owner": "NixOS",
+ "id": "nixpkgs",
"ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
+ "type": "indirect"
}
},
"nixpkgs_24_05": {
@@ -150,22 +134,23 @@
"type": "github"
}
},
- "nixpkgs_3": {
+ "nixpkgs_24_11": {
"locked": {
- "lastModified": 1628465643,
- "narHash": "sha256-QSNw9bDq9uGUniQQtakRuw4m21Jxugm23SXLVgEV4DM=",
+ "lastModified": 1736200483,
+ "narHash": "sha256-JO+lFN2HsCwSLMUWXHeOad6QUxOuwe9UOAF/iSl1J4I=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "6ef4f522d63f22b40004319778761040d3197390",
+ "rev": "3f0a8ac25fb674611b98089ca3a5dd6480175751",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "ref": "nixos-unstable",
- "type": "indirect"
+ "owner": "NixOS",
+ "ref": "nixos-24.11",
+ "repo": "nixpkgs",
+ "type": "github"
}
},
- "nixpkgs_4": {
+ "nixpkgs_3": {
"locked": {
"lastModified": 1730531603,
"narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
@@ -181,7 +166,7 @@
"type": "github"
}
},
- "nixpkgs_5": {
+ "nixpkgs_4": {
"locked": {
"lastModified": 1730272153,
"narHash": "sha256-B5WRZYsRlJgwVHIV6DvidFN7VX7Fg9uuwkRW9Ha8z+w=",
@@ -200,15 +185,16 @@
"root": {
"inputs": {
"my_app": "my_app",
- "nixos-shell": "nixos-shell_2",
- "nixpkgs": "nixpkgs_4",
+ "nixos-shell": "nixos-shell",
+ "nixpkgs": "nixpkgs_3",
"nixpkgs_24_05": "nixpkgs_24_05",
+ "nixpkgs_24_11": "nixpkgs_24_11",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
- "nixpkgs": "nixpkgs_5",
+ "nixpkgs": "nixpkgs_4",
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
diff --git a/flake.nix b/flake.nix
@@ -1,10 +1,11 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ nixpkgs_24_11.url = "github:NixOS/nixpkgs/nixos-24.11";
nixpkgs_24_05.url = "github:NixOS/nixpkgs/nixos-24.05";
nixos-shell.url = "github:Mic92/nixos-shell";
sops-nix.url = "github:Mic92/sops-nix";
- my_app.url = "path:./apps/my_app";
+ my_app.url = "github:silasbrack/example-todomvc";
};
outputs =
{
@@ -18,16 +19,16 @@
}:
let
system = "x86_64-linux";
- pkgs = import nixpkgs {
- inherit system;
- };
+ # pkgs = import nixpkgs {
+ # inherit system;
+ # };
pkgs_24_05 = import nixpkgs_24_05 { inherit system; };
- start = pkgs.writeShellScriptBin "start" ''
- set -e
- export QEMU_NET_OPTS="hostfwd=tcp::8080-:80"
- ${pkgs_24_05.nixos-shell}/bin/nixos-shell --flake .
- '';
in
+ # start = pkgs.writeShellScriptBin "start" ''
+ # set -e
+ # export QEMU_NET_OPTS="hostfwd=tcp::8080-:80"
+ # ${pkgs_24_05.nixos-shell}/bin/nixos-shell --flake .
+ # '';
{
nixosConfigurations.default = nixpkgs.lib.nixosSystem {
inherit system;
@@ -60,23 +61,21 @@
sops
wireguard-tools
squawk
+ clang-tools
+ cmake
+ codespell
+ conan
+ cppcheck
+ doxygen
+ gtest
+ lcov
+ vcpkg
+ vcpkg-tool
];
};
nixosConfigurations.vm = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
- # (
- # inputs@{
- # pkgs,
- # lib,
- # config,
- # options,
- # specialArgs,
- # modulesPath,
- # sops,
- # }:
- # import ./nixos/configuration.nix (inputs // { inherit my_app; })
- # )
(
inputs@{
pkgs,
@@ -98,9 +97,9 @@
nixos-shell.nixosModules.nixos-shell
];
};
- packages = {
- inherit start;
- };
- defaultPackage."${system}" = start;
+ # packages = {
+ # inherit start;
+ # };
+ # defaultPackage."${system}" = start;
};
}
diff --git a/nixos/configuration.nix b/nixos/configuration.nix
@@ -17,6 +17,10 @@
zip
unzip
];
+ nix.settings.experimental-features = [
+ "nix-command"
+ "flakes"
+ ];
services.openssh.enable = true;
networking.firewall.allowedTCPPorts = [ 80 ];
@@ -32,6 +36,7 @@
dates = "weekly";
options = "--delete-older-than 30d";
};
+ nix.settings.auto-optimise-store = true;
# Specific
networking.hostName = "nixos-s-1vcpu-512mb-10gb-ams3-01";
@@ -39,12 +44,12 @@
imports = [
(modulesPath + "/virtualisation/digital-ocean-image.nix")
- ./nixos/vpn.nix
- ./apps/my_app/module.nix
+ ./vpn.nix
+ ./my_app.nix
];
# security.pki.certificates = [ (builtins.readFile "/run/secrets/ca_certificate") ];
- sops.defaultSopsFile = ./secrets.yaml;
+ sops.defaultSopsFile = ../secrets.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.server_wireguard_key = {
restartUnits = [ "wg-quick-wg0.service" ];
@@ -63,11 +68,12 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPYO29H4+yDvJbaoUqTg5V6IpD3CMFlB2F47MCzHNpY silasbrack@gmail.com" # Thinkpad (obsolete)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtyTJ7fQ/dF4ObtXcjmjJ3OFtjkYEJdr/szcugDEA3C silasbrack@gmail.com" # Thinkpad
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqHJMc2SCzL50SO9Flfnhn012p1dmp4Iph8lPQ2aoe/ silasbrack@gmail.com" # Desktop
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZ0gNM0od3EE/LL27kYQ/s5MOU7LBNc0pWRWROeINij silas@Lorenzas-MacBook-Pro.local" # Lolo's Macbook Pro
];
};
services.my_app = {
- enable = false;
+ enable = true;
package = my_app.packages."x86_64-linux".default;
port = 8009;
};
@@ -81,48 +87,6 @@
default_type text/plain;
'';
};
- # locations."/chat" = {
- # proxyPass = "http://10.100.0.4:8080";
- # };
};
};
-
- # services.open-webui = {
- # enable = true;
- # };
-
- # # Enable postgres
- # services.postgresql = {
- # enable = true;
- # package = pkgs.postgresql_16;
- # extraPlugins = ps: with ps; [ pgvector ];
- # ensureDatabases = [ "mydb" ];
- # ensureUsers = [
- # {
- # name = "datascientist";
- # }
- # {
- # name = "silas";
- # }
- # ];
- # authentication = pkgs.lib.mkOverride 10 ''
- # #TYPE DATABASE USER AUTH-METHOD OPTIONAL_IDENT_MAP
- # local all all peer map=superuser_map
- # #TYPE DATABASE USER ADDRESS AUTH-METHOD
- # host all all 127.0.0.1/32 trust
- # host all all ::1/128 trust
- # '';
- # identMap = ''
- # # MAPNAME SYSTEM-USERNAME PG-USERNAME
- # superuser_map root postgres
- # superuser_map postgres postgres
- # superuser_map /^(.*)$ \1
- # '';
- # initialScript = pkgs.writeText "backend-initScript" ''
- # GRANT ALL PRIVILEGES ON DATABASE mydb TO silas;
- # '';
- # settings = {
- # port = 44537;
- # };
- # };
}
diff --git a/nixos/my_app.nix b/nixos/my_app.nix
@@ -0,0 +1,197 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+with lib;
+
+let
+ pkg = import ./.;
+ migrations = pkg.migrations;
+ server = pkg.server;
+ cfg = config.services.my_app;
+in
+{
+ options = {
+ services.my_app = {
+ enable = mkEnableOption "My App";
+
+ package = mkOption {
+ defaultText = lib.literalMD "`packages.default` from the my_app flake";
+ };
+
+ environment = mkOption {
+ type = types.enum [
+ "dev"
+ "prod"
+ ];
+ default = "dev";
+ example = "prod";
+ description = "The environment (dev / prod) to deploy as.";
+ };
+
+ user = mkOption {
+ type = types.str;
+ default = "my_app_user";
+ description = "User account under which my app runs.";
+ };
+
+ port = mkOption {
+ type = types.nullOr types.int;
+ default = 3003;
+ example = 8080;
+ description = ''
+ The port to bind my app server to.
+ '';
+ };
+
+ sqlite_file_path = mkOption {
+ type = types.str;
+ default = "/tmp/test.sqlite3";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ networking.firewall.allowedTCPPorts = [ cfg.port ];
+
+ users.groups.${cfg.user} = { };
+ users.users.${cfg.user} = {
+ name = cfg.user;
+ group = cfg.user;
+ description = "My app service user";
+ isSystemUser = true;
+ createHome = false;
+ packages = with pkgs; [
+ gleam
+ erlang_27
+ rebar3
+ inotify-tools
+ nodejs_22
+ sqlite
+ ];
+ };
+
+ systemd.services = {
+ # clone-pokemon-app = {
+ # wantedBy = [ "multi-user.target" ];
+ # description = "Clone Pokemon app.";
+ # after = [ "network.target" ];
+ # serviceConfig = {
+ # Type = "simple";
+ # User = "root";
+ # ExecStart = "";
+ # };
+ # script = ''
+ # TMP_DIR=$(mktemp)
+ # curl --output-dir $TMP_DIR ""
+ # unzip
+ # '';
+ # # script = ''
+ # # rsync
+ # # '';
+ # };
+
+ create-sqlite-db = {
+ wantedBy = [ "multi-user.target" ];
+ description = "Create sqlite database";
+ after = [ "network.target" ];
+ serviceConfig = {
+ Type = "oneshot";
+ User = cfg.user;
+ ExecStart = "${pkgs.sqlite}/bin/sqlite3 ${cfg.sqlite_file_path}";
+ };
+ };
+
+ my_app = {
+ wantedBy = [ "multi-user.target" ];
+ description = "Run my app.";
+ after = [
+ "network.target"
+ "create-sqlite-db.service"
+ ];
+ # after = [ "clone-pokemon-app" ];
+ # requires = [ "clone-pokemon-app" ];
+ serviceConfig = {
+ Type = "simple";
+ User = cfg.user;
+ ExecStart = "${cfg.package}/bin/todomvc";
+ };
+ environment = {
+ PORT = builtins.toString cfg.port;
+ SQLITE_FILE_PATH = cfg.sqlite_file_path;
+ };
+ # path = with pkgs; [ gleam erlang_27 rebar3 ];
+ };
+
+ # postgres-migration = {
+ # description = "Postgres migrations";
+ # wantedBy = [ "multi-user.target" ];
+ # after = [ "postgresql.service" ];
+ # requires = [ "postgresql.service" ];
+ # };
+ };
+
+ # services = mkIf cfg.environment == "dev" {
+ # postgresql = {
+ # enable = true;
+ # enableTCPIP = true;
+ # ensureDatabases = [ cfg.user ];
+ # ensureUsers = [
+ # {
+ # name = cfg.user;
+ # ensurePermissions = {
+ # "DATABASE ${cfg.user}" = "ALL PRIVILEGES";
+ # };
+ # }
+ # ];
+ # authentication = pkgs.lib.mkOverride 10 ''
+ # local sameuser all peer
+ # host sameuser all ::1/32 trust
+ # '';
+ # };
+ # };
+
+ # systemd.services = {
+ #
+ # # db-migration = {
+ # # description = "DB migrations script";
+ # # wantedBy = [ "multi-user.target" ];
+ # # after = [ "postgresql.service" ];
+ # # requires = [ "postgresql.service" ];
+ # #
+ # # environment = {
+ # # DATABASE_URL = "postgres://${cfg.user}@localhost:5432/myapp?sslmode=disable";
+ # # };
+ # #
+ # # serviceConfig = {
+ # # User = cfg.user;
+ # # Type = "oneshot";
+ # # ExecStart = "${pkgs.dbmate}/bin/dbmate -d ${migrations} --no-dump-schema up";
+ # # };
+ # # };
+ #
+ # myapp = {
+ # wantedBy = [ "multi-user.target" ];
+ # description = "Start my app server.";
+ # after = [ "network.target" ];
+ # # requires = [ "db-migration.service" ];
+ #
+ # # environment = {
+ # # APP_PORT = toString cfg.port;
+ # # DATABASE_URL = "postgres:///${cfg.user}";
+ # # };
+ #
+ # serviceConfig = {
+ # Type = "simple";
+ # User = cfg.user;
+ # ExecStart = ''${server}/bin/server'';
+ # Restart = "always";
+ # KillMode = "process";
+ # };
+ # };
+ # };
+ };
+}
diff --git a/nixos/vm.nix b/nixos/vm.nix
@@ -1,7 +1,7 @@
{
pkgs,
self,
- # my_app,
+ my_app,
...
}:
let
@@ -17,7 +17,7 @@ in
{
system.stateVersion = "24.11";
- environment.sessionVariables = rec {
+ environment.sessionVariables = {
PORT = port;
PGUSER = pg_user;
PGHOST = pg_host;
@@ -26,13 +26,13 @@ in
DATABASE_URL = database_url;
};
- # imports = [ ./module.nix ];
+ imports = [ ./my_app.nix ];
- # services.my_app = {
- # enable = true;
- # package = my_app;
- # port = port;
- # };
+ services.my_app = {
+ enable = true;
+ package = my_app;
+ port = port;
+ };
virtualisation.forwardPorts = [
{
from = "host";
@@ -43,8 +43,8 @@ in
services.postgresql = {
enable = true;
- package = pkgs.postgresql_16;
- extraPlugins = ps: with ps; [ pgvector ];
+ package = pkgs.postgresql_17;
+ # extensions = ps: with ps; [ pgvector ];
ensureDatabases = [ "mydb" ];
ensureUsers = [
{
@@ -67,9 +67,9 @@ in
superuser_map postgres postgres
superuser_map /^(.*)$ \1
'';
- # initialScript = pkgs.writeText "backend-initScript" ''
- # GRANT ALL PRIVILEGES ON DATABASE mydb TO silas;
- # '';
+ initialScript = pkgs.writeText "backend-initScript" ''
+ GRANT ALL PRIVILEGES ON DATABASE mydb TO silas;
+ '';
settings = {
port = pkgs.lib.mkForce pg_port;
};
diff --git a/nixos/vpn.nix b/nixos/vpn.nix
@@ -63,6 +63,11 @@
publicKey = "KwQo8pMz0JYHaEV3sbezmpD8jwgbXjaumIKeqWYaeiE=";
allowedIPs = [ "10.100.0.5/32" ];
}
+ {
+ # Lolo's Macbook Pro
+ publicKey = "qmch+NjlcVOxBcOsfwk2SJIcpN58i54131OS9J2yvmM=";
+ allowedIPs = [ "10.100.0.6/32" ];
+ }
];
};
};