Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70ccf1eba1 | ||
|
|
f6caa2ff32 | ||
|
|
8bc325b148 | ||
|
|
e31094c194 | ||
|
|
09d4cc9b83 | ||
|
|
3341659a0c | ||
|
|
32e1119e33 | ||
|
|
0f7ef8422d | ||
|
|
dd6042928a | ||
|
|
74405b2ffc | ||
|
|
258da6a337 | ||
|
|
73ab3f40c1 | ||
|
|
0768712bf7 | ||
|
|
2ac30dc10a |
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [1.1.7] - 2026-09-21
|
||||
|
||||
### Added
|
||||
- Postgresql: drop per-database autovacuum ALTERs (rejected by Postgres)
|
||||
- Synapse: performance tuning for 32 GB Server+Desktop hosts
|
||||
- Nextcloud, postgresql: fix Nextcloud 35 DB warnings on 32 GB hosts
|
||||
- Clean up flake.nix by removing comments and LiveKit override
|
||||
|
||||
### Changed
|
||||
- Updated nixpkgs
|
||||
- Updated to php85 and fixes
|
||||
- Updated to proper syntax to prevent build errors.
|
||||
- Updated flake lock which contains Bisq 1.10.8 and Bisq2 2.1.13
|
||||
[1.1.7]: https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/releases/tag/v1.1.7
|
||||
|
||||
|
||||
## [1.1.6] - 2026-09-15
|
||||
|
||||
### Added
|
||||
- Rename 'The Sovran Hub' to 'The Hub' in README
|
||||
- Rename 'Sovran Hub' to 'The Hub' in README
|
||||
|
||||
### Changed
|
||||
- Updated nix packages includes the new mempool version
|
||||
|
||||
### Documentation
|
||||
- Update Sovran Hub screenshot to the v1.1.5 redesign
|
||||
[1.1.6]: https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/releases/tag/v1.1.6
|
||||
|
||||
|
||||
## [1.1.5] - 2026-09-09
|
||||
|
||||
### Added
|
||||
|
||||
@@ -21,9 +21,9 @@ Lightning infrastructure, private cloud, and communications platform when you
|
||||
are ready.
|
||||
|
||||
[Visit the Website](https://sovransystems.com) ·
|
||||
[Download the ISO](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.5.iso) ·
|
||||
[Download the ISO](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.7.iso) ·
|
||||
[Try it safely in a VM](#try-it-first-in-a-virtual-machine) ·
|
||||
[Verify the Download](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.5.iso.sha256) ·
|
||||
[Verify the Download](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.7.iso.sha256) ·
|
||||
[Build from Source](#build-from-source)
|
||||
|
||||
<img src="assets/desktop-screenshot.webp" alt="Sovran_SystemsOS private Bitcoin desktop" width="800" />
|
||||
@@ -45,7 +45,7 @@ are ready.
|
||||
- [What is included](#what-is-included)
|
||||
- [Three modes](#three-modes)
|
||||
- [Use it your way](#use-it-your-way)
|
||||
- [The Sovran Hub](#the-sovran-hub)
|
||||
- [The Hub](#the-hub)
|
||||
- [Install Sovran_SystemsOS](#install-sovran_systemsos)
|
||||
- [For developers](#for-developers)
|
||||
- [Development workflow](#development-workflow)
|
||||
@@ -264,11 +264,11 @@ infrastructure behind them.
|
||||
|
||||
---
|
||||
|
||||
## The Sovran Hub
|
||||
## The Hub
|
||||
|
||||
### Your private infrastructure, controlled from any screen.
|
||||
|
||||
The Sovran Hub is the command center built into Sovran_SystemsOS. It is both a
|
||||
The Hub is the command center built into Sovran_SystemsOS. It is both a
|
||||
local desktop application and a private web interface served directly by your
|
||||
Sovran_SystemsOS machine. Nothing needs to be installed on the device opening
|
||||
the Hub: you only need a modern browser and access to the same local network.
|
||||
@@ -281,9 +281,9 @@ From one place, the Hub helps you:
|
||||
- Reach your Bitcoin tools, private cloud, and communications
|
||||
- Perform supported system operations without everyday terminal commands
|
||||
|
||||
<img src="assets/sovran-hub-screenshot.webp" alt="The Sovran Hub dashboard" width="800" />
|
||||
<img src="assets/sovran-hub-screenshot.webp" alt="The Sovran Hub welcome dashboard" width="800" />
|
||||
|
||||
*The Sovran Hub: manage your private infrastructure from one place.*
|
||||
*The Hub: your whole system at a glance — Bitcoin, Lightning, and your private apps.*
|
||||
|
||||
### Example home setup
|
||||
|
||||
@@ -300,7 +300,7 @@ From one place, the Hub helps you:
|
||||
┌──────────────────────────┐
|
||||
│ Sovran_SystemsOS │
|
||||
│ │
|
||||
│ • Sovran Hub │
|
||||
│ • The Hub │
|
||||
│ • Bitcoin node │
|
||||
│ • Sparrow Wallet │
|
||||
│ • Bisq and Bisq 2 │
|
||||
@@ -345,8 +345,8 @@ with an imaging application such as [Balena Etcher](https://etcher.balena.io).
|
||||
|
||||
### 1. Download the ISO and checksum
|
||||
|
||||
- [Download Sovran_SystemsOS-1.1.5.iso](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.5.iso)
|
||||
- [Download Sovran_SystemsOS-1.1.5.iso.sha256](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.5.iso.sha256)
|
||||
- [Download Sovran_SystemsOS-1.1.7.iso](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.7.iso)
|
||||
- [Download Sovran_SystemsOS-1.1.7.iso.sha256](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.7.iso.sha256)
|
||||
|
||||
The download may take some time. Do not rename or modify the ISO before
|
||||
verifying it, and keep both files in the same folder.
|
||||
@@ -364,16 +364,16 @@ checksum exactly.
|
||||
Open a terminal in the download folder and run:
|
||||
|
||||
```bash
|
||||
sha256sum --check Sovran_SystemsOS-1.1.5.iso.sha256
|
||||
sha256sum --check Sovran_SystemsOS-1.1.7.iso.sha256
|
||||
```
|
||||
|
||||
A successful comparison reports:
|
||||
|
||||
```text
|
||||
Sovran_SystemsOS-1.1.5.iso: OK
|
||||
Sovran_SystemsOS-1.1.7.iso: OK
|
||||
```
|
||||
|
||||
You can also run `sha256sum Sovran_SystemsOS-1.1.5.iso` and compare the output
|
||||
You can also run `sha256sum Sovran_SystemsOS-1.1.7.iso` and compare the output
|
||||
against the checksum file manually.
|
||||
|
||||
</details>
|
||||
@@ -384,11 +384,11 @@ against the checksum file manually.
|
||||
Open Terminal in the download folder and run:
|
||||
|
||||
```bash
|
||||
shasum -a 256 Sovran_SystemsOS-1.1.5.iso
|
||||
shasum -a 256 Sovran_SystemsOS-1.1.7.iso
|
||||
```
|
||||
|
||||
Compare the value shown in Terminal with the value inside
|
||||
`Sovran_SystemsOS-1.1.5.iso.sha256`.
|
||||
`Sovran_SystemsOS-1.1.7.iso.sha256`.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -398,7 +398,7 @@ Compare the value shown in Terminal with the value inside
|
||||
Open PowerShell in the download folder and run:
|
||||
|
||||
```powershell
|
||||
Get-FileHash .\Sovran_SystemsOS-1.1.5.iso -Algorithm SHA256
|
||||
Get-FileHash .\Sovran_SystemsOS-1.1.7.iso -Algorithm SHA256
|
||||
```
|
||||
|
||||
Compare the value under `Hash` with the published checksum.
|
||||
@@ -413,7 +413,7 @@ match exactly.
|
||||
|
||||
1. Download and install [Balena Etcher](https://etcher.balena.io), then
|
||||
connect the USB drive.
|
||||
2. Choose **Flash from file** and select `Sovran_SystemsOS-1.1.5.iso`.
|
||||
2. Choose **Flash from file** and select `Sovran_SystemsOS-1.1.7.iso`.
|
||||
3. Choose **Select target**, select the USB drive, and review your selection
|
||||
carefully.
|
||||
4. Choose **Flash** and wait for the writing and verification process to
|
||||
@@ -856,7 +856,7 @@ primary location for collaboration. Please read our
|
||||
## Privacy. Sovereignty. Bitcoin.
|
||||
|
||||
[Visit Sovran Systems](https://sovransystems.com) ·
|
||||
[Download Sovran_SystemsOS](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.5.iso) ·
|
||||
[Download Sovran_SystemsOS](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.7.iso) ·
|
||||
[View the License](LICENSE)
|
||||
|
||||
</div>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 392 KiB After Width: | Height: | Size: 59 KiB |
@@ -165,6 +165,14 @@
|
||||
programs.fish = { enable = true; promptInit = "fastfetch"; };
|
||||
|
||||
# ── PostgreSQL base ────────────────────────────────────────
|
||||
# Shared cluster for Nextcloud (nextclouddb) + Matrix Synapse.
|
||||
# Sized for the README's Server + Desktop recommendation (32 GB RAM,
|
||||
# 500 GB NVMe OS + 2 TB NVMe timechain). Postgres shares the box with
|
||||
# Bitcoin Core, Electrs, LND, MariaDB, PHP-FPM and GNOME, so
|
||||
# shared_buffers stays below the 25%-of-RAM dedicated-server rule.
|
||||
# Fixes Nextcloud 35 Database checks (pg.cache_hit_ratio,
|
||||
# pg.dead_tuples). Override in custom.nix for other hosts, e.g.:
|
||||
# services.postgresql.settings.shared_buffers = lib.mkForce "512MB";
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
authentication = lib.mkForce ''
|
||||
@@ -172,6 +180,34 @@
|
||||
host all all 127.0.0.1/32 trust
|
||||
host all all ::1/128 trust
|
||||
'';
|
||||
settings = {
|
||||
# Memory — fixes low buffer cache hit ratio (stock default is
|
||||
# 128MB shared_buffers). effective_cache_size is only a planner
|
||||
# hint, not an allocation, so it can be generous.
|
||||
# NOTE: changing shared_buffers requires a Postgres restart.
|
||||
shared_buffers = "2GB";
|
||||
effective_cache_size = "12GB";
|
||||
maintenance_work_mem = "512MB";
|
||||
work_mem = "32MB";
|
||||
wal_buffers = "64MB";
|
||||
|
||||
# Checkpoints — spread write bursts out on NVMe. Reload-only.
|
||||
min_wal_size = "1GB";
|
||||
max_wal_size = "4GB";
|
||||
checkpoint_completion_target = 0.9;
|
||||
|
||||
# Autovacuum — the stock 60s naptime can't keep up with
|
||||
# Nextcloud's and Synapse's write-heavy tables (filecache,
|
||||
# activity, jobs, state). Reload-only.
|
||||
autovacuum_naptime = "30s";
|
||||
autovacuum_vacuum_scale_factor = 0.05;
|
||||
autovacuum_analyze_scale_factor = 0.025;
|
||||
autovacuum_max_workers = 4;
|
||||
|
||||
# NVMe planner assumptions (README: NVMe OS + data disks).
|
||||
random_page_cost = "1.1";
|
||||
effective_io_concurrency = 200;
|
||||
};
|
||||
};
|
||||
|
||||
# ── Backups ────────────────────────────────────────────────
|
||||
|
||||
Generated
+28
-45
@@ -5,11 +5,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1788871704,
|
||||
"narHash": "sha256-Vtc2SqCB7NOO028+K5JHbpWQ3XVpLyoC75MZQ12l13o=",
|
||||
"lastModified": 1789651044,
|
||||
"narHash": "sha256-4VAbiqMJXW/fgdMqDN4+03PkCa3xRnWi4zEX9J6/QRk=",
|
||||
"owner": "emmanuelrosa",
|
||||
"repo": "btc-clients-nix",
|
||||
"rev": "e14502cba22806341f8c54c6f0c349094830c58b",
|
||||
"rev": "bc71039666a17100c49e67a93e1d7a15f31dee47",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787559586,
|
||||
"narHash": "sha256-onL0VLf9vPllmT0H/OlURIU5r5t5WIEl7t4tVNKT0Nw=",
|
||||
"lastModified": 1788450739,
|
||||
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "9d0d87172c374f89da73c1cfe6d81ae62feac1f1",
|
||||
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1788179970,
|
||||
"narHash": "sha256-r5LmxzIhsu5+oDybatN/HJ8roYOKjb2Apa5xI6v46VU=",
|
||||
"lastModified": 1789563672,
|
||||
"narHash": "sha256-05W7P4/pqgpliOA/HyZM6IkKd6ojI8L5X/x9tgthckI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1db62ab7d2ccf1916bbf7deb61fc9d16f1c4ab49",
|
||||
"rev": "88142f2dc8f2727eec89047694ec8000f92ce542",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -56,27 +56,11 @@
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1788921488,
|
||||
"narHash": "sha256-8+xWRxEkD6l217cIUdRxfeUGS9lQX0hVtUuNVsBaDzk=",
|
||||
"lastModified": 1789885152,
|
||||
"narHash": "sha256-mDNo95riUw8k0MA2Btzj/OuiMcfLKofqIliLYsLbrSY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6aefcda9401be8acc2b74244fb3b37520ea1f0a8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-26.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable_2": {
|
||||
"locked": {
|
||||
"lastModified": 1788807765,
|
||||
"narHash": "sha256-J9oC0bKnkXUrMegqRTXVkyDFJ0gn2U/Qpoo9HgGMQmA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "93108a538f079596c9a16c72cf03e9322782b6dd",
|
||||
"rev": "6d663c0533ff269008fb84e45930151e37c99db9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -88,11 +72,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1788881743,
|
||||
"narHash": "sha256-2V9GZGvPfrNzxFozhI9dcqV+c3QdA8YZrvAAzqEB+dI=",
|
||||
"lastModified": 1789921291,
|
||||
"narHash": "sha256-Ft/BRnIqw1MywFoXydKobjjWmDFgDdYtSpJliE8+yUw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d6524aaca2ff07876657ae2b323f24be4874944b",
|
||||
"rev": "44a91898084f46797b5fac650c7e8c9ac38c43d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -104,11 +88,11 @@
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1787631388,
|
||||
"narHash": "sha256-vMiXptXarfSdJb1Gkc+FYVOAibuBRj7qxGa8z68q1Uw=",
|
||||
"lastModified": 1789724158,
|
||||
"narHash": "sha256-nlKgrm0dsVhOSopKheVBCcOpiIticufPPVLdVOI0euA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ac6b2166e7a9375683b8e98f860f273222337b16",
|
||||
"rev": "0a3468a402c449992505b6a9fc5b06580141b750",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -120,11 +104,11 @@
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1788881743,
|
||||
"narHash": "sha256-2V9GZGvPfrNzxFozhI9dcqV+c3QdA8YZrvAAzqEB+dI=",
|
||||
"lastModified": 1789921291,
|
||||
"narHash": "sha256-Ft/BRnIqw1MywFoXydKobjjWmDFgDdYtSpJliE8+yUw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d6524aaca2ff07876657ae2b323f24be4874944b",
|
||||
"rev": "44a91898084f46797b5fac650c7e8c9ac38c43d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -141,11 +125,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1788190018,
|
||||
"narHash": "sha256-59BAfH0txPAZrPBF4QJqwvUWppD+ICrcjA1LZAmPnrQ=",
|
||||
"lastModified": 1789961561,
|
||||
"narHash": "sha256-2lRgE8XsmXIVmiujmHVaCy5TrBUSblILNT5vYOj/Ed0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixvim",
|
||||
"rev": "41844750e55f17b1385d5b09ca7ade5f11f49506",
|
||||
"rev": "bcb5f577a36565bda07d7b81346b73cad8618d16",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -165,15 +149,14 @@
|
||||
},
|
||||
"sovran-bitcoin": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nixpkgs-stable": "nixpkgs-stable_2"
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1788921077,
|
||||
"narHash": "sha256-k2i55M0lK3xzjsJKS/kOhQHSf8479r6RYEllnICxggg=",
|
||||
"lastModified": 1790031910,
|
||||
"narHash": "sha256-aqwWD6FfKxhF7edo/ryn2Um8yMCr/MN5HXNIot4KB2k=",
|
||||
"owner": "naturallaw777",
|
||||
"repo": "Sovran_Bitcoin",
|
||||
"rev": "7c4d5b509c0533ea48192146f987182668bf42dc",
|
||||
"rev": "4acd272bec53cb88300535d6238e72ad20bd90f1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
nixvim.url = "github:nix-community/nixvim";
|
||||
btc-clients.url = "github:emmanuelrosa/btc-clients-nix";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-26.05";
|
||||
|
||||
# Bitcoin / Lightning stack — standalone flake, consumed as a module.
|
||||
sovran-bitcoin.url = "github:naturallaw777/Sovran_Bitcoin";
|
||||
};
|
||||
|
||||
@@ -19,24 +17,6 @@
|
||||
system = prev.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
|
||||
# Pin LiveKit to 1.13.6: element-calling.nix sets
|
||||
# rtc.advertise_internal_ip, which gives LAN callers a host candidate
|
||||
# so calls work on Wi-Fi without the router needing NAT-hairpin. That
|
||||
# flag is only honoured when node_ip is set manually from LiveKit
|
||||
# v1.13.6 (mediatransportutil f234b53); nixpkgs-unstable currently
|
||||
# ships 1.13.5. Remove this override once nixpkgs-unstable reaches
|
||||
# >= 1.13.6.
|
||||
livekit = prev.livekit.overrideAttrs (old: {
|
||||
version = "1.13.6";
|
||||
src = prev.fetchFromGitHub {
|
||||
owner = "livekit";
|
||||
repo = "livekit";
|
||||
rev = "v1.13.6";
|
||||
hash = "sha256-sUAx6ooeEUUqot5xuZv7xiQa3DdRFVULteTwYgFUzCI=";
|
||||
};
|
||||
vendorHash = "sha256-nOGSmoNuQQm/sIVI1HojsiS4GkbhA68uYMQ6X7d4a5Q=";
|
||||
});
|
||||
};
|
||||
in
|
||||
{
|
||||
@@ -77,14 +57,5 @@
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
checks.x86_64-linux = let
|
||||
pkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
};
|
||||
in {
|
||||
# Bitcoin hardening and package checks now live in the Sovran_Bitcoin flake.
|
||||
# Run them with: nix build github:naturallaw777/Sovran_Bitcoin#checks.x86_64-linux
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+112
-3
@@ -3,10 +3,22 @@
|
||||
lib.mkIf config.sovran_systemsOS.services.nextcloud {
|
||||
|
||||
# ── PostgreSQL database ───────────────────────────────────
|
||||
# Cluster-wide tuning (shared_buffers, autovacuum) lives in
|
||||
# configuration.nix so it is shared with Matrix Synapse.
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# ── Redis for Nextcloud distributed cache + file locking ───
|
||||
# Nextcloud does not recommend APCu for memcache.locking in production.
|
||||
# TCP on localhost avoids unix-socket permission juggling with the caddy user.
|
||||
# Scoped to Nextcloud only — Synapse / MariaDB / Bitcoin are unaffected.
|
||||
services.redis.servers.nextcloud = {
|
||||
enable = true;
|
||||
bind = "127.0.0.1";
|
||||
port = 6379;
|
||||
};
|
||||
|
||||
# ── Auto-generate DB password and initialize ──────────────
|
||||
systemd.services.nextcloud-db-init = {
|
||||
description = "Initialize Nextcloud PostgreSQL database with auto-generated password";
|
||||
@@ -47,14 +59,20 @@ lib.mkIf config.sovran_systemsOS.services.nextcloud {
|
||||
if ! psql -U postgres -lqt | cut -d \| -f 1 | grep -qw "nextclouddb"; then
|
||||
psql -U postgres -c "CREATE DATABASE nextclouddb WITH OWNER ncusr TEMPLATE template0 LC_COLLATE = 'C' LC_CTYPE = 'C';"
|
||||
fi
|
||||
|
||||
# NOTE: autovacuum GUCs are SIGHUP-context, so they cannot be set
|
||||
# per-database — ALTER DATABASE ... SET rejects them with
|
||||
# 'parameter "..." cannot be changed now'. They are set
|
||||
# cluster-wide in configuration.nix instead, which already covers
|
||||
# both nextclouddb and matrix-synapse.
|
||||
'';
|
||||
};
|
||||
|
||||
# ── Fully automated Nextcloud setup ───────────────────────
|
||||
systemd.services.nextcloud-init = {
|
||||
description = "Download, extract, and fully configure Nextcloud";
|
||||
after = [ "network-online.target" "postgresql.service" "phpfpm-nextcloud.service" "nextcloud-db-init.service" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" "postgresql.service" "phpfpm-nextcloud.service" "nextcloud-db-init.service" "redis-nextcloud.service" ];
|
||||
wants = [ "network-online.target" "redis-nextcloud.service" ];
|
||||
requires = [ "postgresql.service" "nextcloud-db-init.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
@@ -150,7 +168,11 @@ lib.mkIf config.sovran_systemsOS.services.nextcloud {
|
||||
php $INSTALL_DIR/occ config:system:set default_phone_region --value='US'
|
||||
php $INSTALL_DIR/occ config:system:set maintenance_window_start --type=integer --value=1
|
||||
php $INSTALL_DIR/occ config:system:set memcache.local --value='\OC\Memcache\APCu'
|
||||
php $INSTALL_DIR/occ config:system:set memcache.locking --value='\OC\Memcache\APCu'
|
||||
php $INSTALL_DIR/occ config:system:set memcache.distributed --value='\OC\Memcache\Redis'
|
||||
php $INSTALL_DIR/occ config:system:set memcache.locking --value='\OC\Memcache\Redis'
|
||||
php $INSTALL_DIR/occ config:system:set redis host --value='127.0.0.1'
|
||||
php $INSTALL_DIR/occ config:system:set redis port --type=integer --value=6379
|
||||
php $INSTALL_DIR/occ config:system:set redis timeout --value='1.5'
|
||||
php $INSTALL_DIR/occ config:system:set server_id --value='$SERVER_ID'
|
||||
php $INSTALL_DIR/occ background:cron
|
||||
"
|
||||
@@ -247,6 +269,93 @@ CREDS
|
||||
'';
|
||||
};
|
||||
|
||||
# ── Migrate existing installs to Redis locking ────────────
|
||||
# nextcloud-init only runs on fresh installs (ConditionPathExists
|
||||
# !config.php), so pre-existing / pre-Sovran installs would keep
|
||||
# APCu locking forever. This one-shot is idempotent and safe to
|
||||
# re-run on every boot — occ just overwrites the same values.
|
||||
systemd.services.nextcloud-redis-migrate = {
|
||||
description = "Point existing Nextcloud installs at Redis locking";
|
||||
after = [ "postgresql.service" "redis-nextcloud.service" "phpfpm-nextcloud.service" ];
|
||||
wants = [ "redis-nextcloud.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
unitConfig = {
|
||||
ConditionPathExists = [
|
||||
"/var/lib/www/nextcloud/occ"
|
||||
"/var/lib/www/nextcloud/config/config.php"
|
||||
];
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
path = with pkgs; [ coreutils shadow ];
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
INSTALL_DIR="/var/lib/www/nextcloud"
|
||||
# Wait briefly for Redis (TCP localhost:6379).
|
||||
for i in $(seq 1 15); do
|
||||
if (echo > /dev/tcp/127.0.0.1/6379) >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
/run/wrappers/bin/su -s /bin/sh caddy -c "
|
||||
php $INSTALL_DIR/occ config:system:set memcache.local --value='\OC\Memcache\APCu'
|
||||
php $INSTALL_DIR/occ config:system:set memcache.distributed --value='\OC\Memcache\Redis'
|
||||
php $INSTALL_DIR/occ config:system:set memcache.locking --value='\OC\Memcache\Redis'
|
||||
php $INSTALL_DIR/occ config:system:set redis host --value='127.0.0.1'
|
||||
php $INSTALL_DIR/occ config:system:set redis port --type=integer --value=6379
|
||||
php $INSTALL_DIR/occ config:system:set redis timeout --value='1.5'
|
||||
"
|
||||
'';
|
||||
};
|
||||
|
||||
# ── Recurring DB maintenance (Nextcloud 35 checks) ───────────
|
||||
# nextcloud-init runs db:add-missing-indices exactly once. Upgrades
|
||||
# (e.g. to NC35) and later app installs (Mail, Guests) add tables
|
||||
# like oc_mail_tags / oc_guests_users that then seq-scan forever.
|
||||
# Weekly: VACUUM ANALYZE (dead tuples) + backfill missing indices.
|
||||
# Scoped to nextclouddb only — matrix-synapse is untouched.
|
||||
systemd.services.nextcloud-db-maintenance = {
|
||||
description = "Nextcloud DB maintenance: VACUUM + missing indices";
|
||||
after = [ "postgresql.service" "redis-nextcloud.service" "phpfpm-nextcloud.service" ];
|
||||
wants = [ "postgresql.service" ];
|
||||
unitConfig = {
|
||||
ConditionPathExists = [
|
||||
"/var/lib/www/nextcloud/occ"
|
||||
"/var/lib/www/nextcloud/config/config.php"
|
||||
];
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
path = [ config.services.postgresql.package pkgs.coreutils pkgs.shadow ];
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
INSTALL_DIR="/var/lib/www/nextcloud"
|
||||
echo "Vacuuming nextclouddb..."
|
||||
psql -U postgres -d nextclouddb -c "VACUUM (ANALYZE);"
|
||||
echo "Backfilling Nextcloud indices..."
|
||||
/run/wrappers/bin/su -s /bin/sh caddy -c "
|
||||
php $INSTALL_DIR/occ db:add-missing-indices
|
||||
php $INSTALL_DIR/occ db:add-missing-columns
|
||||
php $INSTALL_DIR/occ db:add-missing-primary-keys
|
||||
"
|
||||
echo "Nextcloud DB maintenance complete."
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.nextcloud-db-maintenance = {
|
||||
description = "Weekly Nextcloud DB maintenance";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "Sun 03:30";
|
||||
Persistent = true;
|
||||
RandomizedDelaySec = "30m";
|
||||
};
|
||||
};
|
||||
|
||||
services.cron.systemCronJobs = [
|
||||
"*/5 * * * * caddy /run/current-system/sw/bin/php -f /var/lib/www/nextcloud/cron.php"
|
||||
];
|
||||
|
||||
+56
-14
@@ -1,29 +1,70 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
# ── Shared PHP for Nextcloud + WordPress ──────────────────────────────────────
|
||||
#
|
||||
# One interpreter (with one extension set and one php.ini) is shared by the
|
||||
# phpfpm-nextcloud and phpfpm-wordpress pools, the Nextcloud cron job and the
|
||||
# occ / wp-cli helper scripts. Every consumer must reference
|
||||
# config.sovran_systemsOS.phpPackage (or /run/current-system/sw/bin/php) so
|
||||
# that the CLI and the FPM pools always run the *same* PHP.
|
||||
#
|
||||
# Version policy (September 2026):
|
||||
# • Nextcloud 35 supports PHP 8.3 / 8.4 / 8.5 and recommends 8.5. Its setup
|
||||
# check flags 8.3 as "deprecated since Nextcloud 35" and warns that
|
||||
# Nextcloud 36 may require at least 8.4.
|
||||
# • WordPress 6.9 / 7.0 fully support PHP 8.4 and 8.5.
|
||||
# • PHP 8.3 has been security-only since 2025-12-31; PHP 8.4 leaves active
|
||||
# support on 2026-12-31; PHP 8.5 is actively supported until 2027-12-31.
|
||||
#
|
||||
# To fall back to PHP 8.4 (nixpkgs' current default `pkgs.php`) change only
|
||||
# the `phpBase` line below.
|
||||
|
||||
let
|
||||
phpBase = pkgs.php85;
|
||||
|
||||
custom-php = phpBase.buildEnv {
|
||||
# `enabled` is nixpkgs' default extension set. It already contains every
|
||||
# module Nextcloud lists as required or recommended (ctype, curl, dom,
|
||||
# fileinfo, gd, intl, mbstring, openssl, posix, session, simplexml,
|
||||
# xmlreader, xmlwriter, zip, zlib, pdo_pgsql, pdo_mysql, bcmath, gmp,
|
||||
# exif, sodium, sysvsem, pcntl, ...). OPcache is compiled into PHP >= 8.5
|
||||
# and no longer appears as a separate extension.
|
||||
extensions = { enabled, all }: enabled ++ (with all; [
|
||||
bz2 # Nextcloud: bz2 archive support
|
||||
apcu # Nextcloud: memcache.local (apc.enable_cli=1 below is mandatory for occ + cron)
|
||||
redis # Nextcloud: memcache.distributed / file locking once a Redis server is configured
|
||||
imagick # Nextcloud: previews + theming (nixpkgs ImageMagick is built with SVG support)
|
||||
memcached # WordPress object-cache plugins (legacy option for Nextcloud)
|
||||
]);
|
||||
|
||||
custom-php = pkgs.php83.buildEnv {
|
||||
extensions = { enabled, all }: enabled ++ (with all; [ bz2 apcu redis imagick memcached ]);
|
||||
extraConfig = ''
|
||||
; ── Error handling (production) ─────────────────────────────────
|
||||
display_errors = Off
|
||||
display_startup_errors = Off
|
||||
log_errors = On
|
||||
|
||||
display_errors = On
|
||||
display_startup_errors = On
|
||||
; ── Limits ──────────────────────────────────────────────────────
|
||||
max_execution_time = 10000
|
||||
max_input_time = 3000
|
||||
memory_limit = 1G;
|
||||
opcache.enable=1;
|
||||
opcache.memory_consumption=512;
|
||||
opcache_revalidate_freq = 240;
|
||||
opcache.max_accelerated_files=20000;
|
||||
memory_limit = 1G
|
||||
post_max_size = 3G
|
||||
upload_max_filesize = 3G
|
||||
apc.enable_cli=1
|
||||
opcache.interned_strings_buffer = 192
|
||||
redis.session.locking_enabled=1
|
||||
redis.session.lock_retries=-1
|
||||
redis.session.lock_wait_time=10000
|
||||
|
||||
; ── OPcache (Nextcloud "Server tuning" recommendations) ─────────
|
||||
opcache.enable = 1
|
||||
opcache.memory_consumption = 512
|
||||
opcache.interned_strings_buffer = 192
|
||||
opcache.max_accelerated_files = 20000
|
||||
opcache.revalidate_freq = 240
|
||||
opcache.save_comments = 1
|
||||
|
||||
; ── APCu ────────────────────────────────────────────────────────
|
||||
apc.enable_cli = 1
|
||||
|
||||
; ── phpredis session locking (only used with session.save_handler = redis)
|
||||
redis.session.locking_enabled = 1
|
||||
redis.session.lock_retries = -1
|
||||
redis.session.lock_wait_time = 10000
|
||||
'';
|
||||
};
|
||||
in
|
||||
@@ -55,3 +96,4 @@ in
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -94,16 +94,23 @@ EOF
|
||||
# ── Synapse service ─────────────────────────────────────────
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
# cache-memory provides cache-size statistics for the autotuning below
|
||||
# (in addition to the NixOS defaults).
|
||||
extras = [ "systemd" "postgres" "url-preview" "cache-memory" ];
|
||||
extraConfigFiles = [
|
||||
"/run/matrix-synapse/runtime-config.yaml"
|
||||
];
|
||||
settings = {
|
||||
database = {
|
||||
name = "psycopg2";
|
||||
# Recycle pooled connections less often (fewer reconnects).
|
||||
txn_limit = 10000;
|
||||
args = {
|
||||
host = "localhost";
|
||||
database = "matrix-synapse";
|
||||
user = "matrix-synapse";
|
||||
cp_min = 5;
|
||||
cp_max = 15;
|
||||
};
|
||||
};
|
||||
push.include_content = false;
|
||||
@@ -120,6 +127,32 @@ EOF
|
||||
];
|
||||
presence.enabled = true;
|
||||
enable_registration = false;
|
||||
# ── Performance (32 GB Server + Desktop) ─────────────────
|
||||
# Synapse trades RAM for fewer Postgres round-trips; most RAM goes
|
||||
# to caches. Stock is global_factor 0.5 + 10K event cache, which
|
||||
# leaves syncs hitting the database on every request.
|
||||
# Deliberately unchanged: presence and URL previews stay enabled —
|
||||
# disabling them is faster but changes user-visible behavior.
|
||||
event_cache_size = "100K";
|
||||
caches = {
|
||||
global_factor = 4.0;
|
||||
expire_caches = true;
|
||||
cache_entry_ttl = "30m";
|
||||
sync_response_cache_duration = "2m";
|
||||
cache_autotuning = {
|
||||
max_cache_memory_usage = "2G";
|
||||
target_cache_memory_usage = "1G";
|
||||
min_cache_ttl = "30s";
|
||||
};
|
||||
per_cache_factors = {
|
||||
# Hot paths for /sync and room joins.
|
||||
get_users_in_room = 3.0;
|
||||
get_current_state_ids = 3.0;
|
||||
get_unread_event_push_actions_by_room_for_user = 5.0;
|
||||
};
|
||||
};
|
||||
# Fewer GC pauses at the cost of a little more memory.
|
||||
gc_thresholds = [ 1500 20 10 ];
|
||||
listeners = [
|
||||
{
|
||||
port = 8008;
|
||||
|
||||
Reference in New Issue
Block a user