commit 7894b41b296c1e5f3f9fa7aa7f38a454d11168ef
parent 9fe4a1c9af14900d8cb009da3d94f2aa092cbbd4
Author: Silas Brack <silasbrack@gmail.com>
Date: Mon, 26 May 2025 18:34:24 +0200
Major changes
Diffstat:
20 files changed, 116 insertions(+), 678 deletions(-)
diff --git a/.github/workflows/nixos.yaml b/.github/workflows/nixos.yaml
@@ -10,46 +10,46 @@ jobs:
nixos:
runs-on: ubuntu-latest
steps:
- - name: Maximize build space
- uses: AdityaGarg8/remove-unwanted-software@v1
- with:
- remove-dotnet: 'true'
- remove-android: 'true'
- remove-haskell: 'true'
-
- - uses: pierotofy/set-swap-space@master
- with:
- swap-size-gb: 10
-
- - uses: actions/checkout@v4
-
- - uses: cachix/install-nix-action@v25
- with:
- nix_path: nixpkgs=channel:nixos-unstable
-
- - uses: DeterminateSystems/magic-nix-cache-action@v2
-
- - name: Build
- run: |
- if [[ "$(nix eval .#nixosConfigurations.nixos-s-1vcpu-512mb-10gb-ams3-01.pkgs.system)" = '"x86_64-linux"' ]]; then
- nix build .#nixosConfigurations.nixos-s-1vcpu-512mb-10gb-ams3-01.config.system.build.toplevel
- fi
-
- - name: Check
- run: nix flake check
-
- - name: Deploy
- if: github.ref == 'refs/heads/main'
- env:
- SSH_KEY: ${{secrets.SSH_KEY}}
- SSH_KNOWN_HOSTS: ${{secrets.SSH_KNOWN_HOSTS}}
- run: |
- # Set up SSH key
- mkdir -p ~/.ssh
- printenv SSH_KEY > ~/.ssh/id_ed25519
- printenv SSH_KNOWN_HOSTS > ~/.ssh/known_hosts
- chmod 600 ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/known_hosts
-
- # Deploy to server
- NIX_SSHOPTS="-i ~/.ssh/id_ed25519 -o UserKnownHostsFile=~/.ssh/known_hosts -t" nix run nixpkgs#nixos-rebuild -- --fast --flake .#nixos-s-1vcpu-512mb-10gb-ams3-01 --target-host root@188.166.127.72 test
+ - name: Maximize build space
+ uses: AdityaGarg8/remove-unwanted-software@v1
+ with:
+ remove-dotnet: "true"
+ remove-android: "true"
+ remove-haskell: "true"
+
+ - uses: pierotofy/set-swap-space@master
+ with:
+ swap-size-gb: 10
+
+ - uses: actions/checkout@v4
+
+ - uses: cachix/install-nix-action@v25
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+
+ # - uses: DeterminateSystems/magic-nix-cache-action@v2
+
+ - name: Build
+ run: |
+ if [[ "$(nix eval .#nixosConfigurations.nixos-s-1vcpu-512mb-10gb-ams3-01.pkgs.system)" = '"x86_64-linux"' ]]; then
+ nix build .#nixosConfigurations.nixos-s-1vcpu-512mb-10gb-ams3-01.config.system.build.toplevel
+ fi
+
+ - name: Check
+ run: nix flake check
+
+ - name: Deploy
+ if: github.ref == 'refs/heads/main'
+ env:
+ SSH_KEY: ${{secrets.SSH_KEY}}
+ SSH_KNOWN_HOSTS: ${{secrets.SSH_KNOWN_HOSTS}}
+ run: |
+ # Set up SSH key
+ mkdir -p ~/.ssh
+ printenv SSH_KEY > ~/.ssh/id_ed25519
+ printenv SSH_KNOWN_HOSTS > ~/.ssh/known_hosts
+ chmod 600 ~/.ssh/id_ed25519
+ chmod 600 ~/.ssh/known_hosts
+
+ # Deploy to server
+ NIX_SSHOPTS="-i ~/.ssh/id_ed25519 -o UserKnownHostsFile=~/.ssh/known_hosts -t" nix run nixpkgs#nixos-rebuild -- --fast --flake .#nixos-s-1vcpu-512mb-10gb-ams3-01 --target-host root@188.166.127.72 test
diff --git a/.sops.yaml b/.sops.yaml
@@ -1,7 +1,6 @@
keys:
- &users:
- &desktop age1s29qgfupgx7mqn9dk2rndp6xh63f5qan8vqa77ve603wd5m9a9rqkpq7re
- - &thinkpad age10h669gfc0yfdrfj4gtnsrpdfvrsh55tn0cj8kuk5t3x5e079dpgs30cuxw
- &hosts:
- &server age1e52v0cr69sycuh59hksx9nk5327vgkemkxqwngd25gtztxhkpups87yd5g
creation_rules:
@@ -9,5 +8,4 @@ creation_rules:
key_groups:
- age:
- *desktop
- - *thinkpad
- *server
diff --git a/CHANGELOG.md b/CHANGELOG.md
diff --git a/LICENSE b/LICENSE
diff --git a/Makefile b/Makefile
@@ -1,74 +1,6 @@
-.PHONY: shell vm deploy
-
-## Open the development environment
-shell:
- nix develop
-
-## Spin up a VM locally to test the application
-vm:
- nixos-shell --flake .
+.PHONY: deploy
## Deploy configuration to production server
deploy:
- nixos-rebuild test --fast --flake .#nixos-s-1vcpu-512mb-10gb-ams3-01 --target-host root@188.166.127.72
-
-#################################################################################
-# Self Documenting Commands #
-#################################################################################
-
-.DEFAULT_GOAL := help
+ nixos-rebuild test --show-trace --fast --flake .#nixos-s-1vcpu-512mb-10gb-ams3-01 --target-host root@188.166.127.72
-# Inspired by <http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html>
-# sed script explained:
-# /^##/:
-# * save line in hold space
-# * purge line
-# * Loop:
-# * append newline + line to hold space
-# * go to next line
-# * if line starts with doc comment, strip comment character off and loop
-# * remove target prerequisites
-# * append hold space (+ newline) to line
-# * replace newline plus comments by `---`
-# * print line
-# Separate expressions are necessary because labels cannot be delimited by
-# semicolon; see <http://stackoverflow.com/a/11799865/1968>
-.PHONY: help
-help:
- @echo "$$(tput bold)Available rules:$$(tput sgr0)"
- @echo
- @sed -n -e "/^## / { \
- h; \
- s/.*//; \
- :doc" \
- -e "H; \
- n; \
- s/^## //; \
- t doc" \
- -e "s/:.*//; \
- G; \
- s/\\n## /---/; \
- s/\\n/ /g; \
- p; \
- }" ${MAKEFILE_LIST} \
- | LC_ALL='C' sort --ignore-case \
- | awk -F '---' \
- -v ncol=$$(tput cols) \
- -v indent=19 \
- -v col_on="$$(tput setaf 6)" \
- -v col_off="$$(tput sgr0)" \
- '{ \
- printf "%s%*s%s ", col_on, -indent, $$1, col_off; \
- n = split($$2, words, " "); \
- line_length = ncol - indent; \
- for (i = 1; i <= n; i++) { \
- line_length -= length(words[i]) + 1; \
- if (line_length <= 0) { \
- line_length = ncol - indent - length(words[i]) - 1; \
- printf "\n%*s ", -indent, " "; \
- } \
- printf "%s ", words[i]; \
- } \
- printf "\n"; \
- }' \
- | more $(shell test $(shell uname) = Darwin && echo '--no-init --raw-control-chars')
diff --git a/README.md b/README.md
@@ -1,2 +1,19 @@
# My Project
+## NixOS Deployment
+- Read Justinas' guide ([part 1](https://justinas.org/nixos-in-the-cloud-step-by-step-part-1) and [part 2](https://justinas.org/nixos-in-the-cloud-step-by-step-part-2))
+
+## Tools
+- Go
+- Postgres (RDS)
+- S3
+- EC2
+- HTMX
+- Docker
+
+## Philosophy
+- Radical simplicity
+- Local first
+- Minimise compile time
+- Minimise dependencies
+
diff --git a/db/mydb/README.md b/db/mydb/README.md
diff --git a/db/mydb/migrations/000.sql b/db/mydb/migrations/000.sql
@@ -1,2 +0,0 @@
-CREATE TABLE migrations ( version BIGINT PRIMARY KEY, applied_at TIMESTAMP WITH time zone default now() );
-
diff --git a/db/mydb/migrations/001.sql b/db/mydb/migrations/001.sql
@@ -1,23 +0,0 @@
-create schema if not exists twitter;
-
-create table if not exists twitter.users (
- id bigint primary key generated always as identity,
- username text unique not null,
- email text unique not null,
- password_hash text not null,
- created_at timestamp with time zone default now()
-);
-
-create table if not exists twitter.tweets (
- id bigint primary key generated always as identity,
- user_id bigint not null references twitter.users (id),
- content text not null,
- created_at timestamp with time zone default now()
-);
-
-create table if not exists twitter.followers (
- follower_id bigint not null references twitter.users (id),
- followee_id bigint not null references twitter.users (id),
- followed_at timestamp with time zone default now(),
- primary key (follower_id, followee_id)
-);
diff --git a/db/mydb/migrations/002.sql b/db/mydb/migrations/002.sql
@@ -1,7 +0,0 @@
-CREATE TABLE IF NOT EXISTS twitter.user_sessions (
- id bigint primary key generated always as identity,
- user_id bigint not null references twitter.users (id),
- token VARCHAR(64) NOT NULL,
- created_at timestamp with time zone default now()
-);
-
diff --git a/db/mydb/migrations/003.sql b/db/mydb/migrations/003.sql
@@ -1,23 +0,0 @@
-CREATE SCHEMA myvec;
-CREATE EXTENSION vector;
-
-CREATE TABLE IF NOT EXISTS myvec.users (id IDENTITY PRIMARY KEY, embedding vector(3));
-INSERT INTO myvec.users (id, embedding) VALUES (10153815, '[1,2,3]'), (10153816, '[4,5,6]');
-
-CREATE TYPE myvec.mood AS ENUM ('sad', 'ok', 'happy');
-CREATE TABLE IF NOT EXISTS myvec.content (id IDENTITY PRIMARY KEY, embedding vector(3), asdf myvec.mood);
-INSERT INTO myvec.content (embedding, asdf) VALUES ('[1,2,3]', 'sad'), ('[4,5,6]', 'happy');
-CREATE INDEX CONCURRENTLY IF NOT EXISTS content_embedding_index ON myvec.content
- USING hnsw (embedding vector_cosine_ops)
- WITH (m = 4, ef_construction = 10);
-CREATE INDEX CONCURRENTLY IF NOT EXISTS content_asdf_index ON myvec.content USING HASH (asdf);
-
--- EXPLAIN
--- SELECT
--- c.id AS content_id
--- FROM
--- myvec.content AS c
--- WHERE c.asdf = 'happy'
--- ORDER BY (c.embedding <=> (SELECT embedding FROM myvec.users WHERE id = 10153815)) ASC
--- LIMIT 5;
-
diff --git a/docs/develop.md b/docs/develop.md
diff --git a/docs/philosophy.md b/docs/philosophy.md
@@ -1,19 +0,0 @@
-# My Project
-
-## NixOS Deployment
-- Read Justinas' guide ([part 1](https://justinas.org/nixos-in-the-cloud-step-by-step-part-1) and [part 2](https://justinas.org/nixos-in-the-cloud-step-by-step-part-2))
-
-## Tools
-- Go
-- Postgres (RDS)
-- S3
-- EC2
-- HTMX
-- Docker
-
-## Philosophy
-- Radical simplicity
-- Local first
-- Minimise compile time
-- Minimise dependencies
-
diff --git a/docs/todo.md b/docs/todo.md
@@ -1,4 +0,0 @@
-# Todo
-- [ x ] Fix compilation of pc in rebar3 such that we provide pc instead of having it download it from the web, for which we need to disable sandbox
-- [ ] Sqlite not being used properly in production
-
diff --git a/flake.lock b/flake.lock
@@ -1,162 +1,28 @@
{
"nodes": {
- "flake-utils": {
- "inputs": {
- "systems": "systems"
- },
- "locked": {
- "lastModified": 1731533236,
- "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "my_app": {
- "inputs": {
- "flake-utils": "flake-utils",
- "nix-gleam": "nix-gleam",
- "nixpkgs": "nixpkgs"
- },
- "locked": {
- "lastModified": 1736449443,
- "narHash": "sha256-g0MrVfFwrTJ9V1WyJqADu2YEvflxZPD5QMhW4xtyKQQ=",
- "owner": "silasbrack",
- "repo": "example-todomvc",
- "rev": "e6794e44bf7b48b1b73367b48abce9ade4b28313",
- "type": "github"
- },
- "original": {
- "owner": "silasbrack",
- "repo": "example-todomvc",
- "type": "github"
- }
- },
- "nix-gleam": {
- "locked": {
- "lastModified": 1736073571,
- "narHash": "sha256-Wq0/08n0P0xISxcjAE90k87gjxWzrgVtMITu4E15yII=",
- "owner": "silasbrack",
- "repo": "nix-gleam",
- "rev": "e9bb1634ab8ce7c014c9b89977f8ab2788ffae34",
- "type": "github"
- },
- "original": {
- "owner": "silasbrack",
- "repo": "nix-gleam",
- "type": "github"
- }
- },
- "nixos-shell": {
- "inputs": {
- "nixpkgs": "nixpkgs_2"
- },
- "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": 1735834308,
- "narHash": "sha256-dklw3AXr3OGO4/XT1Tu3Xz9n/we8GctZZ75ZWVqAVhk=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "6df24922a1400241dae323af55f30e4318a6ca65",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs-stable": {
- "locked": {
- "lastModified": 1730602179,
- "narHash": "sha256-efgLzQAWSzJuCLiCaQUCDu4NudNlHdg2NzGLX5GYaEY=",
+ "lastModified": 1748162331,
+ "narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "3c2f1c4ca372622cb2f9de8016c9a0b1cbd0f37c",
+ "rev": "7c43f080a7f28b2774f3b3f43234ca11661bf334",
"type": "github"
},
"original": {
"owner": "NixOS",
- "ref": "release-24.05",
+ "ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
- "lastModified": 1628465643,
- "narHash": "sha256-QSNw9bDq9uGUniQQtakRuw4m21Jxugm23SXLVgEV4DM=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "6ef4f522d63f22b40004319778761040d3197390",
- "type": "github"
- },
- "original": {
- "id": "nixpkgs",
- "ref": "nixos-unstable",
- "type": "indirect"
- }
- },
- "nixpkgs_24_05": {
- "locked": {
- "lastModified": 1730327045,
- "narHash": "sha256-xKel5kd1AbExymxoIfQ7pgcX6hjw9jCgbiBjiUfSVJ8=",
+ "lastModified": 1744868846,
+ "narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "080166c15633801df010977d9d7474b4a6c549d7",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-24.05",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_3": {
- "locked": {
- "lastModified": 1730531603,
- "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_4": {
- "locked": {
- "lastModified": 1730272153,
- "narHash": "sha256-B5WRZYsRlJgwVHIV6DvidFN7VX7Fg9uuwkRW9Ha8z+w=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "2d2a9ddbe3f2c00747398f3dc9b05f7f2ebb0f53",
+ "rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c",
"type": "github"
},
"original": {
@@ -168,24 +34,20 @@
},
"root": {
"inputs": {
- "my_app": "my_app",
- "nixos-shell": "nixos-shell",
- "nixpkgs": "nixpkgs_3",
- "nixpkgs_24_05": "nixpkgs_24_05",
+ "nixpkgs": "nixpkgs",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
- "nixpkgs": "nixpkgs_4",
- "nixpkgs-stable": "nixpkgs-stable"
+ "nixpkgs": "nixpkgs_2"
},
"locked": {
- "lastModified": 1730605784,
- "narHash": "sha256-1NveNAMLHbxOg0BpBMSVuZ2yW2PpDnZLbZ25wV50PMc=",
+ "lastModified": 1747603214,
+ "narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=",
"owner": "Mic92",
"repo": "sops-nix",
- "rev": "e9b5eef9b51cdf966c76143e13a9476725b2f760",
+ "rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd",
"type": "github"
},
"original": {
@@ -193,21 +55,6 @@
"repo": "sops-nix",
"type": "github"
}
- },
- "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",
diff --git a/flake.nix b/flake.nix
@@ -1,24 +1,16 @@
{
inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- nixpkgs_24_05.url = "github:NixOS/nixpkgs/nixos-24.05";
- nixos-shell.url = "github:Mic92/nixos-shell";
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
sops-nix.url = "github:Mic92/sops-nix";
- my_app.url = "github:silasbrack/example-todomvc";
};
outputs =
{
- self,
nixpkgs,
- nixpkgs_24_05,
- nixos-shell,
sops-nix,
- my_app,
...
}:
let
system = "x86_64-linux";
- pkgs_24_05 = import nixpkgs_24_05 { inherit system; };
in
{
# production configuration
@@ -26,18 +18,7 @@
inherit system;
modules = [
sops-nix.nixosModules.sops
- (
- inputs@{
- pkgs,
- lib,
- config,
- options,
- specialArgs,
- modulesPath,
- sops,
- }:
- import ./nixos/configuration.nix (inputs // { inherit my_app; })
- )
+ (import ./nixos/configuration.nix)
];
};
# development environment (nix develop)
@@ -50,36 +31,10 @@
pkgs.mkShell {
buildInputs = with pkgs; [
curl
- pkgs_24_05.nixos-shell
sops
wireguard-tools
squawk
];
};
- # nixos-shell VM configuration for locally testing apps in an isolated environment
- nixosConfigurations.vm = nixpkgs.lib.nixosSystem {
- inherit system;
- modules = [
- (
- inputs@{
- pkgs,
- lib,
- config,
- options,
- specialArgs,
- modulesPath,
- sops,
- }:
- import ./nixos/vm.nix (
- inputs
- // {
- inherit self;
- my_app = my_app.packages."${system}".default;
- }
- )
- )
- nixos-shell.nixosModules.nixos-shell
- ];
- };
};
}
diff --git a/nixos/configuration.nix b/nixos/configuration.nix
@@ -1,7 +1,6 @@
{
pkgs,
modulesPath,
- my_app,
...
}:
{
@@ -21,7 +20,10 @@
"flakes"
];
services.openssh.enable = true;
- networking.firewall.allowedTCPPorts = [ 80 ];
+ networking.firewall.allowedTCPPorts = [
+ 80
+ 443
+ ];
boot.loader.grub = {
enable = false;
@@ -44,16 +46,14 @@
imports = [
(modulesPath + "/virtualisation/digital-ocean-image.nix")
./vpn.nix
- ./my_app.nix
];
- # security.pki.certificates = [ (builtins.readFile "/run/secrets/ca_certificate") ];
sops.defaultSopsFile = ../secrets.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
+
sops.secrets.server_wireguard_key = {
restartUnits = [ "wg-quick-wg0.service" ];
};
- sops.secrets.ca_certificate = { };
users.users = {
silas = {
@@ -65,28 +65,50 @@
"wheel"
]; # "keys"
openssh.authorizedKeys.keys = [
- "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;
- package = my_app.packages."x86_64-linux".default;
- port = 8009;
+ security.acme = {
+ acceptTerms = true;
+ defaults.email = "silasbrack@gmail.com";
};
-
- sops.secrets.livebook_password_env_variable = {
- owner = "livebook";
+ services.nginx = {
+ enable = true;
+ virtualHosts."freshrss.fnarglebeast.com" = {
+ forceSSL = true;
+ enableACME = true;
+ };
+ virtualHosts."livebook.fnarglebeast.com" = {
+ forceSSL = true;
+ enableACME = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:20123";
+ proxyWebsockets = true; # needed if you need to use WebSocket
+ 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;";
+ };
+ };
};
+
+ sops.secrets.livebook_password_env_file = { };
services.livebook = {
enableUserService = true;
environment = {
LIVEBOOK_PORT = 20123;
+ LIVEBOOK_IFRAME_PORT = 20124;
};
environmentFile = "/run/secrets/livebook_password_env_file";
+ extraPackages = with pkgs; [
+ gcc
+ gnumake
+ ];
};
sops.secrets.freshrss_password = {
@@ -97,5 +119,6 @@
defaultUser = "silas";
passwordFile = "/run/secrets/freshrss_password";
baseUrl = "http://localhost:8080";
+ virtualHost = "freshrss.fnarglebeast.com";
};
}
diff --git a/nixos/my_app.nix b/nixos/my_app.nix
@@ -1,110 +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.
- '';
- };
-
- 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 = {
-
- 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"
- ];
- serviceConfig = {
- Type = "simple";
- User = cfg.user;
- ExecStart = "${cfg.package}/bin/todomvc";
- };
- environment = {
- PORT = builtins.toString cfg.port;
- SQLITE_FILE_PATH = cfg.sqlite_file_path;
- };
- };
-
- };
- };
-}
diff --git a/nixos/vm.nix b/nixos/vm.nix
@@ -1,140 +0,0 @@
-{
- pkgs,
- self,
- my_app,
- ...
-}:
-let
- user = "root";
- port = 8008;
-
- pg_user = "postgres";
- pg_host = "localhost";
- pg_port = 44537;
- pg_database = "mydb";
- database_url = "postgres://${pg_user}@${pg_host}:${toString pg_port}/${pg_database}"; # ?sslmode=full
-in
-{
- system.stateVersion = "24.11";
-
- environment.sessionVariables = {
- PORT = port;
- PGUSER = pg_user;
- PGHOST = pg_host;
- PGPORT = pg_port;
- PGDATABASE = pg_database;
- DATABASE_URL = database_url;
- };
-
- imports = [ ./my_app.nix ];
-
- services.my_app = {
- enable = true;
- package = my_app;
- port = port;
- };
- virtualisation.forwardPorts = [
- {
- from = "host";
- host.port = port;
- guest.port = port;
- }
- ];
-
- services.postgresql = {
- enable = true;
- package = pkgs.postgresql_17;
- # extensions = 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 = pkgs.lib.mkForce pg_port;
- };
- };
-
- systemd.services = {
- db-migration = {
- description = "DB migrations script";
- wantedBy = [ "multi-user.target" ];
- after = [ "postgresql.service" ];
- requires = [ "postgresql.service" ];
-
- environment = {
- DATABASE_URL = database_url;
- };
-
- script = ''
- MIGRATIONS_FOLDER=${self}/db/mydb/migrations;
- PSQL=/run/current-system/sw/bin/psql
-
- MIGRATIONS_TABLE_EXISTS=$($PSQL $DATABASE_URL -AXqtc "SELECT EXISTS(SELECT * FROM information_schema.tables WHERE table_schema LIKE 'public' AND table_type LIKE 'BASE TABLE' AND table_name = 'migrations');")
- >&2 echo "MIGRATIONS_TABLE_EXISTS=$MIGRATIONS_TABLE_EXISTS"
- LATEST_VERSION=$(
- if [ $MIGRATIONS_TABLE_EXISTS = 't' ]; then
- $PSQL $DATABASE_URL -AXqtc 'SELECT MAX(version) FROM migrations;'
- else
- echo "-1"
- fi
- );
- >&2 echo "LATEST_VERSION=$LATEST_VERSION"
- MAX_VERSION=$(ls $MIGRATIONS_FOLDER | sort -n | tail -1 | xargs -I _ basename _ .sql | sed -r 's/0*([0-9]*)/\1/');
- >&2 echo "MAX_VERSION=$MAX_VERSION"
-
- for VERSION in $(seq -f "%03g" $(($LATEST_VERSION + 1)) $MAX_VERSION); do
- >&2 echo "Running migration for file $MIGRATIONS_FOLDER/$VERSION.sql"
- $PSQL $DATABASE_URL --single-transaction -a -f $MIGRATIONS_FOLDER/$VERSION.sql \
- && $PSQL $DATABASE_URL -a -c 'INSERT INTO migrations (version) VALUES ('$(($VERSION))');' \
- || exit 1
- done
- '';
- serviceConfig = {
- User = user;
- Type = "oneshot";
- };
- };
-
- # 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/secrets.yaml b/secrets.yaml
@@ -1,12 +1,7 @@
server_wireguard_key: ENC[AES256_GCM,data:21uPlSLnedqeXxIjS+HhJ0lAD6T/diIkjAAhbrB/a6jSVST9u8YTXWNgZ8w=,iv:pOGONrRuUNS8obDdw6GvEkCO7a+Ym5kOgLH6u+P9QQ0=,tag:cAcDTQ5pU8fV5hDzx+d+5A==,type:str]
-ca_certificate: ENC[AES256_GCM,data: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,iv:VQYKe9GilKIRqDEVWKZtls1k+CfaEi8YhdXVKb9nh78=,tag:d4OYBzgyKA5KDkj9gz9CXg==,type:str]
freshrss_password: ENC[AES256_GCM,data:oK/KbYmiux2YdXtNiTVJQUWO5+2K2eDx,iv:v3+cOq6oQGXcp22jDmncoJJFbqF/KZCh9CjcsDTrA50=,tag:aIFGAcfcfkT0QrIsO6lIrQ==,type:str]
-livebook_password_env_file: ENC[AES256_GCM,data:2g2sGNglR+v0MtRnx5iEh22fydW2yNSfS/5r+sA6mPoWUJEzR4dCL9X1dgzSQKxluuNpcYOvRUxRo3JYwD/lmR197nRAXoNOathO9DzuzEROYrY=,iv:cbVhrRJBByHBJil4zMDrQf/yD64nJJS8MbztS4lFKMM=,tag:430gH91+ej1jADhYM7br4Q==,type:str]
+livebook_password_env_file: ENC[AES256_GCM,data:aic46wuBFngu24R3U6sGXNuB8zQSj6YWIum8szgt6UDJ3PZpYlCT6yNEEZ/NlQ87C4NUELWPE402qZ/hPqjW0X0HcEpXIBnQ4ZcO8uoI0zbMeLFMgGw3+27Uq3dyfMxfCWfBe/VHGBK1i8hKEZ0xzIdPktyTF/bZUnsXXgKvoJtJToWXMbX0/g==,iv:zhZvELSPfIcjAu/ZDastRCJJXg7z5Q0qdPA+N3UqBjg=,tag:QfdwD/hpb/6zc6SiNWj/8A==,type:str]
sops:
- kms: []
- gcp_kms: []
- azure_kv: []
- hc_vault: []
age:
- recipient: age1s29qgfupgx7mqn9dk2rndp6xh63f5qan8vqa77ve603wd5m9a9rqkpq7re
enc: |
@@ -35,8 +30,7 @@ sops:
VTVIMjJSaGVRY3hYbmhzUmFiaCtxVUEKmGFgyEVxF0s8UqrbV9vpVonzEqMdx/9z
yeAc9I9fdMiakISPvkh9Jkexc4duFS1noGTIAXPfCEriIupol2MVvw==
-----END AGE ENCRYPTED FILE-----
- lastmodified: "2025-05-25T09:39:51Z"
- mac: ENC[AES256_GCM,data:Gsf0ILlT4TA631JIwZuSXFWYPx/sKSaCBqBPrePBrUZdyMTJw16/hnhAuEZPD0k92TduJilexWc7tfrSKF1/Fqh9Yd8H3cebougnKZLEO6jmGO0g+ykc0CPlET21mZLbLJZ7blZ+n4bXy30YTe6zzNvsNidXKKtJwDAfqCjD8Mg=,iv:HtMe7U+CHWEWfP/yl7We/nZpvtcl98/niqFO/v2fvsE=,tag:h02u+K8ht20ZVMFt6msH8A==,type:str]
- pgp: []
+ lastmodified: "2025-05-26T15:57:13Z"
+ mac: ENC[AES256_GCM,data:eNWuQvY/0SNoX57EzSm47Og12oQl5eD5KPUH5rSKn5qXhr+8FYEOVwgN5/8wsODT3yZUGBSd/dCwdB6NeY48PfX5gVSC0gfBL6RwdzQhgGXhQ57nAWOGJ2x+J6vHXnEddlmv5yWbNhM2YQzS1slF4LAL/c7pv6S2n51yo4DUuO4=,iv:SZZ7SleiCD0f+9IZ5K6YDiaWcIZ9QfAzQj6tDQo/NEo=,tag:Q7Q/gPOyYZfyi8rZASPLNA==,type:str]
unencrypted_suffix: _unencrypted
- version: 3.9.1
+ version: 3.10.2