nix-config/modules/fedi/iceshrimp/default.nix
2025-05-11 21:09:57 +02:00

256 lines
6.5 KiB
Nix

{
lib,
pkgs,
config,
...
}: let
inherit (lib) mkIf mkOption;
inherit (lib.generators) toINI;
inherit (config) versions;
inherit (lib.types) attrs package;
cfg = config.conf.fedi.iceshrimp;
iceshrimp = pkgs.callPackage ./iceshrimp.nix {version = versions.iceshrimp;};
settings = pkgs.writeTextFile {
name = "configuration.overrides.ini";
text = toINI {} config.services.iceshrimp.settings;
};
in {
options = {
services.iceshrimp = {
package = mkOption {
type = package;
default = iceshrimp;
};
settings = mkOption {
type = attrs;
default = {};
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [iceshrimp];
services.nginx.virtualHosts.${cfg.domain.full} = {
useACMEHost = cfg.domain.base;
forceSSL = true;
locations = {
"/" = {
proxyPass = "http://localhost:3000";
extraConfig = ''
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
'';
};
};
};
users = {
users.iceshrimp = {
description = "Iceshrimp user";
group = "iceshrimp";
isSystemUser = true;
};
groups.iceshrimp = {
};
};
services.iceshrimp = {
settings = {
Instance = {
ListenPort = 3000;
ListenHost = "http://localhost";
WebDomain = cfg.domain.full;
AccountDomain = cfg.domain.full;
CharacterLimit = 8192;
};
Security = {
AuthorizedFetch = true;
Registrations = "Open";
FederationMode = "BlockList";
ExposeFederationList = "Public";
ExposeBlockReason = "Public";
PublicPreview = "Public";
};
Performance = {
FederationRequestHandlerConcurrency = 0;
};
"Performance:QueueConcurrency" = {
Inbox = 4;
Deliver = 20;
PreDeliver = 4;
BackgroundTask = 4;
Backfill = 10;
BackfillUser = 10;
};
"Backfill:User" = {
Enabled = true;
MaxItems = 100;
RefreshAfter = "30d";
};
"Backfill:Replies" = {
Enabled = true;
FetchAsUser = true;
NewNoteDelay = "5m";
RefreshAfter = "15m";
};
"Queue:JobRetention" = {
Completed = 10;
Failed = 100;
};
Database = {
Host = "localhost";
Port = 5432;
Database = "iceshrimp";
Username = "iceshrimp";
Password = "iceshrimp";
Multiplexing = true;
};
Storage = {
Provider = "Local";
MaxUploadSize = "10G";
MaxCacheSize = "20M";
MediaRetention = "30d";
CleanAvatars = false;
CleanBanners = false;
ProxyRemoteMedia = true;
};
"Storage:Local" = {
Path = "/var/lib/iceshrimp.net/files/media";
};
"Storage:MediaProcessing" = {
ImageProcessor = "ImageSharp";
LocalOnly = false;
MaxFileSize = "10M";
MaxResolutionMpx = 20;
FailIfImageExceedsMaxRes = true;
ImageProcessorConcurrency = 8;
};
"Storage:MediaProcessing:ImagePipeline:Original:Local" = {
Format = "Keep";
};
"Storage:MediaProcessing:ImagePipeline:Original:Remote" = {
Format = "Keep";
};
"Storage:MediaProcessing:ImagePipeline:Thumbnail:Local" = {
Format = "Webp";
TargetRes = 1000;
};
"Storage:MediaProcessing:ImagePipeline:Thumbnail:Remote" = {
Format = "Webp";
TargetRes = 1000;
QualityFactorPngSource = 75;
};
"Storage:MediaProcessing:ImagePipeline:Public:Local" = {
Format = "Webp";
TargetRes = 2048;
};
"Storage:MediaProcessing:ImagePipeline:Public:Remote" = {
Format = "None";
};
"Logging:LogLevel" = {
Default = "Information";
"Iceshrimp " = "Information";
"Microsoft.AspNetCore" = "Warning";
"Microsoft.EntityFrameworkCore" = "Warning";
"Microsoft.EntityFrameworkCore.Update" = "Critical";
"Microsoft.EntityFrameworkCore.Migrations" = "Information";
"Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager" = "Critical";
"Iceshrimp.Backend.SignalR.Authentication.HubAuthenticationHandler" = "Warning";
};
};
};
systemd.services.iceshrimp = {
enable = true;
description = "Iceshrimp.NET daemon";
environment = {
ICESHRIMP_CONFIG = settings;
MALLOC_TRIM_TRESHOLD = "131072";
};
after = ["postgresql.service"];
requires = ["postgresql.service"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "simple";
Restart = "on-failure";
User = "iceshrimp";
Group = "iceshrimp";
WorkingDirectory = "${iceshrimp}/usr/share";
SysLogIdentifier = "iceshrimp.net";
ExecStart = "${iceshrimp}/bin/iceshrimp --migrate-and-start";
ReadOnlyPaths = [
"${iceshrimp}"
"${settings}"
];
ReadWritePaths = [
"/var/lib/iceshrimp.net/"
"/var/lib/iceshrimp/iceshrimp.net.sock"
];
NoExecPaths = [
"/var/lib/iceshrimp.net/files"
];
RestrictSUIDSGID = true;
RestrictNamespaces = true;
PrivateTmp = true;
PrivateDevices = true;
PrivateUsers = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
ProtectSystem = "strict";
ProtectHome = true;
ProtectProc = "invisible";
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
SystemCallErrorNumber = "EPERM";
LockPersonality = true;
NoNewPrivileges = true;
};
};
services.postgresql = {
enable = true;
ensureDatabases = ["iceshrimp"];
ensureUsers = [
{
name = "iceshrimp";
ensureDBOwnership = true;
}
];
};
};
}