tofu workflow
This commit is contained in:
parent
6972897c46
commit
acc0dac234
26 changed files with 674 additions and 156 deletions
44
.forgejo/workflows/tofu.yml
Normal file
44
.forgejo/workflows/tofu.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
apply:
|
||||
name: OpenTofu
|
||||
# Ensure 'nixos-latest' runner has Docker, SSH client, and basic Nix tools installed.
|
||||
# It seems it already does.
|
||||
runs-on: nixos-latest
|
||||
env:
|
||||
PROXMOX_API_URL: https://192.168.1.205:8006/api2/json
|
||||
# PROXMOX_API_TOKEN_ID: nixos-builder.lab
|
||||
# PROXMOX_API_TOKEN_SECRET: nixos-builder.lab
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
nix-env -iA nixpkgs.nodejs
|
||||
nix-env -iA nixpkgs.openssh
|
||||
nix-env -iA nixpkgs.opentofu
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: OpenTofu fmt
|
||||
id: fmt
|
||||
run: tofu fmt -check
|
||||
continue-on-error: true
|
||||
|
||||
- name: OpenTofu Init
|
||||
id: init
|
||||
run: tofu init
|
||||
working-directory: /infrastructure/proxmox
|
||||
|
||||
- name: OpenTofu Validate
|
||||
id: validate
|
||||
run: tofu validate -no-color
|
||||
working-directory: /infrastructure/proxmox
|
||||
|
||||
- name: OpenTofu Plan
|
||||
id: plan
|
||||
run: tofu plan -no-color
|
||||
working-directory: /infrastructure/proxmox
|
||||
continue-on-error: true
|
||||
17
flake.lock
generated
17
flake.lock
generated
|
|
@ -186,6 +186,22 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1752480373,
|
||||
"narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1752624097,
|
||||
|
|
@ -205,6 +221,7 @@
|
|||
"inputs": {
|
||||
"colmena": "colmena",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"simple-nixos-mailserver": "simple-nixos-mailserver",
|
||||
"sops-nix": "sops-nix"
|
||||
}
|
||||
|
|
|
|||
68
flake.nix
68
flake.nix
|
|
@ -2,17 +2,18 @@
|
|||
description = "Declarative NixOS HomeLab";
|
||||
|
||||
inputs = {
|
||||
# Nixpkgs
|
||||
nixpkgs.url = "github:nixos/nixpkgs";
|
||||
# You can access packages and modules from different nixpkgs revs
|
||||
# at the same time. Here's an working example:
|
||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
# Also see the 'unstable-packages' overlay at 'overlays/default.nix'.
|
||||
# systems.url = "github:nix-systems/default";
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
simple-nixos-mailserver = {
|
||||
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
|
||||
simple-nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs";
|
||||
# home-manager = {
|
||||
# url = "home-manager";
|
||||
# inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
|
@ -30,11 +31,56 @@
|
|||
simple-nixos-mailserver,
|
||||
...
|
||||
} @ inputs: let
|
||||
inherit (self) outputs;
|
||||
# Supported systems for your flake packages, shell, etc.
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
];
|
||||
# This is a function that generates an attribute by calling a function you
|
||||
# pass to it, with each system as an argument
|
||||
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||
in {
|
||||
# Custom packages
|
||||
# Accessible through 'nix build', 'nix shell', etc
|
||||
packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});
|
||||
|
||||
# Formatter for your nix files, available through 'nix fmt'
|
||||
# Other options beside 'alejandra' include 'nixpkgs-fmt'
|
||||
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
|
||||
# Custom packages and modifications, exported as overlays
|
||||
overlays = import ./overlays {inherit inputs;};
|
||||
|
||||
# Reusable nixos modules
|
||||
nixosModules = import ./modules/nixos;
|
||||
|
||||
colmenaHive = colmena.lib.makeHive self.outputs.colmena;
|
||||
colmena = {
|
||||
meta = {
|
||||
nixpkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
overlays = [
|
||||
outputs.overlays.additions
|
||||
outputs.overlays.modifications
|
||||
outputs.overlays.unstable-packages
|
||||
|
||||
colmena.overlays.default
|
||||
];
|
||||
in {
|
||||
colmenaHive = colmena.lib.makeHive self.outputs.colmena;
|
||||
colmena = (import ./hive.nix) (inputs // {inherit overlays;});
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs outputs;
|
||||
};
|
||||
};
|
||||
|
||||
defaults = import ./machines/_default/configuration.nix;
|
||||
|
||||
sandbox = import ./machines/sandbox/configuration.nix;
|
||||
auth = import ./machines/auth/configuration.nix;
|
||||
mail = import ./machines/mail/configuration.nix;
|
||||
monitor = import ./machines/monitor/configuration.nix;
|
||||
photos = import ./machines/photos/configuration.nix;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
34
hive.nix
34
hive.nix
|
|
@ -4,36 +4,9 @@ inputs @ {
|
|||
sops-nix,
|
||||
simple-nixos-mailserver,
|
||||
# home-manager,
|
||||
overlays,
|
||||
outputs,
|
||||
...
|
||||
}: {
|
||||
meta = {
|
||||
nixpkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
};
|
||||
specialArgs.flakeInputs = inputs;
|
||||
};
|
||||
|
||||
defaults = {
|
||||
lib,
|
||||
name,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./machines/_default
|
||||
./machines/modules
|
||||
sops-nix.nixosModules.sops
|
||||
# home-manager.nixosModules.home-manager
|
||||
];
|
||||
nixpkgs = {
|
||||
inherit overlays;
|
||||
system = lib.mkDefault "x86_64-linux";
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
deployment.tags = [config.nixpkgs.system name];
|
||||
};
|
||||
|
||||
sandbox = {name, ...}: {
|
||||
imports = [./machines/${name}/definition.nix];
|
||||
deployment.tags = ["sandbox"];
|
||||
|
|
@ -56,4 +29,9 @@ inputs @ {
|
|||
];
|
||||
deployment.tags = ["mail"];
|
||||
};
|
||||
|
||||
photos = {name, ...}: {
|
||||
imports = [./machines/${name}/definition.nix];
|
||||
deployment.tags = ["ente"];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
{
|
||||
lib,
|
||||
name,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./common_config.nix
|
||||
../modules
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
# inputs.home-manager.nixosModules.home-manager
|
||||
];
|
||||
|
||||
networking.hostName = name;
|
||||
|
|
@ -13,7 +18,7 @@
|
|||
replaceUnknownProfiles = lib.mkDefault true;
|
||||
buildOnTarget = lib.mkDefault false;
|
||||
targetHost = lib.mkDefault "${name}.lab";
|
||||
tags = lib.mkDefault ["homelab"];
|
||||
tags = lib.mkDefault [config.nixpkgs.system name "homelab"];
|
||||
};
|
||||
|
||||
sops = {
|
||||
|
|
@ -21,20 +26,6 @@
|
|||
defaultSopsFile = ../../secrets/secrets.yaml;
|
||||
};
|
||||
|
||||
# home-manager = {
|
||||
# useGlobalPkgs = true;
|
||||
# useUserPackages = true;
|
||||
# users.cottand = {
|
||||
# imports = with flakeInputs.cottand.homeManagerModules; [cli];
|
||||
# home.stateVersion = "22.11";
|
||||
# };
|
||||
# users.root = {
|
||||
# imports = with flakeInputs.cottand.homeManagerModules; [cli];
|
||||
# home.stateVersion = "22.11";
|
||||
# };
|
||||
# };
|
||||
|
||||
# consulNode.enable = lib.mkDefault true;
|
||||
nodeExporter.enable = lib.mkDefault true;
|
||||
journalLog.enable = lib.mkDefault true;
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
{
|
||||
"id": "forgejo",
|
||||
"email": "forgejo@procopius.dk",
|
||||
"email": "git@procopius.dk",
|
||||
"password": "${config.sops.placeholder."service_accounts/forgejo/password"}",
|
||||
"displayName": "Forgejo",
|
||||
"groups": [
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@
|
|||
./redis.nix
|
||||
];
|
||||
|
||||
deployment.tags = ["authelia" "sso" "ldap" "lldap"];
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
11
machines/mail/configuration.nix
Normal file
11
machines/mail/configuration.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{inputs, ...}: {
|
||||
imports = [
|
||||
./mailserver.nix
|
||||
./networking.nix
|
||||
inputs.simple-nixos-mailserver.nixosModule
|
||||
];
|
||||
|
||||
deployment.tags = ["mail"];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
imports = [
|
||||
./mailserver.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
interfaces.eth0.ipv4.addresses = [
|
||||
{
|
||||
|
|
@ -13,7 +9,4 @@
|
|||
nameservers = ["192.168.1.53"];
|
||||
defaultGateway = "192.168.1.1";
|
||||
};
|
||||
deployment.targetHost = "192.168.1.25";
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
|
|
@ -10,5 +10,7 @@
|
|||
./jellyfin-exporter.nix
|
||||
];
|
||||
|
||||
deployment.tags = ["grafana" "prometheus"];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
10
machines/photos/configuration.nix
Normal file
10
machines/photos/configuration.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{outputs, ...}: {
|
||||
imports = [
|
||||
outputs.nixosModules.ente
|
||||
./ente.nix
|
||||
];
|
||||
|
||||
deployment.tags = ["ente"];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
25
machines/photos/ente.nix
Normal file
25
machines/photos/ente.nix
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
services.ente.api = {
|
||||
enable = true;
|
||||
enableLocalDB = true;
|
||||
|
||||
domain = "ente-v2.procopius.dk";
|
||||
settings = {
|
||||
# apps = {
|
||||
# accounts = "https://accounts.procopius.dk";
|
||||
# cast = "https://cast.procopius.dk";
|
||||
# public-albums = "https://albums.procopius.dk";
|
||||
# };
|
||||
};
|
||||
};
|
||||
services.ente.web = {
|
||||
enable = true;
|
||||
domains = {
|
||||
api = "ente-v2.procopius.dk";
|
||||
accounts = "accounts.procopius.dk";
|
||||
albums = "albums.procopius.dk";
|
||||
cast = "cast.procopius.dk";
|
||||
photos = "photos.procopius.dk";
|
||||
};
|
||||
};
|
||||
}
|
||||
6
machines/photos/minio.nix
Normal file
6
machines/photos/minio.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
services.minio = {
|
||||
enable = true;
|
||||
rootCredentialsFile = "/etc/nixos/minio-root-credentials";
|
||||
};
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
{
|
||||
deployment.tags = ["sandbox"];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
3
modules/nixos/default.nix
Normal file
3
modules/nixos/default.nix
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
ente = import ./ente.nix;
|
||||
}
|
||||
351
modules/nixos/ente.nix
Normal file
351
modules/nixos/ente.nix
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
getExe
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optional
|
||||
types
|
||||
;
|
||||
|
||||
cfgApi = config.services.ente.api;
|
||||
cfgWeb = config.services.ente.web;
|
||||
|
||||
webPackage = enteApp:
|
||||
cfgWeb.package.override {
|
||||
inherit enteApp;
|
||||
enteMainUrl = "https://${cfgWeb.domains.photos}";
|
||||
extraBuildEnv = {
|
||||
NEXT_PUBLIC_ENTE_ENDPOINT = "https://${cfgWeb.domains.api}";
|
||||
NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT = "https://${cfgWeb.domains.albums}";
|
||||
NEXT_TELEMETRY_DISABLED = "1";
|
||||
};
|
||||
};
|
||||
|
||||
defaultUser = "ente";
|
||||
defaultGroup = "ente";
|
||||
dataDir = "/var/lib/ente";
|
||||
|
||||
yamlFormat = pkgs.formats.yaml {};
|
||||
in {
|
||||
options.services.ente = {
|
||||
web = {
|
||||
enable = mkEnableOption "Ente web frontend (Photos, Albums)";
|
||||
package = mkPackageOption pkgs "ente-web" {};
|
||||
|
||||
domains = {
|
||||
api = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The domain under which the api is served. This will NOT serve the api itself,
|
||||
but is a required setting to host the frontends! This will automatically be set
|
||||
for you if you enable both the api server and web frontends.
|
||||
'';
|
||||
};
|
||||
|
||||
accounts = mkOption {
|
||||
type = types.str;
|
||||
description = "The domain under which the accounts frontend will be served.";
|
||||
};
|
||||
|
||||
cast = mkOption {
|
||||
type = types.str;
|
||||
description = "The domain under which the cast frontend will be served.";
|
||||
};
|
||||
|
||||
albums = mkOption {
|
||||
type = types.str;
|
||||
description = "The domain under which the albums frontend will be served.";
|
||||
};
|
||||
|
||||
photos = mkOption {
|
||||
type = types.str;
|
||||
description = "The domain under which the photos frontend will be served.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
api = {
|
||||
enable = mkEnableOption "Museum (API server for ente.io)";
|
||||
package = mkPackageOption pkgs "museum" {};
|
||||
nginx.enable = mkEnableOption "nginx proxy for the API server";
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUser;
|
||||
description = "User under which museum runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = defaultGroup;
|
||||
description = "Group under which museum runs.";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "The domain under which the api will be served.";
|
||||
};
|
||||
|
||||
enableLocalDB = mkEnableOption "the automatic creation of a local postgres database for museum.";
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
Museum yaml configuration. Refer to upstream [local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml) for more information.
|
||||
You can specify secret values in this configuration by setting `somevalue._secret = "/path/to/file"` instead of setting `somevalue` directly.
|
||||
'';
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
freeformType = yamlFormat.type;
|
||||
options = {
|
||||
apps = {
|
||||
public-albums = mkOption {
|
||||
type = types.str;
|
||||
default = "https://albums.ente.io";
|
||||
description = ''
|
||||
If you're running a self hosted instance and wish to serve public links,
|
||||
set this to the URL where your albums web app is running.
|
||||
'';
|
||||
};
|
||||
|
||||
cast = mkOption {
|
||||
type = types.str;
|
||||
default = "https://cast.ente.io";
|
||||
description = ''
|
||||
Set this to the URL where your cast page is running.
|
||||
This is for browser and chromecast casting support.
|
||||
'';
|
||||
};
|
||||
|
||||
accounts = mkOption {
|
||||
type = types.str;
|
||||
default = "https://accounts.ente.io";
|
||||
description = ''
|
||||
Set this to the URL where your accounts page is running.
|
||||
This is primarily for passkey support.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
db = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = "The database host";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5432;
|
||||
description = "The database port";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = "The database name";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = "The database user";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfgApi.enable {
|
||||
services.postgresql = mkIf cfgApi.enableLocalDB {
|
||||
enable = true;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "ente";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
ensureDatabases = ["ente"];
|
||||
};
|
||||
|
||||
services.ente.web.domains.api = mkIf cfgWeb.enable cfgApi.domain;
|
||||
services.ente.api.settings = {
|
||||
log-file = mkDefault "";
|
||||
db = mkIf cfgApi.enableLocalDB {
|
||||
host = "/run/postgresql";
|
||||
port = 5432;
|
||||
name = "ente";
|
||||
user = "ente";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.ente = {
|
||||
description = "Ente.io Museum API Server";
|
||||
after = ["network.target"] ++ optional cfgApi.enableLocalDB "postgresql.service";
|
||||
requires = optional cfgApi.enableLocalDB "postgresql.service";
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
preStart = ''
|
||||
# Generate config including secret values. YAML is a superset of JSON, so we can use this here.
|
||||
${utils.genJqSecretsReplacementSnippet cfgApi.settings "/run/ente/local.yaml"}
|
||||
|
||||
# Setup paths
|
||||
mkdir -p ${dataDir}/configurations
|
||||
ln -sTf /run/ente/local.yaml ${dataDir}/configurations/local.yaml
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = getExe cfgApi.package;
|
||||
Type = "simple";
|
||||
Restart = "on-failure";
|
||||
|
||||
AmbientCapablities = [];
|
||||
CapabilityBoundingSet = [];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateMounts = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = false;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_NETLINK"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "@system-service";
|
||||
UMask = "077";
|
||||
|
||||
BindReadOnlyPaths = [
|
||||
"${cfgApi.package}/share/museum/migrations:${dataDir}/migrations"
|
||||
"${cfgApi.package}/share/museum/mail-templates:${dataDir}/mail-templates"
|
||||
];
|
||||
|
||||
User = cfgApi.user;
|
||||
Group = cfgApi.group;
|
||||
|
||||
SyslogIdentifier = "ente";
|
||||
StateDirectory = "ente";
|
||||
WorkingDirectory = dataDir;
|
||||
RuntimeDirectory = "ente";
|
||||
};
|
||||
|
||||
# Environment MUST be called local, otherwise we cannot log to stdout
|
||||
environment = {
|
||||
ENVIRONMENT = "local";
|
||||
GIN_MODE = "release";
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
users = mkIf (cfgApi.user == defaultUser) {
|
||||
${defaultUser} = {
|
||||
description = "ente.io museum service user";
|
||||
inherit (cfgApi) group;
|
||||
isSystemUser = true;
|
||||
home = dataDir;
|
||||
};
|
||||
};
|
||||
groups = mkIf (cfgApi.group == defaultGroup) {${defaultGroup} = {};};
|
||||
};
|
||||
|
||||
services.nginx = mkIf cfgApi.nginx.enable {
|
||||
enable = true;
|
||||
upstreams.museum = {
|
||||
servers."localhost:8080" = {};
|
||||
extraConfig = ''
|
||||
zone museum 64k;
|
||||
keepalive 20;
|
||||
'';
|
||||
};
|
||||
|
||||
virtualHosts.${cfgApi.domain} = {
|
||||
forceSSL = mkDefault false;
|
||||
locations."/".proxyPass = "http://museum";
|
||||
extraConfig = ''
|
||||
client_max_body_size 4M;
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
(mkIf cfgWeb.enable {
|
||||
services.ente.api.settings = mkIf cfgApi.enable {
|
||||
apps = {
|
||||
accounts = "https://${cfgWeb.domains.accounts}";
|
||||
cast = "https://${cfgWeb.domains.cast}";
|
||||
public-albums = "https://${cfgWeb.domains.albums}";
|
||||
};
|
||||
|
||||
webauthn = {
|
||||
rpid = cfgWeb.domains.accounts;
|
||||
rporigins = ["https://${cfgWeb.domains.accounts}"];
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = let
|
||||
domainFor = app: cfgWeb.domains.${app};
|
||||
in {
|
||||
enable = true;
|
||||
virtualHosts.${domainFor "accounts"} = {
|
||||
forceSSL = mkDefault false;
|
||||
locations."/" = {
|
||||
root = webPackage "accounts";
|
||||
tryFiles = "$uri $uri.html /index.html";
|
||||
extraConfig = ''
|
||||
add_header Access-Control-Allow-Origin 'https://${cfgWeb.domains.api}';
|
||||
'';
|
||||
};
|
||||
};
|
||||
virtualHosts.${domainFor "cast"} = {
|
||||
forceSSL = mkDefault false;
|
||||
locations."/" = {
|
||||
root = webPackage "cast";
|
||||
tryFiles = "$uri $uri.html /index.html";
|
||||
extraConfig = ''
|
||||
add_header Access-Control-Allow-Origin 'https://${cfgWeb.domains.api}';
|
||||
'';
|
||||
};
|
||||
};
|
||||
virtualHosts.${domainFor "photos"} = {
|
||||
serverAliases = [
|
||||
(domainFor "albums") # the albums app is shared with the photos frontend
|
||||
];
|
||||
forceSSL = mkDefault false;
|
||||
locations."/" = {
|
||||
root = webPackage "photos";
|
||||
tryFiles = "$uri $uri.html /index.html";
|
||||
extraConfig = ''
|
||||
add_header Access-Control-Allow-Origin 'https://${cfgWeb.domains.api}';
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
meta.maintainers = with lib.maintainers; [oddlama];
|
||||
}
|
||||
|
|
@ -16,6 +16,11 @@ in {
|
|||
user = "forgejo";
|
||||
group = "forgejo";
|
||||
stateDir = "/srv/forgejo";
|
||||
secrets = {
|
||||
mailer = {
|
||||
PASSWD = ;
|
||||
};
|
||||
};
|
||||
settings = {
|
||||
# https://forgejo.org/docs/latest/admin/config-cheat-sheet/
|
||||
server = {
|
||||
|
|
@ -34,8 +39,7 @@ in {
|
|||
|
||||
PROTOCOL = "smtp+starttls";
|
||||
SMTP_ADDR = "mail.procopius.dk";
|
||||
USER = "admin@procopius.dk";
|
||||
PASSWD = "mikael";
|
||||
USER = "git@procopius.dk";
|
||||
};
|
||||
database = {
|
||||
DB_TYPE = lib.mkForce "postgres";
|
||||
|
|
@ -57,9 +61,9 @@ in {
|
|||
ZOMBIE_TASK_TIMEOUT = "30m";
|
||||
};
|
||||
ldap = {
|
||||
AUTHORIZATION_NAME = "My LDAP";
|
||||
HOST = "ldap.example.com";
|
||||
PORT = 389;
|
||||
AUTHORIZATION_NAME = "LLDAP";
|
||||
HOST = "auth.lab";
|
||||
PORT = 3890;
|
||||
ENABLE_TLS = false;
|
||||
USER_SEARCH_BASE = "ou=users,dc=example,dc=com";
|
||||
USER_FILTER = "(&(objectClass=user)(sAMAccountName=%[1]s))";
|
||||
|
|
@ -86,7 +90,6 @@ in {
|
|||
|
||||
security = {
|
||||
INSTALL_LOCK = true;
|
||||
SECRET_KEY = config.sops.secrets."forgejo-secret-key".path; # can be another secret
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,26 +1,12 @@
|
|||
{
|
||||
# services.nfs.client = {
|
||||
# enable = true;
|
||||
# idmapd.enable = true;
|
||||
# };
|
||||
|
||||
# environment.etc."idmapd.conf".text = ''
|
||||
# [General]
|
||||
# Domain = localdomain
|
||||
|
||||
# [Mapping]
|
||||
# Nobody-User = nobody
|
||||
# Nobody-Group = nogroup
|
||||
# '';
|
||||
|
||||
boot.supportedFilesystems = [ "nfs" ];
|
||||
boot.supportedFilesystems = ["nfs"];
|
||||
|
||||
services.rpcbind.enable = true;
|
||||
|
||||
fileSystems."/srv/forgejo" = {
|
||||
device = "192.168.1.226:/volume1/data/forgejo";
|
||||
fsType = "nfs4";
|
||||
options = [ "x-systemd.automount" "noatime" "_netdev" ];
|
||||
options = ["x-systemd.automount" "noatime" "_netdev"];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
../../templates/base.nix
|
||||
./networking.nix
|
||||
./storage.nix
|
||||
./sandbox.nix
|
||||
./warpgate.nix
|
||||
];
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
networking.hostName = "sandbox";
|
||||
networking.interfaces.ens18.useDHCP = true;
|
||||
networking.defaultGateway = "192.168.1.1";
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{ config, pkgs, modulesPath, lib, ... }:
|
||||
|
||||
{
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
boot.supportedFilesystems = ["nfs"];
|
||||
|
||||
services.rpcbind.enable = true;
|
||||
|
||||
# fileSystems."/mnt/nas" = {
|
||||
# device = "192.168.1.226:/volume1/docker";
|
||||
# fsType = "nfs";
|
||||
# options = [ "noatime" "vers=4" "rsize=8192" "wsize=8192" ];
|
||||
# };
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
virtualisation = {
|
||||
containers.enable = true;
|
||||
oci-containers.backend = "podman";
|
||||
|
||||
podman = {
|
||||
enable = true;
|
||||
|
||||
# Create a `docker` alias for podman, to use it as a drop-in replacement
|
||||
dockerCompat = true;
|
||||
|
||||
# Required for containers under podman-compose to be able to talk to each other.
|
||||
defaultNetwork.settings.dns_enabled = true;
|
||||
};
|
||||
};
|
||||
virtualisation.oci-containers.containers = {
|
||||
warpgate = {
|
||||
image = "ghcr.io/warp-tech/warpgate";
|
||||
ports = [
|
||||
"2222:2222"
|
||||
"8888:8888"
|
||||
];
|
||||
volumes = [
|
||||
"/srv/warpgate/data:/data"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /srv/warpgate 0755 root root -"
|
||||
"d /srv/warpgate/data 0755 root root -"
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [8888];
|
||||
}
|
||||
23
overlays/default.nix
Normal file
23
overlays/default.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# This file defines overlays
|
||||
{inputs, ...}: {
|
||||
# This one brings our custom packages from the 'pkgs' directory
|
||||
additions = final: _prev: import ../pkgs final.pkgs;
|
||||
|
||||
# This one contains whatever you want to overlay
|
||||
# You can change versions, add patches, set compilation flags, anything really.
|
||||
# https://nixos.wiki/wiki/Overlays
|
||||
modifications = final: prev: {
|
||||
# example = prev.example.overrideAttrs (oldAttrs: rec {
|
||||
# ...
|
||||
# });
|
||||
};
|
||||
|
||||
# When applied, the unstable nixpkgs set (declared in the flake inputs) will
|
||||
# be accessible through 'pkgs.unstable'
|
||||
unstable-packages = final: _prev: {
|
||||
unstable = import inputs.nixpkgs-unstable {
|
||||
system = final.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
6
pkgs/default.nix
Normal file
6
pkgs/default.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Custom packages, that can be defined similarly to ones from nixpkgs
|
||||
# You can build them using 'nix build .#example'
|
||||
pkgs: {
|
||||
# example = pkgs.callPackage ./example { };
|
||||
ente-web = pkgs.callPackage ./ente-web.nix {};
|
||||
}
|
||||
91
pkgs/ente-web.nix
Normal file
91
pkgs/ente-web.nix
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
fetchYarnDeps,
|
||||
nodejs,
|
||||
yarnConfigHook,
|
||||
yarnBuildHook,
|
||||
nix-update-script,
|
||||
extraBuildEnv ? {},
|
||||
# This package contains serveral sub-applications. This specifies which of them you want to build.
|
||||
enteApp ? "photos",
|
||||
# Accessing some apps (such as account) directly will result in a hardcoded redirect to ente.io.
|
||||
# To prevent users from accidentally logging in to ente.io instead of the selfhosted instance, you
|
||||
# can set this parameter to override these occurrences with your own url. Must include the schema.
|
||||
# Example: https://my-ente.example.com
|
||||
enteMainUrl ? null,
|
||||
}:
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "ente-web-${enteApp}";
|
||||
version = "1.0.4";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ente-io";
|
||||
repo = "ente";
|
||||
sparseCheckout = ["web"];
|
||||
tag = "photos-v${finalAttrs.version}";
|
||||
fetchSubmodules = true;
|
||||
hash = "sha256-M1kAZgqjbWNn6LqymtWRmAk/v0vWEGbyS50lVrsr85o=";
|
||||
};
|
||||
sourceRoot = "${finalAttrs.src.name}/web";
|
||||
|
||||
offlineCache = fetchYarnDeps {
|
||||
yarnLock = "${finalAttrs.src}/web/yarn.lock";
|
||||
hash = "sha256-EYhYwy6+7bgWckU/7SfL1PREWw9JUgKxWadSVtoZwXs=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
yarnConfigHook
|
||||
yarnBuildHook
|
||||
nodejs
|
||||
];
|
||||
|
||||
# See: https://github.com/ente-io/ente/blob/main/web/apps/photos/.env
|
||||
env = extraBuildEnv;
|
||||
|
||||
# Replace hardcoded ente.io urls if desired
|
||||
postPatch = lib.optionalString (enteMainUrl != null) ''
|
||||
substituteInPlace \
|
||||
apps/payments/src/services/billing.ts \
|
||||
apps/photos/src/pages/shared-albums.tsx \
|
||||
--replace-fail "https://ente.io" ${lib.escapeShellArg enteMainUrl}
|
||||
|
||||
substituteInPlace \
|
||||
apps/accounts/src/pages/index.tsx \
|
||||
--replace-fail "https://web.ente.io" ${lib.escapeShellArg enteMainUrl}
|
||||
'';
|
||||
|
||||
yarnBuildScript = "build:${enteApp}";
|
||||
installPhase = let
|
||||
distName =
|
||||
if enteApp == "payments"
|
||||
then "dist"
|
||||
else "out";
|
||||
in ''
|
||||
runHook preInstall
|
||||
|
||||
cp -r apps/${enteApp}/${distName} $out
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
passthru.updateScript = nix-update-script {
|
||||
extraArgs = [
|
||||
"--version-regex"
|
||||
"photos-v(.*)"
|
||||
];
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "Ente application web frontends";
|
||||
homepage = "https://ente.io/";
|
||||
changelog = "https://github.com/ente-io/ente/releases";
|
||||
license = lib.licenses.agpl3Only;
|
||||
maintainers = with lib.maintainers; [
|
||||
pinpox
|
||||
oddlama
|
||||
];
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue