14 Commits
Author SHA1 Message Date
naturallaw777 70ccf1eba1 chore(release): prepare v1.1.7 2026-09-21 18:09:10 -05:00
naturallaw777 f6caa2ff32 updated nixpkgs 2026-09-21 18:07:21 -05:00
Sovran Contributor 8bc325b148 postgresql: drop per-database autovacuum ALTERs (rejected by Postgres)
Follow-up to the previous two commits: the ALTER DATABASE ... SET
autovacuum_* commands fail at boot with

  ERROR: parameter "autovacuum_vacuum_scale_factor" cannot be changed now

and take matrix-synapse-db-tune.service (and nextcloud-db-init.service)
down with them.

Root cause: ALTER DATABASE/ROLE ... SET validates through
set_config_option() with an interactive context, and guc.c rejects any
PGC_SIGHUP parameter set that way. All autovacuum_* GUCs are
SIGHUP-context, so per-database scoping is impossible for them — only
USERSET-level parameters (e.g. work_mem, statement_timeout) can be set
per-database.

Nothing is lost: the same values are already set cluster-wide in
configuration.nix, which covers both nextclouddb and matrix-synapse.
Remove the ALTERs from nextcloud-db-init and delete the now-purposeless
matrix-synapse-db-tune service.
2026-09-21 14:21:01 -05:00
Sovran Contributor e31094c194 synapse: performance tuning for 32 GB Server+Desktop hosts
Monolith Synapse spends most of its RAM on caches to avoid Postgres
round-trips, but Sovran ships stock cache settings (global_factor 0.5,
10K event cache, no autotuning) and a default 5-connection DB pool.

- caches.global_factor 4.0 + 100K event cache + autotuning capped at
  2G (target 1G), with boosts for the /sync and room-join hot paths.
- DB pool cp_min 5 / cp_max 15, txn_limit 10000 (fewer reconnects).
- gc_thresholds raised to cut GC pauses on a 32 GB box.
- cache-memory extra for cache-size statistics.
- Per-database autovacuum (ALTER DATABASE, scoped to matrix-synapse)
  matching the nextclouddb tuning.

Deliberately unchanged: presence and URL previews stay enabled
(disabling them is faster but user-visible), and no workers — monolith
is the right call under ~100 users. Workers would need Redis
replication, the redis extra, and Caddy reverse-proxy rework; revisit
if federation load ever justifies it.
2026-09-21 14:00:19 -05:00
Sovran Contributor 09d4cc9b83 nextcloud, postgresql: fix Nextcloud 35 DB warnings on 32 GB hosts
Nextcloud 35's Database checks flag three Performance issues out of the
box: buffer cache hit ratio ~96% (wants 99%+), 100k+ dead tuples, and
million-plus sequential scans on oc_mail_tags / oc_guests_users.

Root causes in Sovran: stock 128MB shared_buffers, stock 60s autovacuum
naptime, APCu file locking, and db:add-missing-indices running exactly
once at install time (never on upgrades or app installs).

Size Postgres for the README's Server + Desktop recommendation (32 GB
RAM, NVMe): 2GB shared_buffers, 12GB effective_cache_size, 512MB
maintenance_work_mem, 32MB work_mem, 4GB max_wal_size, 30s autovacuum
naptime with 4 workers. shared_buffers stays below the 25% rule because
Postgres shares the box with bitcoind, Electrs, LND, MariaDB and PHP-FPM.

Scope the aggressive autovacuum to nextclouddb via ALTER DATABASE so the
shared matrix-synapse DB keeps the milder cluster defaults.

Add a local Redis (127.0.0.1:6379, Nextcloud only) and move
memcache.distributed/locking to Redis; migrate existing installs with a
one-shot since nextcloud-init never re-runs.

Add a weekly nextcloud-db-maintenance timer (VACUUM ANALYZE +
db:add-missing-*) so upgrades and later app installs can't regress the
checks again.

Note: shared_buffers needs one 'systemctl restart postgresql', which
briefly takes down both Nextcloud and Matrix. Everything else is
reload-only or scoped to nextclouddb.
2026-09-21 13:59:52 -05:00
naturallaw777 3341659a0c updated to php85 and fixes 2026-09-19 16:24:57 -05:00
Sovran Systems 32e1119e33 Updated to proper syntax to prevent build errors. 2026-09-17 16:28:37 -05:00
Sovran Systems 0f7ef8422d Clean up flake.nix by removing comments and LiveKit override
Removed comments and overridden attributes for LiveKit version in flake.nix.
2026-09-17 16:19:37 -05:00
naturallaw777 dd6042928a updated flake lock which contains Bisq 1.10.8 and Bisq2 2.1.13 2026-09-17 15:37:28 -05:00
naturallaw777 74405b2ffc chore(release): prepare v1.1.6 2026-09-15 15:17:10 -05:00
naturallaw777 258da6a337 updated nix packages includes the new mempool version 2026-09-15 14:15:20 -05:00
Sovran Systems 73ab3f40c1 Rename 'The Sovran Hub' to 'The Hub' in README 2026-09-09 11:19:50 -05:00
Sovran Systems 0768712bf7 Rename 'Sovran Hub' to 'The Hub' in README
Updated references from 'Sovran Hub' to 'The Hub' for consistency.
2026-09-09 11:19:03 -05:00
naturallaw777 2ac30dc10a docs: update Sovran Hub screenshot to the v1.1.5 redesign
Replace the pre-redesign Hub capture with the new welcome dashboard
introduced in v1.1.5 — the default view showing system status, Bitcoin
sync, and the update card at a glance.

The capture is rendered from the real Hub frontend (Server + Desktop
role, demo credentials/domains) at 1920x1080, and doubles as the hero
shot of the marketing kit.  Also drops the asset from 391 KB to 59 KB
with no visible loss.
2026-09-09 11:04:57 -05:00
10 changed files with 317 additions and 113 deletions
+30
View File
@@ -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 ## [1.1.5] - 2026-09-09
### Added ### Added
+18 -18
View File
@@ -21,9 +21,9 @@ Lightning infrastructure, private cloud, and communications platform when you
are ready. are ready.
[Visit the Website](https://sovransystems.com) · [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) · [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) [Build from Source](#build-from-source)
<img src="assets/desktop-screenshot.webp" alt="Sovran_SystemsOS private Bitcoin desktop" width="800" /> <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) - [What is included](#what-is-included)
- [Three modes](#three-modes) - [Three modes](#three-modes)
- [Use it your way](#use-it-your-way) - [Use it your way](#use-it-your-way)
- [The Sovran Hub](#the-sovran-hub) - [The Hub](#the-hub)
- [Install Sovran_SystemsOS](#install-sovran_systemsos) - [Install Sovran_SystemsOS](#install-sovran_systemsos)
- [For developers](#for-developers) - [For developers](#for-developers)
- [Development workflow](#development-workflow) - [Development workflow](#development-workflow)
@@ -264,11 +264,11 @@ infrastructure behind them.
--- ---
## The Sovran Hub ## The Hub
### Your private infrastructure, controlled from any screen. ### 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 local desktop application and a private web interface served directly by your
Sovran_SystemsOS machine. Nothing needs to be installed on the device opening 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. 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 - Reach your Bitcoin tools, private cloud, and communications
- Perform supported system operations without everyday terminal commands - 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 ### Example home setup
@@ -300,7 +300,7 @@ From one place, the Hub helps you:
┌──────────────────────────┐ ┌──────────────────────────┐
│ Sovran_SystemsOS │ │ Sovran_SystemsOS │
│ │ │ │
│ • Sovran Hub │ │ • The Hub │
│ • Bitcoin node │ │ • Bitcoin node │
│ • Sparrow Wallet │ │ • Sparrow Wallet │
│ • Bisq and Bisq 2 │ │ • 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 ### 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.7.iso](https://downloads.sovransystems.com/Sovran_SystemsOS-1.1.7.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.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 The download may take some time. Do not rename or modify the ISO before
verifying it, and keep both files in the same folder. 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: Open a terminal in the download folder and run:
```bash ```bash
sha256sum --check Sovran_SystemsOS-1.1.5.iso.sha256 sha256sum --check Sovran_SystemsOS-1.1.7.iso.sha256
``` ```
A successful comparison reports: A successful comparison reports:
```text ```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. against the checksum file manually.
</details> </details>
@@ -384,11 +384,11 @@ against the checksum file manually.
Open Terminal in the download folder and run: Open Terminal in the download folder and run:
```bash ```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 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> </details>
@@ -398,7 +398,7 @@ Compare the value shown in Terminal with the value inside
Open PowerShell in the download folder and run: Open PowerShell in the download folder and run:
```powershell ```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. 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 1. Download and install [Balena Etcher](https://etcher.balena.io), then
connect the USB drive. 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 3. Choose **Select target**, select the USB drive, and review your selection
carefully. carefully.
4. Choose **Flash** and wait for the writing and verification process to 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. ## Privacy. Sovereignty. Bitcoin.
[Visit Sovran Systems](https://sovransystems.com) · [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) [View the License](LICENSE)
</div> </div>
+1 -1
View File
@@ -1 +1 @@
1.1.5 1.1.7
Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 59 KiB

+36
View File
@@ -165,6 +165,14 @@
programs.fish = { enable = true; promptInit = "fastfetch"; }; programs.fish = { enable = true; promptInit = "fastfetch"; };
# ── PostgreSQL base ──────────────────────────────────────── # ── 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 = { services.postgresql = {
enable = true; enable = true;
authentication = lib.mkForce '' authentication = lib.mkForce ''
@@ -172,6 +180,34 @@
host all all 127.0.0.1/32 trust host all all 127.0.0.1/32 trust
host all all ::1/128 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 ──────────────────────────────────────────────── # ── Backups ────────────────────────────────────────────────
Generated
+28 -45
View File
@@ -5,11 +5,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1788871704, "lastModified": 1789651044,
"narHash": "sha256-Vtc2SqCB7NOO028+K5JHbpWQ3XVpLyoC75MZQ12l13o=", "narHash": "sha256-4VAbiqMJXW/fgdMqDN4+03PkCa3xRnWi4zEX9J6/QRk=",
"owner": "emmanuelrosa", "owner": "emmanuelrosa",
"repo": "btc-clients-nix", "repo": "btc-clients-nix",
"rev": "e14502cba22806341f8c54c6f0c349094830c58b", "rev": "bc71039666a17100c49e67a93e1d7a15f31dee47",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -26,11 +26,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1787559586, "lastModified": 1788450739,
"narHash": "sha256-onL0VLf9vPllmT0H/OlURIU5r5t5WIEl7t4tVNKT0Nw=", "narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "9d0d87172c374f89da73c1cfe6d81ae62feac1f1", "rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -41,11 +41,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1788179970, "lastModified": 1789563672,
"narHash": "sha256-r5LmxzIhsu5+oDybatN/HJ8roYOKjb2Apa5xI6v46VU=", "narHash": "sha256-05W7P4/pqgpliOA/HyZM6IkKd6ojI8L5X/x9tgthckI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "1db62ab7d2ccf1916bbf7deb61fc9d16f1c4ab49", "rev": "88142f2dc8f2727eec89047694ec8000f92ce542",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -56,27 +56,11 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1788921488, "lastModified": 1789885152,
"narHash": "sha256-8+xWRxEkD6l217cIUdRxfeUGS9lQX0hVtUuNVsBaDzk=", "narHash": "sha256-mDNo95riUw8k0MA2Btzj/OuiMcfLKofqIliLYsLbrSY=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6aefcda9401be8acc2b74244fb3b37520ea1f0a8", "rev": "6d663c0533ff269008fb84e45930151e37c99db9",
"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",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -88,11 +72,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1788881743, "lastModified": 1789921291,
"narHash": "sha256-2V9GZGvPfrNzxFozhI9dcqV+c3QdA8YZrvAAzqEB+dI=", "narHash": "sha256-Ft/BRnIqw1MywFoXydKobjjWmDFgDdYtSpJliE8+yUw=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d6524aaca2ff07876657ae2b323f24be4874944b", "rev": "44a91898084f46797b5fac650c7e8c9ac38c43d4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -104,11 +88,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1787631388, "lastModified": 1789724158,
"narHash": "sha256-vMiXptXarfSdJb1Gkc+FYVOAibuBRj7qxGa8z68q1Uw=", "narHash": "sha256-nlKgrm0dsVhOSopKheVBCcOpiIticufPPVLdVOI0euA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ac6b2166e7a9375683b8e98f860f273222337b16", "rev": "0a3468a402c449992505b6a9fc5b06580141b750",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -120,11 +104,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1788881743, "lastModified": 1789921291,
"narHash": "sha256-2V9GZGvPfrNzxFozhI9dcqV+c3QdA8YZrvAAzqEB+dI=", "narHash": "sha256-Ft/BRnIqw1MywFoXydKobjjWmDFgDdYtSpJliE8+yUw=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d6524aaca2ff07876657ae2b323f24be4874944b", "rev": "44a91898084f46797b5fac650c7e8c9ac38c43d4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -141,11 +125,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1788190018, "lastModified": 1789961561,
"narHash": "sha256-59BAfH0txPAZrPBF4QJqwvUWppD+ICrcjA1LZAmPnrQ=", "narHash": "sha256-2lRgE8XsmXIVmiujmHVaCy5TrBUSblILNT5vYOj/Ed0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixvim", "repo": "nixvim",
"rev": "41844750e55f17b1385d5b09ca7ade5f11f49506", "rev": "bcb5f577a36565bda07d7b81346b73cad8618d16",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -165,15 +149,14 @@
}, },
"sovran-bitcoin": { "sovran-bitcoin": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_4", "nixpkgs": "nixpkgs_4"
"nixpkgs-stable": "nixpkgs-stable_2"
}, },
"locked": { "locked": {
"lastModified": 1788921077, "lastModified": 1790031910,
"narHash": "sha256-k2i55M0lK3xzjsJKS/kOhQHSf8479r6RYEllnICxggg=", "narHash": "sha256-aqwWD6FfKxhF7edo/ryn2Um8yMCr/MN5HXNIot4KB2k=",
"owner": "naturallaw777", "owner": "naturallaw777",
"repo": "Sovran_Bitcoin", "repo": "Sovran_Bitcoin",
"rev": "7c4d5b509c0533ea48192146f987182668bf42dc", "rev": "4acd272bec53cb88300535d6238e72ad20bd90f1",
"type": "github" "type": "github"
}, },
"original": { "original": {
-29
View File
@@ -6,8 +6,6 @@
nixvim.url = "github:nix-community/nixvim"; nixvim.url = "github:nix-community/nixvim";
btc-clients.url = "github:emmanuelrosa/btc-clients-nix"; btc-clients.url = "github:emmanuelrosa/btc-clients-nix";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-26.05"; 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"; sovran-bitcoin.url = "github:naturallaw777/Sovran_Bitcoin";
}; };
@@ -19,24 +17,6 @@
system = prev.stdenv.hostPlatform.system; system = prev.stdenv.hostPlatform.system;
config.allowUnfree = true; 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 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
View File
@@ -3,10 +3,22 @@
lib.mkIf config.sovran_systemsOS.services.nextcloud { lib.mkIf config.sovran_systemsOS.services.nextcloud {
# ── PostgreSQL database ─────────────────────────────────── # ── PostgreSQL database ───────────────────────────────────
# Cluster-wide tuning (shared_buffers, autovacuum) lives in
# configuration.nix so it is shared with Matrix Synapse.
services.postgresql = { services.postgresql = {
enable = true; 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 ────────────── # ── Auto-generate DB password and initialize ──────────────
systemd.services.nextcloud-db-init = { systemd.services.nextcloud-db-init = {
description = "Initialize Nextcloud PostgreSQL database with auto-generated password"; 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 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';" psql -U postgres -c "CREATE DATABASE nextclouddb WITH OWNER ncusr TEMPLATE template0 LC_COLLATE = 'C' LC_CTYPE = 'C';"
fi 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 ─────────────────────── # ── Fully automated Nextcloud setup ───────────────────────
systemd.services.nextcloud-init = { systemd.services.nextcloud-init = {
description = "Download, extract, and fully configure Nextcloud"; description = "Download, extract, and fully configure Nextcloud";
after = [ "network-online.target" "postgresql.service" "phpfpm-nextcloud.service" "nextcloud-db-init.service" ]; after = [ "network-online.target" "postgresql.service" "phpfpm-nextcloud.service" "nextcloud-db-init.service" "redis-nextcloud.service" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" "redis-nextcloud.service" ];
requires = [ "postgresql.service" "nextcloud-db-init.service" ]; requires = [ "postgresql.service" "nextcloud-db-init.service" ];
wantedBy = [ "multi-user.target" ]; 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 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 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.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 config:system:set server_id --value='$SERVER_ID'
php $INSTALL_DIR/occ background:cron 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 = [ services.cron.systemCronJobs = [
"*/5 * * * * caddy /run/current-system/sw/bin/php -f /var/lib/www/nextcloud/cron.php" "*/5 * * * * caddy /run/current-system/sw/bin/php -f /var/lib/www/nextcloud/cron.php"
]; ];
+59 -17
View File
@@ -1,29 +1,70 @@
{ config, pkgs, lib, ... }: { 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 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 = '' extraConfig = ''
; Error handling (production)
display_errors = On display_errors = Off
display_startup_errors = On display_startup_errors = Off
log_errors = On
; Limits
max_execution_time = 10000 max_execution_time = 10000
max_input_time = 3000 max_input_time = 3000
memory_limit = 1G; memory_limit = 1G
opcache.enable=1;
opcache.memory_consumption=512;
opcache_revalidate_freq = 240;
opcache.max_accelerated_files=20000;
post_max_size = 3G post_max_size = 3G
upload_max_filesize = 3G upload_max_filesize = 3G
apc.enable_cli=1
; OPcache (Nextcloud "Server tuning" recommendations)
opcache.enable = 1
opcache.memory_consumption = 512
opcache.interned_strings_buffer = 192 opcache.interned_strings_buffer = 192
redis.session.locking_enabled=1 opcache.max_accelerated_files = 20000
redis.session.lock_retries=-1 opcache.revalidate_freq = 240
redis.session.lock_wait_time=10000 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 in
@@ -46,12 +87,13 @@ in
}; };
users.users.php.group = "php"; users.users.php.group = "php";
users.groups.php = {}; users.groups.php = {};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
custom-php custom-php
]; ];
}; };
} }
+33
View File
@@ -94,16 +94,23 @@ EOF
# ── Synapse service ───────────────────────────────────────── # ── Synapse service ─────────────────────────────────────────
services.matrix-synapse = { services.matrix-synapse = {
enable = true; 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 = [ extraConfigFiles = [
"/run/matrix-synapse/runtime-config.yaml" "/run/matrix-synapse/runtime-config.yaml"
]; ];
settings = { settings = {
database = { database = {
name = "psycopg2"; name = "psycopg2";
# Recycle pooled connections less often (fewer reconnects).
txn_limit = 10000;
args = { args = {
host = "localhost"; host = "localhost";
database = "matrix-synapse"; database = "matrix-synapse";
user = "matrix-synapse"; user = "matrix-synapse";
cp_min = 5;
cp_max = 15;
}; };
}; };
push.include_content = false; push.include_content = false;
@@ -120,6 +127,32 @@ EOF
]; ];
presence.enabled = true; presence.enabled = true;
enable_registration = false; 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 = [ listeners = [
{ {
port = 8008; port = 8008;