fixxxxxxxxxxxxxxxx
This commit is contained in:
@@ -12,6 +12,23 @@ let
|
||||
|
||||
cfg = config.services.wafrn;
|
||||
|
||||
defaultWafrnPackage =
|
||||
if wafrnSrc != null then
|
||||
pkgs.stdenvNoCC.mkDerivation {
|
||||
pname = "wafrn-source";
|
||||
version = "unstable";
|
||||
src = wafrnSrc;
|
||||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
installPhase = ''
|
||||
mkdir -p "$out"
|
||||
cp -a ./. "$out/"
|
||||
chmod -R u+w "$out"
|
||||
'';
|
||||
}
|
||||
else
|
||||
null;
|
||||
|
||||
toEnvString = value:
|
||||
if builtins.isBool value then
|
||||
(if value then "true" else "false")
|
||||
@@ -105,14 +122,17 @@ let
|
||||
|
||||
serviceEnvFile = "${cfg.stateDir}/.env";
|
||||
composeFile = "${cfg.stateDir}/docker-compose.yml";
|
||||
sourcePath =
|
||||
if cfg.source != null then
|
||||
cfg.source
|
||||
else if wafrnSrc != null then
|
||||
toString wafrnSrc
|
||||
else
|
||||
"";
|
||||
packageSourcePath = toString cfg.package;
|
||||
sourcePath = if cfg.source != null then cfg.source else "";
|
||||
preparedSourcePath = "${cfg.stateDir}/source";
|
||||
usingPrebuiltImages = cfg.images.backend != null && cfg.images.frontend != null;
|
||||
effectiveCaddyConfigDir =
|
||||
if cfg.caddyConfigDir != null then
|
||||
cfg.caddyConfigDir
|
||||
else if usingPrebuiltImages then
|
||||
null
|
||||
else
|
||||
"${preparedSourcePath}/packages/caddy";
|
||||
|
||||
publishedPorts =
|
||||
lib.optionals (cfg.httpPort != null) [ "${toString cfg.httpPort}:80" ]
|
||||
@@ -132,8 +152,24 @@ let
|
||||
dockerfile = "packages/backend/Dockerfile";
|
||||
};
|
||||
|
||||
backendContainerSpec =
|
||||
if usingPrebuiltImages then
|
||||
{ image = cfg.images.backend; }
|
||||
else
|
||||
{ build = backendBuild; };
|
||||
|
||||
frontendContainerSpec =
|
||||
if usingPrebuiltImages then
|
||||
{ image = cfg.images.frontend; }
|
||||
else
|
||||
{
|
||||
build = {
|
||||
context = preparedSourcePath;
|
||||
dockerfile = "packages/frontend/Dockerfile";
|
||||
};
|
||||
};
|
||||
|
||||
backendService = {
|
||||
build = backendBuild;
|
||||
depends_on = {
|
||||
db = { condition = "service_started"; };
|
||||
redis = { condition = "service_started"; };
|
||||
@@ -153,9 +189,9 @@ let
|
||||
|
||||
composeConfig = {
|
||||
services = {
|
||||
backend = serviceCommon // backendService;
|
||||
backend = serviceCommon // backendService // backendContainerSpec;
|
||||
|
||||
migration = serviceCommon // backendService // {
|
||||
migration = serviceCommon // backendService // backendContainerSpec // {
|
||||
restart = "no";
|
||||
depends_on = {
|
||||
db = { condition = "service_started"; };
|
||||
@@ -165,11 +201,7 @@ let
|
||||
command = "npm exec tsx migrate.ts init-container";
|
||||
};
|
||||
|
||||
frontend = serviceCommon // {
|
||||
build = {
|
||||
context = preparedSourcePath;
|
||||
dockerfile = "packages/frontend/Dockerfile";
|
||||
};
|
||||
frontend = serviceCommon // frontendContainerSpec // {
|
||||
restart = "unless-stopped";
|
||||
ports = publishedPorts;
|
||||
extra_hosts = [ "host.docker.internal:host-gateway" ];
|
||||
@@ -177,7 +209,8 @@ let
|
||||
"${cfg.stateDir}/caddy:/data"
|
||||
"${cfg.stateDir}/frontend:/var/www/html/frontend"
|
||||
"${cfg.stateDir}/uploads:/var/www/html/uploads"
|
||||
"${preparedSourcePath}/packages/caddy:/etc/caddy/config"
|
||||
] ++ lib.optionals (effectiveCaddyConfigDir != null) [
|
||||
"${effectiveCaddyConfigDir}:/etc/caddy/config"
|
||||
];
|
||||
};
|
||||
|
||||
@@ -205,8 +238,7 @@ let
|
||||
};
|
||||
}
|
||||
// optionalAttrs cfg.bluesky.enable {
|
||||
pds_worker = serviceCommon // {
|
||||
build = backendBuild;
|
||||
pds_worker = serviceCommon // backendContainerSpec // {
|
||||
command = "npm exec tsx atproto.ts";
|
||||
depends_on = {
|
||||
db = { condition = "service_started"; };
|
||||
@@ -266,7 +298,41 @@ in
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/srv/wafrn";
|
||||
description = "Optional path to a Wafrn source checkout. If null, the module uses the pinned source from this flake input.";
|
||||
description = "Optional path to a Wafrn source checkout. If null, the service uses services.wafrn.package as the source.";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default =
|
||||
if defaultWafrnPackage != null then
|
||||
defaultWafrnPackage
|
||||
else
|
||||
throw "services.wafrn.package must be set when no flake-pinned wafrn source is available";
|
||||
defaultText = lib.literalExpression "<wafrn source package>";
|
||||
description = "Package containing Wafrn source tree used to build backend/frontend Docker images.";
|
||||
};
|
||||
|
||||
caddyConfigDir = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/srv/wafrn/packages/caddy";
|
||||
description = "Optional host path mounted into frontend container as /etc/caddy/config for Caddy hooks/overrides.";
|
||||
};
|
||||
|
||||
images = {
|
||||
backend = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "ghcr.io/your-org/wafrn-backend:2026.02.01";
|
||||
description = "Prebuilt backend image. Set together with images.frontend to skip local source/Docker builds.";
|
||||
};
|
||||
|
||||
frontend = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "ghcr.io/your-org/wafrn-frontend:2026.02.01";
|
||||
description = "Prebuilt frontend image. Set together with images.backend to skip local source/Docker builds.";
|
||||
};
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
@@ -352,8 +418,12 @@ in
|
||||
message = "services.wafrn requires virtualisation.docker.enable = true;";
|
||||
}
|
||||
{
|
||||
assertion = cfg.source != null || wafrnSrc != null;
|
||||
message = "services.wafrn.source is null and no flake-pinned wafrn source is available.";
|
||||
assertion = usingPrebuiltImages || cfg.source != null || cfg.package != null;
|
||||
message = "Provide services.wafrn.images.backend+frontend, set services.wafrn.source, or set services.wafrn.package.";
|
||||
}
|
||||
{
|
||||
assertion = (cfg.images.backend == null) == (cfg.images.frontend == null);
|
||||
message = "Set both services.wafrn.images.backend and services.wafrn.images.frontend, or neither.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.httpPort != null || cfg.httpsPort != null;
|
||||
@@ -369,6 +439,7 @@ in
|
||||
"d ${cfg.stateDir}/cache 0750 root root -"
|
||||
"d ${cfg.stateDir}/caddy 0750 root root -"
|
||||
"d ${cfg.stateDir}/frontend 0750 root root -"
|
||||
] ++ lib.optionals (!usingPrebuiltImages) [
|
||||
"d ${cfg.stateDir}/source 0750 root root -"
|
||||
] ++ lib.optionals (cfg.bluesky.enable && cfg.bluesky.useBundledPds) [
|
||||
"d ${cfg.stateDir}/pds 0750 root root -"
|
||||
@@ -389,20 +460,38 @@ in
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -d "${sourcePath}" ]; then
|
||||
echo "wafrn-nix: source directory does not exist: ${sourcePath}" >&2
|
||||
exit 1
|
||||
fi
|
||||
${optionalString (!usingPrebuiltImages) ''
|
||||
selected_source=""
|
||||
|
||||
rm -rf "${preparedSourcePath}"
|
||||
mkdir -p "${preparedSourcePath}"
|
||||
cp -a "${sourcePath}/." "${preparedSourcePath}/"
|
||||
chmod -R u+w "${preparedSourcePath}"
|
||||
if [ -n "${sourcePath}" ] && [ -d "${sourcePath}" ]; then
|
||||
selected_source="${sourcePath}"
|
||||
elif [ -n "${sourcePath}" ]; then
|
||||
echo "wafrn-nix: configured source does not exist (${sourcePath}), falling back to services.wafrn.package" >&2
|
||||
fi
|
||||
|
||||
if [ ! -f "${preparedSourcePath}/package-lock.json" ]; then
|
||||
echo "wafrn-nix: package-lock.json missing, generating with npm" >&2
|
||||
(cd "${preparedSourcePath}" && npm install --package-lock-only --ignore-scripts)
|
||||
fi
|
||||
if [ -z "$selected_source" ] && [ -d "${packageSourcePath}" ]; then
|
||||
selected_source="${packageSourcePath}"
|
||||
fi
|
||||
|
||||
if [ -z "$selected_source" ]; then
|
||||
echo "wafrn-nix: no usable source directory found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "${preparedSourcePath}"
|
||||
mkdir -p "${preparedSourcePath}"
|
||||
cp -a "$selected_source/." "${preparedSourcePath}/"
|
||||
chmod -R u+w "${preparedSourcePath}"
|
||||
|
||||
if [ ! -e "${preparedSourcePath}/.git" ]; then
|
||||
mkdir -p "${preparedSourcePath}/.git"
|
||||
fi
|
||||
|
||||
if [ ! -f "${preparedSourcePath}/package-lock.json" ]; then
|
||||
echo "wafrn-nix: package-lock.json missing, generating with npm" >&2
|
||||
(cd "${preparedSourcePath}" && npm install --package-lock-only --ignore-scripts)
|
||||
fi
|
||||
''}
|
||||
|
||||
install -m 0600 ${envTemplate} ${serviceEnvFile}
|
||||
${optionalString (cfg.secretsFile != null) ''
|
||||
|
||||
Reference in New Issue
Block a user