Files
silverlinux-infra/docs/decisions.md
T

12 KiB

Architecture Decisions

Purpose

This document records important architectural and operational decisions made for SilverLinux.

The goal is to document not only what was implemented, but also why the decision was made.


2026-06-17

Ubuntu 24.04 LTS Selected

Decision:

Use Ubuntu Server 24.04 LTS as the operating system.

Reason:

  • Long-term support
  • Large community
  • Excellent Docker support
  • Familiar administration tools

Status:

Implemented


2026-06-17

Docker Standardization

Decision:

All services should run in Docker containers whenever possible.

Reason:

  • Consistent deployment
  • Easier backups
  • Easier migrations
  • Better isolation

Status:

Implemented


2026-06-17

Nginx Proxy Manager Selected

Decision:

Use Nginx Proxy Manager as the reverse proxy solution.

Reason:

  • Easy SSL management
  • Simple administration
  • User-friendly interface
  • Fast deployment

Status:

Implemented


2026-06-17

Gitea Selected

Decision:

Use Gitea for source control.

Reason:

  • Self-hosted
  • Lightweight
  • GitHub-like experience
  • Excellent Docker support

Status:

Implemented


2026-06-17

PostgreSQL Selected

Decision:

Use PostgreSQL as the central database platform.

Reason:

  • Reliability
  • Mature ecosystem
  • Supports multiple applications
  • Strong backup tooling

Status:

Implemented


2026-06-17

OpenProject Selected

Decision:

Use OpenProject for project management.

Reason:

  • Mature platform
  • Open source
  • Strong planning features
  • Work package management
  • Time tracking

Status:

Implemented


2026-06-21

Plane.so Removed

Decision:

Do not deploy Plane.so.

Reason:

  • OpenProject fully satisfies requirements
  • Reduces maintenance burden
  • Avoids duplicate functionality

Status:

Implemented


2026-06-21

Centralized Secrets Management

Decision:

Originally store shared credentials in a single secrets file.

Location:

Legacy local secrets file

Reason:

  • Avoid secrets in Docker Compose files
  • Easier credential rotation
  • Easier disaster recovery
  • Reduced risk of accidental exposure

Status:

Superseded by Infisical and slcompose

Current state:

  • Standard SilverLinux service secrets are stored in Infisical.
  • slcompose injects secrets into Compose stacks at runtime.
  • The legacy local secrets file should be removed if it still exists.
  • Sentry is the exception and follows the upstream self-hosted Sentry installation pattern.

2026-06-21

OpenID Disabled in Gitea

Decision:

Disable OpenID authentication.

Reason:

  • Not required
  • Reduces attack surface
  • Simplifies authentication model

Status:

Implemented


2026-06-21

Gmail SMTP Selected

Decision:

Use Gmail SMTP for outbound email.

Sender:

noreply@silveressence.net

Reason:

  • Reliable delivery
  • Easy setup
  • Supports application notifications

Status:

Implemented


2026-06-21 - Adopt Gitea Actions + Self-Hosted Runner for Package Publishing

Decision:

  • Replace GitHub Actions with self-hosted Gitea Actions.
  • Execute package publishing on SilverLinux using the global silverlinux-runner.
  • Publish internal NuGet packages to BaGet.
  • Store the runner registration token in Infisical and publishing credentials in Gitea Actions Secrets.
  • Use [Package] in commit messages to request commit-driven package publishing.

Reason:

  • Keep source control, build execution and package hosting inside SilverLinux.
  • Avoid storing credentials in repositories.
  • Provide a simple, explicit package-release convention.

Status:

Accepted

2026-06-21 - BaGet Secret Storage

Decision:

The BaGet API key is currently stored directly in the BaGet Docker Compose configuration.

Reason:

  • Simplicity during initial deployment.

Current Plan:

Move the API key into the centralized SilverLinux secrets management system:

Infisical

when the BaGet deployment is fully aligned with the standard slcompose pattern.


2026-06-22 - Deploy Microsoft SQL Server Express Alongside PostgreSQL

Decision:

  • Run Microsoft SQL Server 2022 Express alongside PostgreSQL.
  • Attach MSSQL only to the internal Docker network.
  • Do not publish port 1433 or route MSSQL through the reverse proxy.
  • Store MSSQL_SA_PASSWORD in Infisical.

Reason:

  • Support Silver projects that require Microsoft SQL Server compatibility.
  • Allow both database platforms to coexist without exposing database ports.

Status:

Implemented

2026-06-22 - Select DbGate for Database Administration

Decision:

  • Use DbGate to administer Microsoft SQL Server and PostgreSQL.
  • Connect DbGate to both the internal and proxy Docker networks.
  • Publish only the DbGate web interface through Nginx Proxy Manager.
  • Require DbGate authentication and HTTPS.

Reason:

  • Provides one lightweight, modern browser interface for both database platforms.
  • Keeps PostgreSQL and MSSQL private.

Follow-up:

Move the DbGate password from any legacy server-side Compose configuration to Infisical.

Status:

Implemented

2026-06-24 - Formalize Multi-Network Segmentation

Decision:

  • Treat SilverLinux as a three-layer Docker network architecture.
  • Use internal for private databases and backend service traffic.
  • Use proxy for public HTTP and HTTPS services routed through Nginx Proxy Manager.
  • Use isolated stack networks for Jitsi, Xray and CI/CD runner traffic where the active runtime attachments support it.

Reason:

  • Keep databases private while allowing selected web interfaces to be public.
  • Reduce unnecessary cross-service connectivity.
  • Make specialized infrastructure stacks easier to reason about and audit.

Status:

Accepted

2026-06-24 - Confirm Nginx Proxy Manager as the Single Reverse Proxy

Decision:

Use Nginx Proxy Manager as the sole reverse proxy and SSL termination layer for SilverLinux HTTP and HTTPS services.

Reason:

  • The active platform uses Nginx Proxy Manager for domain routing.
  • No Traefik or alternate reverse proxy is active.
  • A single proxy layer keeps exposure and certificate management centralized.

Status:

Confirmed

2026-06-24 - Add Xray Connectivity Layer

Decision:

  • Classify Xray as a network tunneling and connectivity layer.
  • Attach Xray to the proxy network for public endpoint access.
  • Keep xray_default documented as the Compose-created Xray stack network.
  • Monitor the service as an exposed connectivity endpoint rather than as an application backend.

Reason:

  • Improve connectivity stability to SilverLinux.
  • Support secure long-distance connection paths.
  • Keep tunneling concerns separate from application and database services.

Status:

Accepted

Runtime Note:

The 2026-06-24 Docker snapshot showed the running xray container attached to proxy only. The xray_default network existed but had no running containers attached.


2026-06-24 - Confirm Jitsi Meet Is Fully Deployed

Decision:

Treat the Jitsi Meet stack as an operational isolated collaboration stack.

Components:

  • jitsi-web
  • jitsi-jvb
  • jitsi-jicofo
  • jitsi-prosody

Networks:

  • proxy
  • jitsi-docker-jitsi-meet-aa76415_meet.jitsi

Reason:

  • Jitsi Web is expected to be public.
  • Internal Jitsi components should remain isolated inside the Jitsi stack network.

Status:

Confirmed

2026-06-24 - Adopt Phased Infrastructure Roadmap

Decision:

Use a phased roadmap for planned SilverLinux platform improvements.

Phases:

  • Phase 1: Grafana, Prometheus, Loki, Redis and Authelia.
  • Phase 2: CrowdSec, Sentry, Restic, Fail2Ban upgrade and Cloudflare rate limiting/WAF.
  • Phase 3: SonarQube, Harbor, Backstage and Nextcloud.

Reason:

  • Prioritize observability, access control and shared runtime foundations first.
  • Add security and backup maturity before larger platform expansion.
  • Keep enterprise developer-platform tools grouped together.

Status:

Accepted

Current status:

  • Sentry is now implemented and documented as the exception to the standard slcompose + Infisical service pattern.

2026-06-25 - Select Prometheus And Grafana Monitoring Stack

Decision:

Deploy a dedicated monitoring Docker stack using:

  • Prometheus for metrics collection
  • Grafana for visualization
  • Node Exporter for host metrics
  • cAdvisor for Docker metrics
  • Alertmanager for alert routing and incident notifications

Reason:

  • Prometheus provides a standard pull-based metrics system.
  • Grafana provides flexible dashboards and datasource integration.
  • Node Exporter provides host CPU, memory and disk visibility.
  • cAdvisor provides Docker container visibility.
  • Alertmanager provides grouping, deduplication and multi-recipient email routing.

Status:

Implemented

Validation:

  • Prometheus UI validated
  • Prometheus targets validated
  • Grafana datasource connected to Prometheus
  • Initial monitoring dashboards created and validated
  • Alertmanager email routing validated

2026-06-25 - Export Backup Metrics Through Node Exporter

Decision:

Export SilverLinux backup metrics through the Node Exporter Textfile Collector.

Metrics:

  • silverlinux_backup_success
  • silverlinux_backup_duration_seconds
  • silverlinux_backup_size_bytes
  • silverlinux_backup_timestamp_seconds

Reason:

  • Keep backup status visible in the same monitoring stack as host and container metrics.
  • Avoid a separate metrics service for backup scripts.
  • Allow Grafana dashboards to show backup health.

Status:

Implemented

2026-06-25 - Validate Backup v5.3 And Restore Workflow

Decision:

Treat Backup v5.3 as the operational SilverLinux backup system.

Implemented:

  • HTML backup reports
  • Email notifications
  • Automatic archive creation
  • Backup logging
  • Restore validation
  • MSSQL data inclusion fix
  • Backup metrics
  • Automatic low disk space cleanup
  • Daily cron execution
  • Lock file protection
  • Disk space validation
  • Central logging
  • Structured failure handling

Validation:

  • Dry-run restore completed
  • Full archive validation completed
  • PostgreSQL restore coverage verified
  • MSSQL backup integrity verified
  • Gitea backup verified
  • BaGet backup verified
  • OpenProject assets verified
  • Docker configuration verified

Status:

Implemented

2026-06-25 - Implement Incident Intelligence Alerting

Decision:

Use Alertmanager with incident grouping, severity-based routing and alert deduplication for SilverLinux monitoring.

Incident groups:

  • backup_failure
  • system_pressure
  • storage_pressure
  • database_outage
  • monitoring_failure
  • container_health

Reason:

  • Merge related alerts into single incidents.
  • Reduce notification noise.
  • Route alerts by severity.
  • Make alerts root-cause oriented.

Status:

Implemented

2026-07-08 - Deploy Nextcloud For Private Cloud Storage

Decision:

Deploy Nextcloud as the SilverLinux private cloud storage and file sharing service at cloud.silveressence.net.

Implementation:

  • Run nextcloud:29-apache as the web application container.
  • Run postgres:16 as the stack-local Nextcloud database.
  • Run redis:7-alpine as the stack-local cache and locking backend.
  • Attach only the web container to proxy.
  • Keep PostgreSQL and Redis on nextcloud_nextcloud_internal.
  • Persist data in nextcloud_nextcloud_data and nextcloud_nextcloud_db.
  • Manage the stack from /srv/docker/nextcloud with slcompose and Infisical secret injection.

Reason:

  • Provide self-hosted file storage and document sharing.
  • Keep user files inside SilverLinux infrastructure.
  • Avoid exposing database or cache ports publicly.
  • Reuse the standard Nginx Proxy Manager routing model.

Status:

Implemented

2026-07-08 - Document Sentry As Upstream Self-Hosted Deployment

Decision:

Run Sentry using the upstream self-hosted install.sh workflow and expose it at sentry.silveressence.net through Nginx Proxy Manager.

Implementation:

  • Use the upstream Sentry self-hosted installer layout.
  • Treat sentry-self-hosted as one atomic deployment unit.
  • Keep Sentry backing services isolated on sentry-self-hosted_default.
  • Route public access through the Sentry nginx or web entry layer.
  • Do not force Sentry into the standard SilverLinux slcompose and Infisical pattern.

Reason:

  • Sentry is a large distributed application with many tightly coupled services.
  • The upstream self-hosted installer manages required configuration and generated secrets.
  • Preserving the upstream layout reduces maintenance risk during upgrades.

Status:

Implemented

Future Decisions

Document future decisions using the following template:

Date:

Decision:

Reason:

Alternatives Considered:

Status: