Compare commits

...

6 Commits

Author SHA1 Message Date
m3tam3re
c2ca0dfe27 +gitignore 2025-04-03 10:34:40 +02:00
m3tam3re
811f643410 +gitignore 2025-04-03 10:31:47 +02:00
m3tam3re
851ffc4ed3 +version file 2025-04-03 10:24:42 +02:00
m3tam3re
e653e1640a +version file 2025-04-03 09:42:57 +02:00
m3tam3re
8b7635d56a +gitignore 2025-04-03 09:28:07 +02:00
m3tam3re
00e16adb89 structure changes to flake 2025-03-28 10:13:26 +01:00
9 changed files with 172 additions and 210 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
config.json
starter/config.json

27
flake.lock generated Normal file
View File

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1741379970,
"narHash": "sha256-Wh7esNh7G24qYleLvgOSY/7HlDUzWaL/n4qzlBePpiw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "36fd87baa9083f34f7f5027900b62ee6d09b1f2f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

View File

@ -1,197 +1,94 @@
{
config,
lib,
pkgs,
self,
...
}:
# Read configuration from JSON
let
jsonConfig = builtins.fromJSON (builtins.readFile ./config.json);
in {
imports = [
./disko-config.nix
./hardware-configuration.nix
];
# Enable flakes and nix commands
nix = {
settings = {
experimental-features = ["nix-command" "flakes"];
# Enable automatic garbage collection
auto-optimise-store = true;
customServicesDir = ./custom-services;
customServicesExists = builtins.pathExists customServicesDir;
customServices =
if customServicesExists
then
map
(name: ./custom-services + "/${name}")
(builtins.filter
(name: lib.hasSuffix ".nix" name)
(builtins.attrNames (builtins.readDir customServicesDir)))
else [];
in {
imports =
[
./disko-config.nix
]
++ customServices;
options.nixosConfig.flake = lib.mkOption {
type = lib.types.path;
description = "Path to the current flake configuration";
};
config = {
nix.settings = {
trusted-users = [jsonConfig.username];
};
# Automatic cleanup of old generations
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
# Set the flake path
nixosConfig.flake = self;
# Activation script to save the configuration
system.activationScripts.saveFlakeConfig = {
deps = [];
text = ''
rm -rf /etc/nixos/current-systemconfig
mkdir -p /etc/nixos/current-systemconfig
cp -rf ${config.nixosConfig.flake}/* /etc/nixos/current-systemconfig/
cd /etc/nixos/current-systemconfig
chown -R ${jsonConfig.username}:users /etc/nixos/current-systemconfig
chmod -R u=rwX,g=rX,o=rX /etc/nixos/current-systemconfig
'';
};
};
# Boot configuration
boot.loader.grub = {
enable = true;
devices = [jsonConfig.rootDevice];
efiSupport = true;
efiInstallAsRemovable = true;
};
# Networking
networking = {
firewall = {
services.selfHostPlaybook = {
enable = true;
# Only allow necessary ports
allowedTCPPorts = [80 443 2222]; # HTTP, HTTPS, and SSH
tier = "starter"; # This determines which services are enabled
};
};
environment.etc = {
environment-files = {
source = pkgs.copyPathToStore ./env;
# Networking
networking = {
firewall = {
enable = true;
# Only allow necessary ports
allowedTCPPorts = [80 443 2222]; # HTTP, HTTPS, and SSH
};
};
};
# System packages
environment.systemPackages = with pkgs; [
# System utilities
neovim
git
# Docker tools
docker
docker-compose
];
environment.etc = {
environment-files = {
source = ./env;
};
};
# User configuration
users.users.${jsonConfig.username} = {
isNormalUser = true;
extraGroups = ["wheel" "docker"];
hashedPassword = jsonConfig.hashedPassword;
openssh.authorizedKeys.keys = [jsonConfig.sshKey];
# Set default shell to bash
shell = pkgs.bash;
};
# Enable Docker with recommended settings
virtualisation.docker = {
enable = true;
# Enable docker daemon to start on boot
enableOnBoot = true;
# Use overlay2 storage driver
storageDriver = "overlay2";
# Enable live restore
liveRestore = true;
};
# Services configuration
services = {
# SSH server configuration
openssh = {
programs.git = {
enable = true;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
# Additional security settings
MaxAuthTries = 3;
LoginGraceTime = "30s";
};
ports = [2222];
};
# Caddy configuration with security headers
caddy = {
enable = true;
virtualHosts = {
"${jsonConfig.domains.portainer}" = {
extraConfig = ''
reverse_proxy localhost:9000
header {
# Security headers
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
'';
};
"${jsonConfig.domains.n8n}" = {
extraConfig = ''
reverse_proxy localhost:5678
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
'';
};
"${jsonConfig.domains.baserow}" = {
extraConfig = ''
reverse_proxy localhost:3000
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
'';
};
config = {
user.name = jsonConfig.username;
user.email = "${jsonConfig.username}@nixos";
safe.directory = "/etc/nixos/current-systemconfig";
};
};
};
# User configuration
users.users.${jsonConfig.username} = {
isNormalUser = true;
extraGroups = ["wheel" "docker"];
hashedPassword = jsonConfig.hashedPassword;
openssh.authorizedKeys.keys = [jsonConfig.sshKey];
# Set default shell to bash
shell = pkgs.bash;
};
# Container configurations
virtualisation.oci-containers = {
backend = "docker";
containers = {
"portainer" = {
image = "docker.io/portainer/portainer-ce:latest";
ports = ["127.0.0.1:9000:9000"];
volumes = [
"/etc/localtime:/etc/localtime:ro"
"/var/run/docker.sock:/var/run/docker.sock:ro"
"portainer_data:/data"
];
extraOptions = [
"--network=web"
];
};
"n8n" = {
image = "docker.io/n8nio/n8n:latest";
environmentFiles = ["/etc/environment-files/n8n.env"];
ports = ["127.0.0.1:5678:5678"];
volumes = ["n8n_data:/home/node/.n8n"];
extraOptions = ["--network=web"];
};
"baserow" = {
image = "docker.io/baserow/baserow:latest";
environmentFiles = ["/etc/environment-files/baserow.env"];
ports = ["127.0.0.1:3000:80"];
volumes = ["baserow_data:/baserow/data"];
extraOptions = ["--network=web"];
};
};
};
systemd.services.docker-network-web = {
description = "Create Docker Network Web";
requires = ["docker.service"];
after = ["docker.service"];
wantedBy = ["multi-user.target"];
# Run on startup if network doesn't exist
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
if ! /run/current-system/sw/bin/docker network ls | grep -q 'web'; then
/run/current-system/sw/bin/docker network create web
fi
'';
};
# System state version (do not change)
system.stateVersion = "24.11";
}

1
starter/env/n8n.env vendored
View File

@ -1,3 +1,4 @@
N8N_HOST=N8N_DOMAIN
WEBHOOK_URL=https://N8N_DOMAIN
NODE_ENV=production
N8N_ENCRYPTION_KEY=changeme

56
starter/flake.lock generated
View File

@ -1,5 +1,25 @@
{
"nodes": {
"base-config": {
"inputs": {
"nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable"
},
"locked": {
"lastModified": 1741872348,
"narHash": "sha256-4d0S59c/rR5lcfqeqw3z+k4FlDwyci6dwrwMPgKuO/g=",
"ref": "stable",
"rev": "50af8d01fb5d5d5616bd1d5c38ced9946f863ca4",
"revCount": 6,
"type": "git",
"url": "https://code.m3tam3re.com/m3tam3re/self-host-playbook-base"
},
"original": {
"ref": "stable",
"type": "git",
"url": "https://code.m3tam3re.com/m3tam3re/self-host-playbook-base"
}
},
"disko": {
"inputs": {
"nixpkgs": [
@ -7,11 +27,11 @@
]
},
"locked": {
"lastModified": 1739760714,
"narHash": "sha256-SaGuzIQUTC2UPwX0aTm9W4aSEUcq3h6yZbi30piej2U=",
"lastModified": 1741786315,
"narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=",
"owner": "nix-community",
"repo": "disko",
"rev": "be1e4321c9fb3a4bc2c061dafcdb424937a74dad",
"rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de",
"type": "github"
},
"original": {
@ -22,24 +42,44 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1739580444,
"narHash": "sha256-+/bSz4EAVbqz8/HsIGLroF8aNaO8bLRL7WfACN+24g4=",
"lastModified": 1741600792,
"narHash": "sha256-yfDy6chHcM7pXpMF4wycuuV+ILSTG486Z/vLx/Bdi6Y=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8bb37161a0488b89830168b81c48aed11569cb93",
"rev": "ebe2788eafd539477f83775ef93c3c7e244421d3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1741708242,
"narHash": "sha256-cNRqdQD4sZpN7JLqxVOze4+WsWTmv2DGH0wNCOVwrWc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b62d2a95c72fb068aecd374a7262b37ed92df82b",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b62d2a95c72fb068aecd374a7262b37ed92df82b",
"type": "github"
}
},
"root": {
"inputs": {
"base-config": "base-config",
"disko": "disko",
"nixpkgs": "nixpkgs"
"nixpkgs": [
"base-config",
"nixpkgs"
]
}
}
},

View File

@ -2,7 +2,14 @@
description = "Self-hosted server setup with Portainer, n8n, and Baserow";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
base-config = {
# url = "path:/home/m3tam3re/p/nix/self-host-playbook-base";
url = "git+https://code.m3tam3re.com/m3tam3re/self-host-playbook-base?ref=stable";
};
nixpkgs = {
url = "github:NixOS/nixpkgs/nixos-24.11";
follows = "base-config/nixpkgs";
};
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
@ -11,15 +18,23 @@
outputs = {
self,
base-config,
nixpkgs,
...
} @ inputs: {
nixosConfigurations.server = nixpkgs.lib.nixosSystem {
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
(base-config.nixosModules.default {
tier = "starter";
jsonConfig = builtins.fromJSON (builtins.readFile ./config.json);
}) # Pass tier here
inputs.disko.nixosModules.disko
./configuration.nix
];
specialArgs = {
inherit self;
};
};
};
}

View File

@ -1,26 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
lib,
modulesPath,
...
}: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

8
starter/version.json Normal file
View File

@ -0,0 +1,8 @@
{
"version": "0.1.0",
"minCompatibleVersion": "0.0.0",
"updateUrl": "https://code.m3tam3re.com/m3tam3re/self-host-playbook",
"changelog": {
"0.1.0": ["Management CLI", "Flake rework"]
}
}