sqlite-web module & deployment
This commit is contained in:
parent
9b0255eaad
commit
8bcf0c68e1
16
flake.lock
16
flake.lock
|
@ -2057,11 +2057,11 @@
|
||||||
"shimmeringvoid": "shimmeringvoid"
|
"shimmeringvoid": "shimmeringvoid"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1744141371,
|
"lastModified": 1744558061,
|
||||||
"narHash": "sha256-anPwB6x7NvXfivSdZgpCWUQ9BY/zbPwmUtrAOXfGAcs=",
|
"narHash": "sha256-88/C7xbeE5vxb0YFfBeLi8yjOB664u3aYCjn+AQGOaA=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "42d7de0bb1177ed13a94d64311d70259bd0c789d",
|
"rev": "d6b15ed45f32e03e5697b35ed0308d9cf2c8ef66",
|
||||||
"revCount": 91,
|
"revCount": 95,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringmoon.git"
|
"url": "ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringmoon.git"
|
||||||
},
|
},
|
||||||
|
@ -2073,11 +2073,11 @@
|
||||||
"shimmeringvoid": {
|
"shimmeringvoid": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1744140761,
|
"lastModified": 1744146722,
|
||||||
"narHash": "sha256-ciOI5UMLxDlAYS4HjTSf6MViEhBgHhUEYjLxP/Xv2G0=",
|
"narHash": "sha256-qvh6UxyLbbaSrrpAJwW3fzA1YqrwnTUT8qj17poi0aY=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "890b7973dd522ac175e17fb6ea7d6bd74fec9565",
|
"rev": "b6ab7c08daac587a1da5649cfdbc082ef2a01a20",
|
||||||
"revCount": 10,
|
"revCount": 13,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringvoid.git"
|
"url": "ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringvoid.git"
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,7 +39,7 @@ in
|
||||||
satellite.persistence.at.data.apps.smos.directories = [ config.programs.smos.workflowDir ];
|
satellite.persistence.at.data.apps.smos.directories = [ config.programs.smos.workflowDir ];
|
||||||
|
|
||||||
sops.secrets.smos_github_token = {
|
sops.secrets.smos_github_token = {
|
||||||
sopsFile = ../secrets.yaml;
|
sopsFile = ./secrets.yaml;
|
||||||
path = "${config.xdg.dataHome}/smos/.github_token";
|
path = "${config.xdg.dataHome}/smos/.github_token";
|
||||||
};
|
};
|
||||||
# }}}
|
# }}}
|
||||||
|
|
|
@ -29,5 +29,7 @@
|
||||||
glass-server = 8425;
|
glass-server = 8425;
|
||||||
glass-server-lp-tcp = 8426;
|
glass-server-lp-tcp = 8426;
|
||||||
glass-server-lp-udp = 8427;
|
glass-server-lp-udp = 8427;
|
||||||
|
sqlite-web-glass = 8428;
|
||||||
|
sqlite-web-shimmer = 8429;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
imports = [ ./module.nix ];
|
imports = [ ./module.nix ];
|
||||||
|
|
||||||
|
@ -20,32 +20,40 @@
|
||||||
group = config.services.glass-server.user;
|
group = config.services.glass-server.user;
|
||||||
sopsFile = ../../secrets.yaml;
|
sopsFile = ../../secrets.yaml;
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.templates.glass-server-config = {
|
|
||||||
owner = config.services.glass-server.user;
|
|
||||||
group = config.services.glass-server.user;
|
|
||||||
content = builtins.toJSON {
|
|
||||||
CONTENT_BUNDLE_FOLDER_PATH = "${pkgs.shimmeringextra}/bundles";
|
|
||||||
SECRET_KEY = "${config.sops.placeholder.glass_server_secret_key}";
|
|
||||||
PASSWORD = "${config.sops.placeholder.glass_server_admin_password}";
|
|
||||||
API_TOKEN = "${config.sops.placeholder.glass_server_admin_token}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# }}}
|
# }}}
|
||||||
|
# {{{ Routing
|
||||||
satellite.cloudflared.at.arcaea.port = config.satellite.ports.glass-server;
|
|
||||||
satellite.cloudflared.at."tcp.lp.arcaea".port = config.satellite.ports.glass-server-lp-tcp;
|
satellite.cloudflared.at."tcp.lp.arcaea".port = config.satellite.ports.glass-server-lp-tcp;
|
||||||
satellite.cloudflared.at."udp.lp.arcaea".port = config.satellite.ports.glass-server-lp-udp;
|
satellite.cloudflared.at."udp.lp.arcaea".port = config.satellite.ports.glass-server-lp-udp;
|
||||||
|
satellite.cloudflared.at.arcaea.port = 80;
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."arcaea.moonythm.dev" = {
|
||||||
|
locations."/web/".proxyPass =
|
||||||
|
"http://localhost:${toString config.satellite.ports.glass-server}/web/";
|
||||||
|
locations."/db/glass/".proxyPass =
|
||||||
|
"http://localhost:${toString config.satellite.ports.sqlite-web-glass}/db/glass/";
|
||||||
|
locations."/db/shimmer/".proxyPass =
|
||||||
|
"http://localhost:${toString config.satellite.ports.sqlite-web-shimmer}/db/shimmer/";
|
||||||
|
locations."/" = {
|
||||||
|
return = "301 https://arcaea.lowiro.com/en";
|
||||||
|
priority = 2000; # 1000 is the default for everything else
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
satellite.sqliteWeb.databases.glass.location = "/db/glass/";
|
||||||
|
satellite.sqliteWeb.databases.shimmer.location = "/db/shimmer/";
|
||||||
|
# }}}
|
||||||
|
|
||||||
services.glass-server = {
|
services.glass-server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
adminUsername = "prescientmoon";
|
adminUsername = "prescientmoon";
|
||||||
|
|
||||||
dataDir = "/persist/state/var/lib/arcaea/server";
|
dataDir = "/persist/state/var/lib/arcaea/server";
|
||||||
secretConfig = config.sops.templates.glass-server-config.path;
|
|
||||||
|
|
||||||
port = config.satellite.ports.glass-server;
|
port = config.satellite.ports.glass-server;
|
||||||
linkPlayTCPPort = config.satellite.ports.glass-server-lp-tcp;
|
linkPlayTCPPort = config.satellite.ports.glass-server-lp-tcp;
|
||||||
linkPlayUDPPort = config.satellite.ports.glass-server-lp-udp;
|
linkPlayUDPPort = config.satellite.ports.glass-server-lp-udp;
|
||||||
|
|
||||||
|
secretKeyFile = config.sops.secrets.glass_server_secret_key.path;
|
||||||
|
passwordFile = config.sops.secrets.glass_server_admin_password.path;
|
||||||
|
apiTokenFile = config.sops.secrets.glass_server_admin_token.path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ let
|
||||||
SAVE_FULL_UNLOCK = false;
|
SAVE_FULL_UNLOCK = false;
|
||||||
STAMINA_RECOVER_TICK = 1; # Recover stamina instantly
|
STAMINA_RECOVER_TICK = 1; # Recover stamina instantly
|
||||||
SKILL_FATALIS_WORLD_LOCKED_TIME = 1; # Recover from Fatalis instantly
|
SKILL_FATALIS_WORLD_LOCKED_TIME = 1; # Recover from Fatalis instantly
|
||||||
|
|
||||||
|
CONTENT_BUNDLE_FOLDER_PATH = "${pkgs.shimmeringextra}/bundles";
|
||||||
# }}}
|
# }}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,13 +89,21 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
secretConfig = lib.mkOption {
|
secretKeyFile = lib.mkOption {
|
||||||
type = lib.types.path;
|
type = lib.types.path;
|
||||||
description = ''
|
description = "Path to a file containing the secret key to use for the server";
|
||||||
Path to additional config that might be generated at runtime by a tool
|
|
||||||
like sops. This might be useful for things like the admin password
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
passwordFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Path to a file containing the admin password for the server";
|
||||||
|
};
|
||||||
|
|
||||||
|
apiTokenFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Path to a file containing the api token for the server";
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
@ -121,15 +131,24 @@ in
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.user;
|
Group = cfg.user;
|
||||||
ExecStart = pkgs.writeShellScript "glass-server-startup" ''
|
ExecStart = pkgs.writeShellScript "glass-server-startup" ''
|
||||||
# Merge the given configs
|
# Copy secrets into config
|
||||||
${lib.getExe pkgs.jq} -s ".[0] * .[1]" \
|
${lib.getExe pkgs.jq} "\
|
||||||
${cfg.secretConfig} \
|
.SECRET_KEY=\"$(cat ${cfg.secretKeyFile})\" |\
|
||||||
|
.PASSWORD=\"$(cat ${cfg.passwordFile})\" |\
|
||||||
|
.API_TOKEN=\"$(cat ${cfg.apiTokenFile})\" \
|
||||||
|
" \
|
||||||
${serverConfigPath} \
|
${serverConfigPath} \
|
||||||
> ${configPath}
|
> ${configPath}
|
||||||
|
|
||||||
|
# TODO: only do this if the db file already exists...
|
||||||
|
# Update the db
|
||||||
|
${lib.getExe pkgs.glass-server-db-updater} \
|
||||||
|
${glassServerConfig.SQLITE_DATABASE_PATH}
|
||||||
|
|
||||||
# Start the server
|
# Start the server
|
||||||
ARCAEA_JSON_CONFIG_PATH=${configPath} ${pkg}/bin/glass-server
|
ARCAEA_JSON_CONFIG_PATH=${configPath} ${pkg}/bin/glass-server
|
||||||
'';
|
'';
|
||||||
|
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -144,5 +163,13 @@ in
|
||||||
groups.${defaultUser} = { };
|
groups.${defaultUser} = { };
|
||||||
};
|
};
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
satellite.sqliteWeb.databases.glass = {
|
||||||
|
port = config.satellite.ports.sqlite-web-glass;
|
||||||
|
user = cfg.user;
|
||||||
|
group = cfg.user;
|
||||||
|
file = glassServerConfig.SQLITE_DATABASE_PATH;
|
||||||
|
passwordFile = cfg.passwordFile;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,14 @@ in
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [ "d ${dataDir} 0755 ${user} ${user}" ];
|
systemd.tmpfiles.rules = [ "d ${dataDir} 0755 ${user} ${user}" ];
|
||||||
|
|
||||||
|
satellite.sqliteWeb.databases.shimmer = {
|
||||||
|
port = config.satellite.ports.sqlite-web-shimmer;
|
||||||
|
user = user;
|
||||||
|
group = user;
|
||||||
|
file = "${dataDir}/db.sqlite";
|
||||||
|
passwordFile = config.services.glass-server.passwordFile;
|
||||||
|
};
|
||||||
|
|
||||||
# {{{ Secrets
|
# {{{ Secrets
|
||||||
sops.secrets.shimmering_discord_token = {
|
sops.secrets.shimmering_discord_token = {
|
||||||
owner = user;
|
owner = user;
|
||||||
|
|
|
@ -7,4 +7,5 @@
|
||||||
nginx = ./nginx.nix;
|
nginx = ./nginx.nix;
|
||||||
pilot = ./pilot.nix;
|
pilot = ./pilot.nix;
|
||||||
pounce = ./pounce.nix;
|
pounce = ./pounce.nix;
|
||||||
|
sqliteWeb = ./sqlite-web.nix;
|
||||||
}
|
}
|
||||||
|
|
82
modules/nixos/sqlite-web.nix
Normal file
82
modules/nixos/sqlite-web.nix
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.satellite.sqliteWeb;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.satellite.sqliteWeb = {
|
||||||
|
databases = lib.mkOption {
|
||||||
|
description = "Per-database sqlite-web configuration";
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
options.port = lib.mkOption {
|
||||||
|
description = "Port to serve UI on";
|
||||||
|
type = lib.types.nullOr lib.types.port;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
options.user = lib.mkOption {
|
||||||
|
description = "The user the GUI should run as";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
options.group = lib.mkOption {
|
||||||
|
description = "The group the GUI should run as";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
options.file = lib.mkOption {
|
||||||
|
description = "Path to serve files from";
|
||||||
|
type = lib.types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
options.passwordFile = lib.mkOption {
|
||||||
|
description = "File containing the password to use for authentication";
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
options.location = lib.mkOption {
|
||||||
|
description = "Prefix path to add to all urls";
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config.systemd.services = lib.attrsets.mapAttrs' (name: value: {
|
||||||
|
name = "sqlite-web-${name}";
|
||||||
|
value = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
description = "Sqlite web GUI";
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
User = value.user;
|
||||||
|
Group = value.user;
|
||||||
|
ExecStart = pkgs.writeShellScript "sqlite-web-startup" ''
|
||||||
|
export SQLITE_WEB_PASSWORD=$(cat ${value.passwordFile})
|
||||||
|
|
||||||
|
${lib.getExe pkgs.sqlite-web} \
|
||||||
|
--port=${toString value.port} \
|
||||||
|
--url-prefix=${value.location} \
|
||||||
|
--password \
|
||||||
|
--no-browser \
|
||||||
|
${value.file}
|
||||||
|
'';
|
||||||
|
Restart = "on-failure";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) cfg.databases;
|
||||||
|
}
|
|
@ -17,8 +17,8 @@ pkgs.stdenv.mkDerivation {
|
||||||
src = pkgs.fetchFromGitHub {
|
src = pkgs.fetchFromGitHub {
|
||||||
owner = "starlitcanopy";
|
owner = "starlitcanopy";
|
||||||
repo = "ArcaeaServerFork";
|
repo = "ArcaeaServerFork";
|
||||||
rev = "2ee761f49462eabd6e26d2951cdd32205808261c";
|
rev = "eb9bd4849b429d9228ae9509b3367f2a921c2a0b";
|
||||||
sha256 = "i0h3lXo1k99h0h1P4VIFoYvugOtcY4vZZx9+8L//z1A=";
|
sha256 = "HGBQ0Pib6f7o7QGbcbnvnQ3mIOiXnNRuGAkLDNzFpPw=";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
|
|
Loading…
Reference in a new issue