Compare commits
9 Commits
master
..
a74909be25
| Author | SHA1 | Date | |
|---|---|---|---|
| a74909be25 | |||
| 4cf06da0a8 | |||
| db42baa33e | |||
| 4c2da84795 | |||
| ab461a5c08 | |||
| a8e23d3036 | |||
| b43f2b790e | |||
| efbdfb241c | |||
| 02a7ac7971 |
@@ -1,16 +1,156 @@
|
|||||||
# SilverLinux
|
# SilverLinux Infrastructure
|
||||||
|
|
||||||
Production infrastructure for Silver Solutions.
|
This repository contains the infrastructure configuration, deployment files and operational documentation for the SilverLinux server.
|
||||||
|
|
||||||
## Services
|
SilverLinux is the primary self-hosted platform for Silver Solutions and hosts source control, project management, collaboration, communication and CI/CD services.
|
||||||
|
|
||||||
- Nginx Proxy Manager
|
---
|
||||||
- Portainer
|
|
||||||
- PostgreSQL
|
|
||||||
- Gitea
|
|
||||||
|
|
||||||
## Server
|
## Server Information
|
||||||
|
|
||||||
- Ubuntu 24.04
|
| Property | Value |
|
||||||
- Docker 29
|
| ---------------- | ----------------------- |
|
||||||
- RAID1
|
| Hostname | silverlinux |
|
||||||
|
| Provider | OVH |
|
||||||
|
| Operating System | Ubuntu Server 24.04 LTS |
|
||||||
|
| Public IP | 51.255.83.140 |
|
||||||
|
| CPU | Intel Xeon-D 1520 |
|
||||||
|
| Memory | 32 GB RAM |
|
||||||
|
| Storage | 2 × 480 GB SSD RAID1 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Core Services
|
||||||
|
|
||||||
|
### Running
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Microsoft SQL Server 2022 Express
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
* Portainer
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* BaGet
|
||||||
|
* Gitea Actions Runner
|
||||||
|
* DbGate
|
||||||
|
* Xray
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
### Planned
|
||||||
|
|
||||||
|
* Nextcloud
|
||||||
|
* Loki
|
||||||
|
* Redis
|
||||||
|
* Authelia
|
||||||
|
* CrowdSec
|
||||||
|
* Sentry
|
||||||
|
* Restic
|
||||||
|
* Harbor
|
||||||
|
* SonarQube
|
||||||
|
* Backstage
|
||||||
|
|
||||||
|
See [docs/roadmap.md](docs/roadmap.md) for the phased infrastructure roadmap.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
* Plane.so (replaced by OpenProject)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Infrastructure
|
||||||
|
|
||||||
|
The following components are shared across multiple services:
|
||||||
|
|
||||||
|
* Docker
|
||||||
|
* Docker Compose
|
||||||
|
* Internal Docker Network
|
||||||
|
* Proxy Docker Network
|
||||||
|
* Isolated Docker Networks
|
||||||
|
* Monitoring Docker Stack
|
||||||
|
* Automated Backup System
|
||||||
|
* Shared Secrets Management
|
||||||
|
|
||||||
|
Secrets are stored outside the repository:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```text
|
||||||
|
baget/
|
||||||
|
dbgate/
|
||||||
|
docs/
|
||||||
|
gitea/
|
||||||
|
jitsi/
|
||||||
|
mssql/
|
||||||
|
nginx-proxy-manager/
|
||||||
|
openproject/
|
||||||
|
portainer/
|
||||||
|
postgres/
|
||||||
|
scripts/
|
||||||
|
```
|
||||||
|
|
||||||
|
Each service folder contains:
|
||||||
|
|
||||||
|
* docker-compose.yml
|
||||||
|
* README.md
|
||||||
|
* .env.example
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This repository serves as the single source of truth for rebuilding and maintaining the SilverLinux environment.
|
||||||
|
|
||||||
|
Infrastructure documentation, Docker Compose files, backup procedures, deployment notes and operational decisions are stored here.
|
||||||
|
|
||||||
|
The goal is that the entire environment can be rebuilt from this repository and the documented backup files.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
Gitea Actions is enabled globally and uses the self-hosted `silverlinux-runner` on SilverLinux. The operational Silver 2.0 package workflow builds and publishes NuGet packages to the internal BaGet feed.
|
||||||
|
|
||||||
|
See [docs/cicd.md](docs/cicd.md) for the runner, workflow triggers, pipeline stages and secret locations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Never commit:
|
||||||
|
|
||||||
|
* Passwords
|
||||||
|
* API Keys
|
||||||
|
* SMTP Credentials
|
||||||
|
* OAuth Secrets
|
||||||
|
* SSL Private Keys
|
||||||
|
* Database Credentials
|
||||||
|
* Real `.env` files
|
||||||
|
* `/srv/secrets/company.env`
|
||||||
|
|
||||||
|
Use example files whenever possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Disaster Recovery
|
||||||
|
|
||||||
|
This repository should contain enough information to rebuild the entire SilverLinux environment from scratch.
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/network.md
|
||||||
|
* docs/roadmap.md
|
||||||
|
* docs/backups.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
|||||||
+403
@@ -0,0 +1,403 @@
|
|||||||
|
# SilverLinux Infrastructure Summary
|
||||||
|
|
||||||
|
Last Updated: 2026-06-25
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux is the primary infrastructure server for Silver Solutions.
|
||||||
|
|
||||||
|
The platform hosts source control, project management, video conferencing, container management and supporting infrastructure services.
|
||||||
|
|
||||||
|
Monitoring, alerting, automated backups and restore validation are now production-ready.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Public Services
|
||||||
|
|
||||||
|
| Service | URL |
|
||||||
|
| ----------- | ----------------------------------- |
|
||||||
|
| Gitea | https://git.silveressence.net |
|
||||||
|
| OpenProject | https://team.silveressence.net |
|
||||||
|
| Portainer | https://portainer.silveressence.net |
|
||||||
|
| Jitsi Meet | https://meet.silveressence.net |
|
||||||
|
| BaGet | https://nuget.silveressence.net |
|
||||||
|
| DbGate | https://dbgate.silveressence.net |
|
||||||
|
| Xray | Public tunneling endpoint |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running Services
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Git repositories
|
||||||
|
* Pull requests
|
||||||
|
* Issue tracking
|
||||||
|
* Gitea Actions enabled globally
|
||||||
|
* Self-hosted Actions runner operational
|
||||||
|
* NuGet package publishing to BaGet
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
|
||||||
|
* Local accounts
|
||||||
|
* Planned Google OAuth2
|
||||||
|
* Planned GitHub OAuth2
|
||||||
|
|
||||||
|
Email:
|
||||||
|
|
||||||
|
* SMTP configured
|
||||||
|
* Password reset supported
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Project management
|
||||||
|
* Sprint planning
|
||||||
|
* Time tracking
|
||||||
|
* Roadmaps
|
||||||
|
* Team collaboration
|
||||||
|
|
||||||
|
Email:
|
||||||
|
|
||||||
|
* SMTP configured
|
||||||
|
* Notifications enabled
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Jitsi Meet
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Video conferencing
|
||||||
|
* Screen sharing
|
||||||
|
* Team meetings
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
|
||||||
|
* Internal authentication
|
||||||
|
* Guest access enabled
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Shared database platform
|
||||||
|
* OpenProject database
|
||||||
|
* Gitea database
|
||||||
|
* Future application databases
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Microsoft SQL Server Express
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Support projects requiring Microsoft SQL Server
|
||||||
|
* Provide a private SQL Server 2022 Express platform
|
||||||
|
|
||||||
|
Access:
|
||||||
|
|
||||||
|
* Docker `internal` network only
|
||||||
|
* Port 1433 is not publicly exposed
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
* Operational
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Portainer
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Docker administration
|
||||||
|
* Stack deployment
|
||||||
|
* Container monitoring
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Nginx Proxy Manager
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Reverse proxy
|
||||||
|
* SSL certificate management
|
||||||
|
* Domain routing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Monitoring Stack
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Metrics collection
|
||||||
|
* Monitoring dashboards
|
||||||
|
* Host and Docker visibility
|
||||||
|
* Backup metrics visibility
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
Validated:
|
||||||
|
|
||||||
|
* Prometheus UI
|
||||||
|
* Prometheus targets
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Backup metrics
|
||||||
|
* Grafana datasource
|
||||||
|
* Alertmanager email routing
|
||||||
|
|
||||||
|
Dashboards:
|
||||||
|
|
||||||
|
* Custom backup dashboard
|
||||||
|
* Custom system dashboard
|
||||||
|
* Docker monitoring dashboard
|
||||||
|
|
||||||
|
Alerting:
|
||||||
|
|
||||||
|
* Incident grouping
|
||||||
|
* Severity-based routing
|
||||||
|
* Alert deduplication
|
||||||
|
* Multi-recipient email notifications
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
* Production ready
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Automated Backup System
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Daily backup execution
|
||||||
|
* Archive generation
|
||||||
|
* HTML reporting
|
||||||
|
* Email notification
|
||||||
|
* Restore validation
|
||||||
|
* Prometheus backup metrics
|
||||||
|
|
||||||
|
Current version:
|
||||||
|
|
||||||
|
* Backup v5.3
|
||||||
|
|
||||||
|
Validated:
|
||||||
|
|
||||||
|
* Backup execution
|
||||||
|
* Restore archive extraction
|
||||||
|
* MSSQL backup integrity
|
||||||
|
* PostgreSQL backup
|
||||||
|
* Email notifications
|
||||||
|
* Cron automation
|
||||||
|
* Backup metrics export
|
||||||
|
* Lock file protection
|
||||||
|
* Disk space validation
|
||||||
|
* Structured failure handling
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
* Production ready
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BaGet
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private NuGet package hosting
|
||||||
|
* Internal Silver.* package distribution
|
||||||
|
|
||||||
|
Access:
|
||||||
|
|
||||||
|
* Routed through Nginx Proxy Manager
|
||||||
|
* https://nuget.silveressence.net
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea Actions Runner
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Execute Gitea Actions workflows
|
||||||
|
* Build and package Silver 2.0 libraries
|
||||||
|
* Publish NuGet packages to BaGet
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
* Global runner operational as `silverlinux-runner`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DbGate
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Browser-based MSSQL and PostgreSQL administration
|
||||||
|
|
||||||
|
Access:
|
||||||
|
|
||||||
|
* https://dbgate.silveressence.net
|
||||||
|
* HTTPS through Nginx Proxy Manager
|
||||||
|
* Username and password required
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
* Operational
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Xray
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Connectivity and tunneling layer
|
||||||
|
* Improve stable access paths to SilverLinux
|
||||||
|
|
||||||
|
Access:
|
||||||
|
|
||||||
|
* Attached to `proxy`
|
||||||
|
* Publishes `32443 -> 8080/tcp`
|
||||||
|
* `xray_default` exists, but no running Xray container was attached to it in the 2026-06-24 runtime snapshot
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
* Operational
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Infrastructure
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Container hosting
|
||||||
|
* Service isolation
|
||||||
|
|
||||||
|
### Internal Network
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private communication between services
|
||||||
|
|
||||||
|
### Proxy Network
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Public HTTP and HTTPS services through Nginx Proxy Manager
|
||||||
|
|
||||||
|
### Isolated Networks
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Separate specialized stacks such as Jitsi, Xray and CI/CD runners where active runtime attachments support it
|
||||||
|
|
||||||
|
### Shared Secrets
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* PostgreSQL passwords
|
||||||
|
* MSSQL SA password
|
||||||
|
* OpenProject secrets
|
||||||
|
* Future DbGate password
|
||||||
|
* Future OAuth secrets
|
||||||
|
|
||||||
|
This file must never be committed to Git.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture Decisions
|
||||||
|
|
||||||
|
### OpenProject Selected
|
||||||
|
|
||||||
|
OpenProject is the primary project management platform.
|
||||||
|
|
||||||
|
### Plane.so Removed
|
||||||
|
|
||||||
|
Plane.so was removed to reduce maintenance complexity and duplicate functionality. It is not used and will not be used. Its containers, Nginx Proxy Manager route and unused SSL certificate were removed.
|
||||||
|
|
||||||
|
### Centralized Secrets
|
||||||
|
|
||||||
|
All shared credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Xray Connectivity Layer
|
||||||
|
|
||||||
|
Xray is classified as a tunneling and connectivity layer rather than an application backend.
|
||||||
|
|
||||||
|
### Multi-Network Segmentation
|
||||||
|
|
||||||
|
SilverLinux uses `internal`, `proxy` and isolated infrastructure networks to separate database, public and specialized stack traffic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Roadmap
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/roadmap.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 1 - Immediate Impact
|
||||||
|
|
||||||
|
* Loki logging
|
||||||
|
* Redis
|
||||||
|
* Authelia SSO
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
|
||||||
|
* Grafana + Prometheus
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
* Backup metrics integration
|
||||||
|
* Incident intelligence
|
||||||
|
|
||||||
|
### Phase 2 - Security And Stability
|
||||||
|
|
||||||
|
* CrowdSec
|
||||||
|
* Sentry
|
||||||
|
* Fail2Ban upgrade
|
||||||
|
* Cloudflare rate limiting and WAF
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
|
||||||
|
* Backup v5.3 automation
|
||||||
|
* Restore validation
|
||||||
|
|
||||||
|
### Phase 3 - Scale And Enterprise Services
|
||||||
|
|
||||||
|
* SonarQube
|
||||||
|
* Harbor Docker registry
|
||||||
|
* Backstage portal
|
||||||
|
* Nextcloud
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Mission
|
||||||
|
|
||||||
|
Provide a secure, reliable and self-hosted platform for software development and business operations within Silver Solutions.
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# BaGet
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
BaGet is the private NuGet package server for Silver Solutions.
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://nuget.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
Public HTTPS access is routed through Nginx Proxy Manager. The BaGet container is connected to the external `proxy` Docker network.
|
||||||
|
|
||||||
|
NuGet v3 feed:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://nuget.silveressence.net/v3/index.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Current configuration is stored directly in the Docker Compose file.
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/baget/docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Current configuration includes:
|
||||||
|
|
||||||
|
* ApiKey
|
||||||
|
* Storage configuration
|
||||||
|
* Database configuration
|
||||||
|
* Search configuration
|
||||||
|
|
||||||
|
## Data Storage
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/baget/data
|
||||||
|
```
|
||||||
|
|
||||||
|
This directory contains the SQLite database and hosted NuGet packages and should be included in backups.
|
||||||
|
|
||||||
|
## Reverse Proxy
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
| ---------------- | ----------------------------------- |
|
||||||
|
| Public URL | `https://nuget.silveressence.net` |
|
||||||
|
| Target container | `baget` |
|
||||||
|
| Target port | `80` |
|
||||||
|
| Docker network | `proxy` |
|
||||||
|
|
||||||
|
## Gitea Actions Integration
|
||||||
|
|
||||||
|
The Silver 2.0 workflow at `.gitea/workflows/package.yml` publishes packages to this feed through the global `silverlinux-runner`.
|
||||||
|
|
||||||
|
Publishing requires the repository Actions secret:
|
||||||
|
|
||||||
|
```text
|
||||||
|
BAGET_API_KEY
|
||||||
|
```
|
||||||
|
|
||||||
|
It is stored under **Repository Settings -> Actions -> Secrets** and must never be committed to a repository.
|
||||||
|
|
||||||
|
The end-to-end Gitea Actions to BaGet publishing pipeline is operational.
|
||||||
|
|
||||||
|
### Future Improvement
|
||||||
|
|
||||||
|
BaGet configuration should eventually be migrated to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
to centralize secret management across SilverLinux services.
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
services:
|
||||||
|
baget:
|
||||||
|
image: loicsharma/baget:latest
|
||||||
|
container_name: baget
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "5555:80"
|
||||||
|
|
||||||
|
environment:
|
||||||
|
ApiKey: "your api key"
|
||||||
|
Storage__Type: FileSystem
|
||||||
|
Storage__Path: /var/baget/packages
|
||||||
|
Database__Type: Sqlite
|
||||||
|
Database__ConnectionString: Data Source=/var/baget/baget.db
|
||||||
|
Search__Type: Database
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/baget/data:/var/baget
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# DbGate
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
DbGate is the HTTPS-accessible database administration portal for SilverLinux.
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://dbgate.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
It administers private Microsoft SQL Server and PostgreSQL instances without exposing either database server directly to the internet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Container | `dbgate` |
|
||||||
|
| Image | `dbgate/dbgate:latest` |
|
||||||
|
| Application port | `3000` |
|
||||||
|
| Networks | `internal`, `proxy` |
|
||||||
|
| Compose location | `/srv/docker/dbgate/docker-compose.yml` |
|
||||||
|
| Data location | `/srv/docker/dbgate/data` |
|
||||||
|
|
||||||
|
The `internal` network provides database access. The `proxy` network connects DbGate to Nginx Proxy Manager.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reverse Proxy
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Domain | `dbgate.silveressence.net` |
|
||||||
|
| Scheme | `http` |
|
||||||
|
| Forward host | `dbgate` |
|
||||||
|
| Forward port | `3000` |
|
||||||
|
| SSL | Let's Encrypt |
|
||||||
|
| Force SSL | Enabled |
|
||||||
|
| HTTP/2 | Enabled |
|
||||||
|
|
||||||
|
Only DbGate is publicly accessible. MSSQL port `1433` and PostgreSQL port `5432` remain private.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
DbGate requires a username and password before granting access. The initial unauthenticated deployment was corrected by configuring `LOGIN` and `PASSWORD`.
|
||||||
|
|
||||||
|
The running server currently stores the DbGate credentials directly in its Compose configuration. The repository intentionally does not contain the password; its Compose definition resolves `DBGATE_PASSWORD` from the deployment environment.
|
||||||
|
|
||||||
|
Planned improvement:
|
||||||
|
|
||||||
|
* Add `DBGATE_PASSWORD` to `/srv/secrets/company.env`.
|
||||||
|
* Deploy with `docker compose --env-file /srv/secrets/company.env up -d`.
|
||||||
|
* Remove the credential from the server-side Compose file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Connections
|
||||||
|
|
||||||
|
### SilverLinux MSSQL
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Engine | SQL Server |
|
||||||
|
| Server | `mssql` |
|
||||||
|
| Port | `1433` |
|
||||||
|
| Default database | `master` |
|
||||||
|
| User | `sa` |
|
||||||
|
| Encrypt | Yes |
|
||||||
|
| Trust server certificate | Yes |
|
||||||
|
|
||||||
|
The connection was validated against `master`, `model`, `msdb` and `tempdb`.
|
||||||
|
|
||||||
|
PostgreSQL is also reachable through the shared `internal` network using hostname `postgres` and port `5432`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker ps
|
||||||
|
docker logs dbgate
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected log message:
|
||||||
|
|
||||||
|
```text
|
||||||
|
DbGate API listening on port 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```text
|
||||||
|
Internet
|
||||||
|
-> Nginx Proxy Manager
|
||||||
|
-> DbGate
|
||||||
|
-> MSSQL 2022 Express
|
||||||
|
-> PostgreSQL 17
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Requirements
|
||||||
|
|
||||||
|
Back up:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/dbgate/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Also retain the Compose definition, Nginx Proxy Manager configuration and DbGate credential through the centralized secrets backup after migration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* mssql/README.md
|
||||||
|
* postgres/README.md
|
||||||
|
* nginx-proxy-manager/README.md
|
||||||
|
* docs/domains.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/backups.md
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
services:
|
||||||
|
dbgate:
|
||||||
|
image: dbgate/dbgate:latest
|
||||||
|
container_name: dbgate
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
LOGIN: admin
|
||||||
|
PASSWORD: ${DBGATE_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/dbgate/data:/root/.dbgate
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- proxy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
# SilverLinux AI Context
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
SilverLinux is the primary self-hosted infrastructure server for Silver Solutions.
|
||||||
|
|
||||||
|
The goal is to host all development, collaboration, deployment and internal tooling.
|
||||||
|
|
||||||
|
## Server
|
||||||
|
|
||||||
|
Hostname: silverlinux
|
||||||
|
|
||||||
|
OS: Ubuntu Server 24.04 LTS
|
||||||
|
|
||||||
|
Provider: OVH
|
||||||
|
|
||||||
|
Public IP: 51.255.83.140
|
||||||
|
|
||||||
|
## Core Services
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Microsoft SQL Server 2022 Express
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
* Portainer
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* BaGet
|
||||||
|
* Gitea Actions Runner (`silverlinux-runner`)
|
||||||
|
* DbGate
|
||||||
|
* Xray
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
## Domains
|
||||||
|
|
||||||
|
git.silveressence.net -> Gitea
|
||||||
|
|
||||||
|
team.silveressence.net -> OpenProject
|
||||||
|
|
||||||
|
meet.silveressence.net -> Jitsi
|
||||||
|
|
||||||
|
portainer.silveressence.net -> Portainer
|
||||||
|
|
||||||
|
nuget.silveressence.net -> BaGet (through Nginx Proxy Manager)
|
||||||
|
|
||||||
|
dbgate.silveressence.net -> DbGate (through Nginx Proxy Manager)
|
||||||
|
|
||||||
|
Xray -> Public tunneling endpoint through proxy network
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
Secrets are stored in:
|
||||||
|
|
||||||
|
/srv/secrets/company.env
|
||||||
|
|
||||||
|
Never hardcode credentials.
|
||||||
|
|
||||||
|
Always use env_file.
|
||||||
|
|
||||||
|
## Docker Networks
|
||||||
|
|
||||||
|
proxy
|
||||||
|
internal
|
||||||
|
jitsi-docker-jitsi-meet-aa76415_meet.jitsi
|
||||||
|
xray_default
|
||||||
|
gitea-runner_default
|
||||||
|
|
||||||
|
MSSQL is attached only to `internal`. DbGate is attached to both `internal` and `proxy`.
|
||||||
|
|
||||||
|
Jitsi uses `jitsi-docker-jitsi-meet-aa76415_meet.jitsi` for its internal cluster and `proxy` for web access. Xray is currently attached to `proxy`; `xray_default` exists but had no running containers attached in the 2026-06-24 runtime snapshot.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Gitea:
|
||||||
|
|
||||||
|
* Local accounts
|
||||||
|
* OpenID disabled
|
||||||
|
* Google OAuth planned
|
||||||
|
* GitHub OAuth planned
|
||||||
|
|
||||||
|
OpenProject:
|
||||||
|
|
||||||
|
* Local accounts
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
Gitea Actions is enabled globally.
|
||||||
|
|
||||||
|
The global self-hosted runner is operational at `/srv/docker/gitea-runner` with the name `silverlinux-runner`.
|
||||||
|
|
||||||
|
Silver 2.0 uses `.gitea/workflows/package.yml` to publish NuGet packages to BaGet when a push to `net-8-version` has a commit message containing `[Package]`.
|
||||||
|
|
||||||
|
The runner registration token is stored in `/srv/secrets/company.env`. The BaGet publishing key is stored as the repository Actions secret `BAGET_API_KEY`.
|
||||||
|
|
||||||
|
## Databases
|
||||||
|
|
||||||
|
PostgreSQL 17 and Microsoft SQL Server 2022 Express are operational.
|
||||||
|
|
||||||
|
MSSQL uses hostname `mssql` on the `internal` Docker network. Port 1433 is not published.
|
||||||
|
|
||||||
|
DbGate provides authenticated HTTPS administration for MSSQL and PostgreSQL at `https://dbgate.silveressence.net`.
|
||||||
|
|
||||||
|
Xray is a connectivity layer, not an application backend. It runs from `ghcr.io/xtls/xray-core:latest` and publishes `0.0.0.0:32443 -> 8080/tcp`. Its endpoint exposure and access policy should be reviewed during security checks.
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
The monitoring stack is operational.
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
Validated:
|
||||||
|
|
||||||
|
* Prometheus UI
|
||||||
|
* Prometheus targets
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Backup metrics
|
||||||
|
* Grafana datasource
|
||||||
|
* Alertmanager email routing
|
||||||
|
|
||||||
|
Grafana has custom backup, system and Docker monitoring dashboards.
|
||||||
|
|
||||||
|
Alertmanager implements incident intelligence with incident groups:
|
||||||
|
|
||||||
|
* `backup_failure`
|
||||||
|
* `system_pressure`
|
||||||
|
* `storage_pressure`
|
||||||
|
* `database_outage`
|
||||||
|
* `monitoring_failure`
|
||||||
|
* `container_health`
|
||||||
|
|
||||||
|
## Backup
|
||||||
|
|
||||||
|
Backup v5.3 is production.
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* Daily cron backup
|
||||||
|
* HTML reports
|
||||||
|
* Email reports through Postfix and Gmail SMTP
|
||||||
|
* Automatic archive generation
|
||||||
|
* Automatic cleanup
|
||||||
|
* Prometheus metrics export
|
||||||
|
* Restore validation
|
||||||
|
* Lock file protection
|
||||||
|
* Disk space validation
|
||||||
|
* Central logging
|
||||||
|
* Structured failure handling
|
||||||
|
|
||||||
|
Verified:
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* MSSQL
|
||||||
|
* Gitea
|
||||||
|
* BaGet
|
||||||
|
* OpenProject assets
|
||||||
|
* Docker configuration
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Read all files in:
|
||||||
|
|
||||||
|
docs/
|
||||||
|
|
||||||
|
and the README.md of each service folder before making infrastructure recommendations.
|
||||||
|
|
||||||
|
Roadmap:
|
||||||
|
|
||||||
|
* Phase 1 completed: Grafana, Prometheus, Node Exporter, cAdvisor, Alertmanager, backup metrics integration, incident intelligence
|
||||||
|
* Phase 1 remaining: Loki, Redis, Authelia
|
||||||
|
* Phase 2 completed: Backup v5.3 automation, restore validation
|
||||||
|
* Phase 2 remaining: CrowdSec, Sentry, Fail2Ban upgrade, Cloudflare rate limiting and WAF
|
||||||
|
* Phase 3: SonarQube, Harbor, Backstage, Nextcloud
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/roadmap.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Decisions
|
||||||
|
|
||||||
|
* Plane.so removed
|
||||||
|
* OpenProject selected
|
||||||
|
* Centralized secrets implemented
|
||||||
|
* Nginx Proxy Manager selected
|
||||||
|
* PostgreSQL selected as shared database platform
|
||||||
|
* BaGet deployed at nuget.silveressence.net through Nginx Proxy Manager
|
||||||
|
* Gitea Actions and a global self-hosted runner selected for package publishing
|
||||||
|
* MSSQL Express deployed alongside PostgreSQL
|
||||||
|
* DbGate selected as the database administration portal
|
||||||
|
* Xray introduced as a tunneling and connectivity layer
|
||||||
|
* Multi-network segmentation formalized: internal, proxy and isolated infrastructure networks
|
||||||
+591
@@ -0,0 +1,591 @@
|
|||||||
|
# Backups
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document describes the backup strategy for SilverLinux.
|
||||||
|
|
||||||
|
The goal is to ensure that all critical services can be restored after hardware failure, accidental deletion, corruption, or disaster recovery scenarios.
|
||||||
|
|
||||||
|
Current state:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Backup v5.3 production
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup System Status
|
||||||
|
|
||||||
|
### Backup v1.4
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* HTML backup reports
|
||||||
|
* Email notification after backup
|
||||||
|
* Automatic archive creation
|
||||||
|
* Backup logging
|
||||||
|
* Restore validation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backup v1.5
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* MSSQL backup fix
|
||||||
|
* Runtime MSSQL data included correctly
|
||||||
|
* Restore tests verified MSSQL data is present in backups
|
||||||
|
* Improved backup structure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backup v2
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* Backup metrics generation
|
||||||
|
* Prometheus metrics export
|
||||||
|
* Backup duration metric
|
||||||
|
* Backup size metric
|
||||||
|
* Backup success metric
|
||||||
|
* Automatic low disk space handling
|
||||||
|
* Automatic deletion of oldest backups when required
|
||||||
|
* Improved logging
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backup v5.3
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* PostgreSQL backup using `pg_dumpall`
|
||||||
|
* MSSQL backup using `sqlcmd` and `docker cp`
|
||||||
|
* Gitea backup
|
||||||
|
* BaGet backup
|
||||||
|
* OpenProject backup
|
||||||
|
* Docker configuration backup
|
||||||
|
* Final compressed archive
|
||||||
|
* Lock file protection
|
||||||
|
* Disk space validation
|
||||||
|
* Central backup logging
|
||||||
|
* Structured failure handling
|
||||||
|
* Prometheus Textfile Collector metrics output
|
||||||
|
* Backup success and failure tracking
|
||||||
|
* Duration and size monitoring
|
||||||
|
* Historical logging
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Production
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Priorities
|
||||||
|
|
||||||
|
### Critical
|
||||||
|
|
||||||
|
These items must always be backed up.
|
||||||
|
|
||||||
|
#### PostgreSQL
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* OpenProject database
|
||||||
|
* Gitea database
|
||||||
|
* Future application databases
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Microsoft SQL Server
|
||||||
|
|
||||||
|
Data location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/mssql/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
* Native SQL Server database backups
|
||||||
|
* MSSQL Compose configuration
|
||||||
|
* `MSSQL_SA_PASSWORD` from the shared secrets backup
|
||||||
|
* Runtime MSSQL data included by the v1.5+ backup structure
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
Restore validation has verified that MSSQL data is present in current backup archives.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Gitea Data
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Git repositories
|
||||||
|
* Attachments
|
||||||
|
* Configuration
|
||||||
|
* User data
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### OpenProject Assets
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/openproject/assets
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Attachments
|
||||||
|
* Uploaded files
|
||||||
|
* User generated content
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Shared Secrets
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* PostgreSQL passwords
|
||||||
|
* MSSQL SA password
|
||||||
|
* OpenProject secrets
|
||||||
|
* Future DbGate password
|
||||||
|
* Future OAuth secrets
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
Without this file applications may not start correctly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Nginx Proxy Manager
|
||||||
|
|
||||||
|
Locations:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/data
|
||||||
|
/srv/docker/nginx-proxy-manager/letsencrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Proxy configuration
|
||||||
|
* SSL certificates
|
||||||
|
* Domain routing
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Medium Priority
|
||||||
|
|
||||||
|
#### Portainer
|
||||||
|
|
||||||
|
Volume:
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer_portainer_data
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Portainer users
|
||||||
|
* Portainer configuration
|
||||||
|
* Stack definitions
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Medium
|
||||||
|
|
||||||
|
Can be recreated if necessary.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Jitsi Configuration
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/jitsi
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Jitsi configuration
|
||||||
|
* Internal authentication configuration
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Medium
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### BaGet Data
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/baget/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Hosted NuGet packages
|
||||||
|
* SQLite database
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Medium
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Gitea Actions Runner Configuration
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Runner deployment configuration
|
||||||
|
* Runner state
|
||||||
|
|
||||||
|
The registration token is stored separately in `/srv/secrets/company.env`.
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Medium
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### DbGate Data
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/dbgate/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Saved connections
|
||||||
|
* DbGate application state
|
||||||
|
|
||||||
|
Also retain the Nginx Proxy Manager route and DbGate authentication credential.
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Medium
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Xray Configuration
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/xray
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Xray Docker Compose configuration
|
||||||
|
* Xray runtime configuration
|
||||||
|
* Endpoint credentials, UUIDs or keys if stored with the service
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Medium
|
||||||
|
|
||||||
|
Xray credentials and keys must be backed up securely and must never be committed to Git.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Storage
|
||||||
|
|
||||||
|
Current backup capabilities:
|
||||||
|
|
||||||
|
* Automatic archive generation
|
||||||
|
* HTML backup report generation
|
||||||
|
* Backup log generation
|
||||||
|
* Email report delivery
|
||||||
|
* Prometheus metrics export
|
||||||
|
* Automatic cleanup when disk space is low
|
||||||
|
* Automatic deletion of oldest backups when required
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Current Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/backups
|
||||||
|
```
|
||||||
|
|
||||||
|
Suggested Structure:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/backups/
|
||||||
|
├── daily
|
||||||
|
├── weekly
|
||||||
|
└── monthly
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Retention Policy
|
||||||
|
|
||||||
|
Current cleanup behavior:
|
||||||
|
|
||||||
|
* Backup v5.3 monitors available disk space.
|
||||||
|
* If disk space is low, the oldest backups are deleted automatically.
|
||||||
|
* Cleanup is logged.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Daily
|
||||||
|
|
||||||
|
Keep:
|
||||||
|
|
||||||
|
```text
|
||||||
|
7 days
|
||||||
|
```
|
||||||
|
|
||||||
|
### Weekly
|
||||||
|
|
||||||
|
Keep:
|
||||||
|
|
||||||
|
```text
|
||||||
|
4 weeks
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monthly
|
||||||
|
|
||||||
|
Keep:
|
||||||
|
|
||||||
|
```text
|
||||||
|
12 months
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Restore Priorities
|
||||||
|
|
||||||
|
Restore order:
|
||||||
|
|
||||||
|
1. Shared secrets
|
||||||
|
2. PostgreSQL
|
||||||
|
3. Microsoft SQL Server
|
||||||
|
4. Nginx Proxy Manager
|
||||||
|
5. Gitea
|
||||||
|
6. OpenProject
|
||||||
|
7. Portainer
|
||||||
|
8. Jitsi
|
||||||
|
9. BaGet
|
||||||
|
10. Gitea Actions Runner
|
||||||
|
11. DbGate
|
||||||
|
12. Xray
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Restore Validation
|
||||||
|
|
||||||
|
Restore procedure has been validated.
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
|
||||||
|
* Dry-run restore
|
||||||
|
* Full archive validation
|
||||||
|
* Archive extraction
|
||||||
|
|
||||||
|
Verified:
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Microsoft SQL Server
|
||||||
|
* Gitea
|
||||||
|
* BaGet
|
||||||
|
* OpenProject assets
|
||||||
|
* Docker configuration
|
||||||
|
|
||||||
|
Validation results:
|
||||||
|
|
||||||
|
* MSSQL backup integrity verified
|
||||||
|
* PostgreSQL backup verified
|
||||||
|
* Restore archive extraction verified
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoring Integration
|
||||||
|
|
||||||
|
Backup v5.3 exports metrics for Prometheus.
|
||||||
|
|
||||||
|
Current metrics:
|
||||||
|
|
||||||
|
* Backup success
|
||||||
|
* Backup duration
|
||||||
|
* Backup size
|
||||||
|
* Backup timestamp
|
||||||
|
|
||||||
|
Metric names:
|
||||||
|
|
||||||
|
* `silverlinux_backup_success`
|
||||||
|
* `silverlinux_backup_duration_seconds`
|
||||||
|
* `silverlinux_backup_size_bytes`
|
||||||
|
* `silverlinux_backup_timestamp_seconds`
|
||||||
|
|
||||||
|
Export path:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Node Exporter Textfile Collector
|
||||||
|
```
|
||||||
|
|
||||||
|
Prometheus target status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Validated
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Automation
|
||||||
|
|
||||||
|
Current automation:
|
||||||
|
|
||||||
|
* Daily backup execution
|
||||||
|
* Root cron configuration
|
||||||
|
* Backup wrapper command
|
||||||
|
* Email report
|
||||||
|
* HTML report
|
||||||
|
* Automatic cleanup
|
||||||
|
* Automatic archive generation
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Email Notifications
|
||||||
|
|
||||||
|
Postfix is configured to relay through Gmail SMTP.
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* Gmail relay
|
||||||
|
* App Password authentication
|
||||||
|
* TLS encryption
|
||||||
|
* Successful email delivery
|
||||||
|
* Backup success emails
|
||||||
|
* Backup report emails
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Disaster Recovery Checklist
|
||||||
|
|
||||||
|
### Step 1
|
||||||
|
|
||||||
|
Install:
|
||||||
|
|
||||||
|
* Ubuntu Server
|
||||||
|
* Docker
|
||||||
|
* Docker Compose
|
||||||
|
|
||||||
|
### Step 2
|
||||||
|
|
||||||
|
Restore:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3
|
||||||
|
|
||||||
|
Restore:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker
|
||||||
|
```
|
||||||
|
|
||||||
|
data directories.
|
||||||
|
|
||||||
|
### Step 4
|
||||||
|
|
||||||
|
Restore PostgreSQL and Microsoft SQL Server databases.
|
||||||
|
|
||||||
|
### Step 5
|
||||||
|
|
||||||
|
Deploy Docker stacks.
|
||||||
|
|
||||||
|
### Step 6
|
||||||
|
|
||||||
|
Verify:
|
||||||
|
|
||||||
|
* DNS
|
||||||
|
* SSL certificates
|
||||||
|
* Email delivery
|
||||||
|
* Application access
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/monitoring.md
|
||||||
|
* postgres/README.md
|
||||||
|
* gitea/README.md
|
||||||
|
* openproject/README.md
|
||||||
|
* mssql/README.md
|
||||||
|
* dbgate/README.md
|
||||||
|
* docs/roadmap.md
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
# CI/CD
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux provides CI/CD through globally enabled Gitea Actions and a self-hosted runner. Package publishing is operational; application deployment to Windows IIS and Linux targets remains future work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gitea Actions
|
||||||
|
|
||||||
|
Gitea Actions is enabled in Gitea's `app.ini` and is available globally.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Self-Hosted Runner
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Location | `/srv/docker/gitea-runner` |
|
||||||
|
| Image | `gitea/act_runner:latest` |
|
||||||
|
| Runner name | `silverlinux-runner` |
|
||||||
|
| Runner type | Global Runner |
|
||||||
|
| Status | Operational |
|
||||||
|
|
||||||
|
Runner labels:
|
||||||
|
|
||||||
|
* `ubuntu-latest`
|
||||||
|
* `ubuntu-24.04`
|
||||||
|
* `ubuntu-22.04`
|
||||||
|
|
||||||
|
The global runner can execute Actions workflows for repositories hosted by the SilverLinux Gitea instance.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Silver 2.0 Package Publishing
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.gitea/workflows/package.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
The workflow runs when both conditions are satisfied:
|
||||||
|
|
||||||
|
1. Code is pushed to the `net-8-version` branch.
|
||||||
|
2. The commit message contains `[Package]`.
|
||||||
|
|
||||||
|
Example commit message:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Package Silver 2.0 libraries [Package]
|
||||||
|
```
|
||||||
|
|
||||||
|
Pipeline steps:
|
||||||
|
|
||||||
|
1. Check out the repository.
|
||||||
|
2. Install the .NET 8 SDK.
|
||||||
|
3. Restore the solution.
|
||||||
|
4. Build the solution using the `Deploy` configuration.
|
||||||
|
5. Pack the NuGet packages.
|
||||||
|
6. Push the packages to BaGet.
|
||||||
|
|
||||||
|
NuGet feed:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://nuget.silveressence.net/v3/index.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Operational Flow
|
||||||
|
|
||||||
|
```text
|
||||||
|
Git push
|
||||||
|
-> Gitea Actions
|
||||||
|
-> silverlinux-runner
|
||||||
|
-> dotnet restore
|
||||||
|
-> dotnet build
|
||||||
|
-> dotnet pack
|
||||||
|
-> BaGet package publish
|
||||||
|
```
|
||||||
|
|
||||||
|
The complete workflow has been tested successfully and is operational.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
Runner registration token:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
BaGet publishing credential:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Repository Settings -> Actions -> Secrets
|
||||||
|
BAGET_API_KEY
|
||||||
|
```
|
||||||
|
|
||||||
|
No credentials are stored in repositories. Infrastructure-level secrets belong in `company.env`; repository workflow secrets belong in Gitea Actions Secrets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Deployment Targets
|
||||||
|
|
||||||
|
### Windows IIS
|
||||||
|
|
||||||
|
Planned targets include ASP.NET Core, Blazor Server and Blazor Web App deployments.
|
||||||
|
|
||||||
|
```text
|
||||||
|
Publish -> Copy files -> Restart IIS site
|
||||||
|
```
|
||||||
|
|
||||||
|
Status: Planned
|
||||||
|
|
||||||
|
### Linux Containers
|
||||||
|
|
||||||
|
```text
|
||||||
|
Build image -> Push image -> Deploy stack
|
||||||
|
```
|
||||||
|
|
||||||
|
Status: Future
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
* Automated tests
|
||||||
|
* Automated Windows IIS deployment
|
||||||
|
* Linux container deployment
|
||||||
|
* Release pipelines
|
||||||
|
* Multi-environment deployments
|
||||||
|
* Package publishing for additional repositories
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Services
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* Gitea Actions Runner
|
||||||
|
* BaGet
|
||||||
|
* Portainer
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* gitea/README.md
|
||||||
|
* baget/README.md
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
@@ -0,0 +1,598 @@
|
|||||||
|
# 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:
|
||||||
|
|
||||||
|
Store shared credentials in a single secrets file.
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
* Avoid secrets in Docker Compose files
|
||||||
|
* Easier credential rotation
|
||||||
|
* Easier disaster recovery
|
||||||
|
* Reduced risk of accidental exposure
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
Implemented
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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 `/srv/secrets/company.env` 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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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.
|
||||||
|
|
||||||
|
Future Plan:
|
||||||
|
|
||||||
|
Move the API key into the centralized SilverLinux secrets management system located at:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
when additional services begin consuming the same secret management approach.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 `/srv/secrets/company.env`.
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
* Support Silver projects that require Microsoft SQL Server compatibility.
|
||||||
|
* Allow both database platforms to coexist without exposing database ports.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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 the server-side Compose configuration to `/srv/secrets/company.env`.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Accepted
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Implemented
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Decisions
|
||||||
|
|
||||||
|
Document future decisions using the following template:
|
||||||
|
|
||||||
|
Date:
|
||||||
|
|
||||||
|
Decision:
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
Alternatives Considered:
|
||||||
|
|
||||||
|
Status:
|
||||||
+304
@@ -0,0 +1,304 @@
|
|||||||
|
# Domains
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document contains the public domains used by SilverLinux and the services they expose.
|
||||||
|
|
||||||
|
All public services are routed through Nginx Proxy Manager.
|
||||||
|
|
||||||
|
Verified proxy-host snapshot:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026-06-24
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Primary Domain
|
||||||
|
|
||||||
|
```text
|
||||||
|
silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Used for:
|
||||||
|
|
||||||
|
* Public services
|
||||||
|
* Subdomains
|
||||||
|
* SSL certificates
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Nginx Proxy Manager Hosts
|
||||||
|
|
||||||
|
| ID | Domain | Forward target | SSL Force | HTTP/2 | HSTS | WebSocket | Access List | Status |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| 1 | `portainer.silveressence.net` | `http://portainer:9000` | enabled | enabled | enabled | enabled | none | enabled |
|
||||||
|
| 2 | `git.silveressence.net` | `http://gitea:3000` | disabled | disabled | disabled | enabled | none | enabled |
|
||||||
|
| 3 | `meet.silveressence.net` | `http://jitsi-docker-jitsi-meet-aa76415-web-1:80` | disabled | disabled | disabled | enabled | none | enabled |
|
||||||
|
| 5 | `team.silveressence.net` | `http://openproject:80` | enabled | enabled | disabled | enabled | none | enabled |
|
||||||
|
| 6 | `nuget.silveressence.net` | `http://baget:80` | disabled | disabled | disabled | disabled | none | enabled |
|
||||||
|
| 8 | `dbgate.silveressence.net` | `http://dbgate:3000` | disabled | disabled | disabled | enabled | none | enabled |
|
||||||
|
|
||||||
|
All listed active inventory hosts have Block Exploits enabled.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Additional Active Proxy Hosts
|
||||||
|
|
||||||
|
These proxy hosts were present and enabled in Nginx Proxy Manager during the 2026-06-24 snapshot, but are not part of the current core infrastructure service inventory.
|
||||||
|
|
||||||
|
| ID | Domain | Forward target | Reason |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 7 | `cicd.silveressence.net` | `http://bobsAutowas:8080` | Active prototype deployment and test endpoint; may change frequently |
|
||||||
|
| 9 | `exactsyncer.silveressence.net` | `http://exact-syncer:8080` | Active client-facing demo for the Exact Online syncer application |
|
||||||
|
|
||||||
|
Action:
|
||||||
|
|
||||||
|
* Keep `cicd.silveressence.net` documented as a fast-changing prototype endpoint.
|
||||||
|
* Keep `exactsyncer.silveressence.net` documented as an intentional client-facing demo endpoint.
|
||||||
|
* Document owner, authentication model and exposure policy for active non-core endpoints.
|
||||||
|
|
||||||
|
Plane.so cleanup:
|
||||||
|
|
||||||
|
* Plane.so containers were removed.
|
||||||
|
* `plane.silveressence.net` was removed from Nginx Proxy Manager.
|
||||||
|
* The unused Plane.so SSL certificate was removed from the server.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Proxy Hardening Review
|
||||||
|
|
||||||
|
Nginx Proxy Manager findings from the 2026-06-24 snapshot:
|
||||||
|
|
||||||
|
* `portainer.silveressence.net` has SSL Force, HTTP/2 and HSTS enabled.
|
||||||
|
* `team.silveressence.net` has SSL Force and HTTP/2 enabled.
|
||||||
|
* `git.silveressence.net`, `meet.silveressence.net`, `nuget.silveressence.net` and `dbgate.silveressence.net` do not have SSL Force enabled.
|
||||||
|
* No listed proxy host uses an Nginx Proxy Manager access list.
|
||||||
|
* DbGate is a high-sensitivity database administration interface and should be prioritized for SSL Force and an access restriction policy.
|
||||||
|
* Plane.so has been removed from containers, Nginx Proxy Manager and server certificate storage.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Domain Details
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
git.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Source control
|
||||||
|
* Git repositories
|
||||||
|
* Pull requests
|
||||||
|
* Issue tracking
|
||||||
|
|
||||||
|
Container:
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
team.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Project management
|
||||||
|
* Work packages
|
||||||
|
* Time tracking
|
||||||
|
* Team collaboration
|
||||||
|
|
||||||
|
Container:
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Jitsi Meet
|
||||||
|
|
||||||
|
Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
meet.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Video conferencing
|
||||||
|
* Team meetings
|
||||||
|
* Customer meetings
|
||||||
|
|
||||||
|
Container Stack:
|
||||||
|
|
||||||
|
```text
|
||||||
|
jitsi-docker-jitsi-meet-aa76415-web-1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Portainer
|
||||||
|
|
||||||
|
Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Docker management
|
||||||
|
* Infrastructure administration
|
||||||
|
|
||||||
|
Container:
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BaGet
|
||||||
|
|
||||||
|
Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
nuget.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private NuGet package hosting
|
||||||
|
|
||||||
|
Container:
|
||||||
|
|
||||||
|
```text
|
||||||
|
baget
|
||||||
|
```
|
||||||
|
|
||||||
|
Routing:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nginx Proxy Manager -> baget:80
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Active
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DbGate
|
||||||
|
|
||||||
|
Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
dbgate.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* HTTPS database administration portal
|
||||||
|
|
||||||
|
Container:
|
||||||
|
|
||||||
|
```text
|
||||||
|
dbgate
|
||||||
|
```
|
||||||
|
|
||||||
|
Routing:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nginx Proxy Manager -> dbgate:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Active
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DNS
|
||||||
|
|
||||||
|
DNS records should point to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
51.255.83.140
|
||||||
|
```
|
||||||
|
|
||||||
|
Server:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SilverLinux
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSL Certificates
|
||||||
|
|
||||||
|
SSL certificates are managed through:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nginx Proxy Manager
|
||||||
|
```
|
||||||
|
|
||||||
|
Certificate data location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/letsencrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
|
||||||
|
Internet
|
||||||
|
↓
|
||||||
|
Nginx Proxy Manager
|
||||||
|
↓
|
||||||
|
Service Container
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
git.silveressence.net
|
||||||
|
↓
|
||||||
|
gitea
|
||||||
|
|
||||||
|
team.silveressence.net
|
||||||
|
↓
|
||||||
|
openproject
|
||||||
|
|
||||||
|
meet.silveressence.net
|
||||||
|
↓
|
||||||
|
jitsi
|
||||||
|
|
||||||
|
portainer.silveressence.net
|
||||||
|
↓
|
||||||
|
portainer
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/network.md
|
||||||
|
* nginx-proxy-manager/README.md
|
||||||
+255
@@ -0,0 +1,255 @@
|
|||||||
|
# Email Configuration
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux uses a centralized SMTP configuration for application email delivery.
|
||||||
|
|
||||||
|
Email is used for:
|
||||||
|
|
||||||
|
* Password resets
|
||||||
|
* User invitations
|
||||||
|
* Notifications
|
||||||
|
* System alerts
|
||||||
|
* Backup reports
|
||||||
|
* Future CI/CD notifications
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sender Address
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Automated emails
|
||||||
|
* Application notifications
|
||||||
|
* No inbound processing required
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SMTP Provider
|
||||||
|
|
||||||
|
Provider:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Gmail SMTP
|
||||||
|
```
|
||||||
|
|
||||||
|
Server:
|
||||||
|
|
||||||
|
```text
|
||||||
|
smtp.gmail.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Port:
|
||||||
|
|
||||||
|
```text
|
||||||
|
587
|
||||||
|
```
|
||||||
|
|
||||||
|
Security:
|
||||||
|
|
||||||
|
```text
|
||||||
|
STARTTLS
|
||||||
|
```
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Login
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secret Storage
|
||||||
|
|
||||||
|
SMTP credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SMTP_HOST
|
||||||
|
SMTP_PORT
|
||||||
|
SMTP_USERNAME
|
||||||
|
SMTP_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
These values must never be committed to Git repositories.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Applications Using Email
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Password reset emails
|
||||||
|
* Work package notifications
|
||||||
|
* Mention notifications
|
||||||
|
* User invitations
|
||||||
|
|
||||||
|
Sender:
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
Configured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Password reset emails
|
||||||
|
* Repository notifications
|
||||||
|
* User invitations
|
||||||
|
|
||||||
|
Sender:
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
Configured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backup System
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Backup success emails
|
||||||
|
* HTML backup report emails
|
||||||
|
* Operational backup notifications
|
||||||
|
|
||||||
|
Delivery:
|
||||||
|
|
||||||
|
* Postfix relay through Gmail SMTP
|
||||||
|
* Gmail App Password authentication
|
||||||
|
* TLS encryption
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
Configured and validated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Alertmanager
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Monitoring alert emails
|
||||||
|
* Incident grouped notifications
|
||||||
|
* Severity-based alert routing
|
||||||
|
|
||||||
|
Recipients:
|
||||||
|
|
||||||
|
* `oclick021@gmail.com`
|
||||||
|
* `martin@silversolutions.nl`
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
Configured and validated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Applications
|
||||||
|
|
||||||
|
Future services should use the centralized SMTP configuration whenever possible.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* BaGet
|
||||||
|
* CI/CD notifications
|
||||||
|
* Alerting systems
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
Test by:
|
||||||
|
|
||||||
|
1. Creating a user.
|
||||||
|
2. Triggering a password reset.
|
||||||
|
3. Verifying email delivery.
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
Test by:
|
||||||
|
|
||||||
|
1. Opening "Forgot Password".
|
||||||
|
2. Requesting a password reset.
|
||||||
|
3. Verifying email delivery.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
View logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
View logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gmail Authentication
|
||||||
|
|
||||||
|
Verify:
|
||||||
|
|
||||||
|
* App password is valid
|
||||||
|
* SMTP credentials match company.env
|
||||||
|
* STARTTLS is enabled
|
||||||
|
* Port 587 is used
|
||||||
|
|
||||||
|
### Backup Reports
|
||||||
|
|
||||||
|
Verify:
|
||||||
|
|
||||||
|
* Postfix relay is active
|
||||||
|
* Gmail App Password authentication succeeds
|
||||||
|
* TLS delivery succeeds
|
||||||
|
* Backup wrapper sends the HTML report after backup completion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
* Use Gmail App Passwords.
|
||||||
|
* Never use personal Gmail passwords.
|
||||||
|
* Store SMTP credentials only in company.env.
|
||||||
|
* Rotate credentials if they become exposed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/backups.md
|
||||||
|
* docs/monitoring.md
|
||||||
|
* openproject/README.md
|
||||||
|
* gitea/README.md
|
||||||
@@ -0,0 +1,311 @@
|
|||||||
|
# Monitoring And Alerting
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux runs a self-hosted observability stack for metrics, dashboards, backup visibility and incident alerting.
|
||||||
|
|
||||||
|
Current state:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Production ready
|
||||||
|
```
|
||||||
|
|
||||||
|
The stack has evolved from basic monitoring into an incident intelligence system with alert grouping, severity routing and email notifications.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stack Components
|
||||||
|
|
||||||
|
### Prometheus
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Metrics collection
|
||||||
|
* Alert rule evaluation
|
||||||
|
* Monitoring data storage
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Grafana
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Monitoring dashboards
|
||||||
|
* Prometheus datasource visualization
|
||||||
|
* Backup, system and Docker visibility
|
||||||
|
|
||||||
|
Dashboards:
|
||||||
|
|
||||||
|
* Custom backup dashboard
|
||||||
|
* Custom system dashboard
|
||||||
|
* Docker monitoring dashboard
|
||||||
|
|
||||||
|
Compatibility note:
|
||||||
|
|
||||||
|
The imported Prometheus 2.0 Overview dashboard is not compatible with Prometheus `3.5.4`. This is a third-party dashboard compatibility issue, not an infrastructure problem.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Node Exporter
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Host metrics
|
||||||
|
* CPU, memory and disk metrics
|
||||||
|
* Textfile Collector for custom backup metrics
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### cAdvisor
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Docker container metrics
|
||||||
|
* Container CPU and memory visibility
|
||||||
|
* Container health and restart visibility
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Alertmanager
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Alert routing
|
||||||
|
* Alert grouping
|
||||||
|
* Alert deduplication
|
||||||
|
* Email notifications
|
||||||
|
* Incident intelligence
|
||||||
|
|
||||||
|
Recipients:
|
||||||
|
|
||||||
|
* `oclick021@gmail.com`
|
||||||
|
* `martin@silversolutions.nl`
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Infrastructure
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/monitoring
|
||||||
|
```
|
||||||
|
|
||||||
|
Architecture:
|
||||||
|
|
||||||
|
* Docker-based stack
|
||||||
|
* Persistent Prometheus volume
|
||||||
|
* Persistent Grafana volume
|
||||||
|
* Dedicated monitoring network
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
|
||||||
|
### System Metrics
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* `node_load1`
|
||||||
|
* `node_memory_*`
|
||||||
|
* `node_filesystem_*`
|
||||||
|
* Container metrics through cAdvisor
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backup Metrics
|
||||||
|
|
||||||
|
Export method:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Node Exporter Textfile Collector
|
||||||
|
```
|
||||||
|
|
||||||
|
Metrics:
|
||||||
|
|
||||||
|
* `silverlinux_backup_success`
|
||||||
|
* `silverlinux_backup_duration_seconds`
|
||||||
|
* `silverlinux_backup_size_bytes`
|
||||||
|
* `silverlinux_backup_timestamp_seconds`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prometheus Scrape Targets
|
||||||
|
|
||||||
|
Prometheus successfully scrapes:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* SilverLinux backup metrics
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Validated
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alerting Evolution
|
||||||
|
|
||||||
|
### Stage v1
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* Basic Prometheus rules
|
||||||
|
* Simple email alerts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Stage v2
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* Alertmanager
|
||||||
|
* Email routing
|
||||||
|
* Multi-recipient alerts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Stage v3-v4
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* `incident_group` concept
|
||||||
|
* Alert correlation by service
|
||||||
|
* Severity-based routing
|
||||||
|
* Alert deduplication
|
||||||
|
* Reduced notification noise
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Incident Groups
|
||||||
|
|
||||||
|
Alertmanager groups alerts by incident category.
|
||||||
|
|
||||||
|
Incident groups:
|
||||||
|
|
||||||
|
* `backup_failure`
|
||||||
|
* `system_pressure`
|
||||||
|
* `storage_pressure`
|
||||||
|
* `database_outage`
|
||||||
|
* `monitoring_failure`
|
||||||
|
* `container_health`
|
||||||
|
|
||||||
|
Outcome:
|
||||||
|
|
||||||
|
* Multiple related alerts merge into single incidents.
|
||||||
|
* Alerts are root-cause oriented.
|
||||||
|
* Alert fatigue is reduced.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alert Rules
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
|
||||||
|
* `BackupFailed`
|
||||||
|
* `BackupStale`
|
||||||
|
|
||||||
|
### System
|
||||||
|
|
||||||
|
* `HighCPU`
|
||||||
|
* `HighMemoryUsage`
|
||||||
|
* `DiskAlmostFull`
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
|
||||||
|
* `PrometheusDown`
|
||||||
|
* `GrafanaDown`
|
||||||
|
|
||||||
|
### Databases
|
||||||
|
|
||||||
|
* `PostgresDown`
|
||||||
|
* `MSSQLDown`
|
||||||
|
|
||||||
|
### Containers
|
||||||
|
|
||||||
|
* `ContainerDown`
|
||||||
|
* `TooManyRestarts`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Fixes
|
||||||
|
|
||||||
|
Resolved during implementation:
|
||||||
|
|
||||||
|
* Fixed Docker mount errors caused by file versus directory conflicts
|
||||||
|
* Standardized alert rule file naming as `alerts.yml`
|
||||||
|
* Fixed Prometheus rule loading configuration
|
||||||
|
* Eliminated duplicate backup success metric sources
|
||||||
|
* Unified backup metric naming to `silverlinux_backup_*`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
```text
|
||||||
|
Servers
|
||||||
|
-> Node Exporter / cAdvisor
|
||||||
|
-> Prometheus
|
||||||
|
-> Alertmanager
|
||||||
|
-> Email notifications
|
||||||
|
-> Grafana dashboards
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Validated:
|
||||||
|
|
||||||
|
* Prometheus UI
|
||||||
|
* Prometheus targets
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Backup metrics
|
||||||
|
* Grafana datasource
|
||||||
|
* Alertmanager email routing
|
||||||
|
* Backup success and failure visibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/services.md
|
||||||
|
* docs/backups.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/network.md
|
||||||
|
* docs/email.md
|
||||||
|
* docs/decisions.md
|
||||||
+300
@@ -0,0 +1,300 @@
|
|||||||
|
# Network Architecture
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux uses Docker networks to separate public entry points, private service communication and isolated infrastructure stacks.
|
||||||
|
|
||||||
|
Current model:
|
||||||
|
|
||||||
|
* `internal` for private databases and backend service traffic
|
||||||
|
* `proxy` for HTTP and HTTPS services routed by Nginx Proxy Manager
|
||||||
|
* Isolated stack networks for specialized infrastructure such as Jitsi, Xray, monitoring and CI/CD runners
|
||||||
|
|
||||||
|
Verified runtime snapshot:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026-06-24 10:15 CEST
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Network Layers
|
||||||
|
|
||||||
|
### Internal Layer
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private database access
|
||||||
|
* Backend-to-database communication
|
||||||
|
* Service traffic that should not be reachable from the internet
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
Services:
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Microsoft SQL Server Express
|
||||||
|
* Gitea backend connectivity
|
||||||
|
* OpenProject backend connectivity
|
||||||
|
* DbGate database connectivity
|
||||||
|
|
||||||
|
Policy:
|
||||||
|
|
||||||
|
* Database ports must not be published on the host
|
||||||
|
* Database engines must not be routed through Nginx Proxy Manager
|
||||||
|
* Only containers that require private backend access should join this network
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Proxy Layer
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Public HTTP and HTTPS entry point
|
||||||
|
* SSL termination
|
||||||
|
* Domain routing through Nginx Proxy Manager
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Public services:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Portainer
|
||||||
|
* DbGate
|
||||||
|
* Xray
|
||||||
|
* Jitsi Web
|
||||||
|
* BaGet
|
||||||
|
|
||||||
|
Internal monitoring services:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
Verified subnet:
|
||||||
|
|
||||||
|
```text
|
||||||
|
172.18.0.0/16
|
||||||
|
```
|
||||||
|
|
||||||
|
Policy:
|
||||||
|
|
||||||
|
* Nginx Proxy Manager is the single reverse proxy system
|
||||||
|
* HTTP services should be exposed through Nginx Proxy Manager instead of direct host ports
|
||||||
|
* Public management and administration services require strong authentication
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Isolated Infrastructure Layers
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Keep specialized stacks separate from the shared application and database networks
|
||||||
|
* Limit cross-service traffic to only the attachments each stack requires
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
```text
|
||||||
|
jitsi-docker-jitsi-meet-aa76415_meet.jitsi
|
||||||
|
xray_default
|
||||||
|
gitea-runner_default
|
||||||
|
monitoring stack network
|
||||||
|
```
|
||||||
|
|
||||||
|
#### jitsi-docker-jitsi-meet-aa76415_meet.jitsi
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Isolated Jitsi communication cluster
|
||||||
|
|
||||||
|
Services:
|
||||||
|
|
||||||
|
* jitsi-web
|
||||||
|
* jitsi-jvb
|
||||||
|
* jitsi-jicofo
|
||||||
|
* jitsi-prosody
|
||||||
|
|
||||||
|
Public attachment:
|
||||||
|
|
||||||
|
* All currently running Jitsi containers also attach to `proxy`.
|
||||||
|
* Public user access is expected through the Jitsi Web component.
|
||||||
|
|
||||||
|
Verified subnet:
|
||||||
|
|
||||||
|
```text
|
||||||
|
172.20.0.0/16
|
||||||
|
```
|
||||||
|
|
||||||
|
#### xray_default
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Isolated tunneling and connectivity system
|
||||||
|
* Compose-created network for the Xray stack
|
||||||
|
|
||||||
|
Services:
|
||||||
|
|
||||||
|
* No running containers were attached in the 2026-06-24 runtime snapshot
|
||||||
|
|
||||||
|
Public attachment:
|
||||||
|
|
||||||
|
* The running `xray` container is attached to `proxy`.
|
||||||
|
* The running `xray` container was not attached to `xray_default` in the 2026-06-24 runtime snapshot.
|
||||||
|
|
||||||
|
Verified subnet:
|
||||||
|
|
||||||
|
```text
|
||||||
|
172.22.0.0/16
|
||||||
|
```
|
||||||
|
|
||||||
|
#### gitea-runner_default
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Runner execution and workflow isolation
|
||||||
|
* Keep build traffic separate from public services and private databases unless explicit access is required
|
||||||
|
|
||||||
|
Runtime attachment:
|
||||||
|
|
||||||
|
* `gitea-runner` is attached to both `gitea-runner_default` and `internal`.
|
||||||
|
|
||||||
|
Verified subnet:
|
||||||
|
|
||||||
|
```text
|
||||||
|
172.21.0.0/16
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Monitoring Stack Network
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Dedicated monitoring stack communication
|
||||||
|
* Prometheus scraping of monitoring targets
|
||||||
|
* Grafana datasource connectivity to Prometheus
|
||||||
|
|
||||||
|
Services:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
Validated:
|
||||||
|
|
||||||
|
* Prometheus scrapes Prometheus
|
||||||
|
* Prometheus scrapes Node Exporter
|
||||||
|
* Prometheus scrapes cAdvisor
|
||||||
|
* Prometheus scrapes SilverLinux backup metrics
|
||||||
|
* Grafana connects to Prometheus
|
||||||
|
* Alertmanager routes monitoring alerts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Runtime-Published Ports
|
||||||
|
|
||||||
|
The current Docker runtime includes these host-published ports.
|
||||||
|
|
||||||
|
| Service | Published port | Container port | UFW state | Notes |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| Nginx Proxy Manager | `80`, `81`, `443` | `80`, `81`, `443` | `80` and `443` allowed; `81` not listed | Public proxy and NPM admin interface |
|
||||||
|
| Gitea | `2222` | `22` | Allowed | Git SSH access |
|
||||||
|
| OpenProject | `8082` | `80` | Not listed as allowed | Direct HTTP port also published |
|
||||||
|
| BaGet | `5555` | `80` | Not listed as allowed | Direct HTTP port also published |
|
||||||
|
| Jitsi Web | `8000`, `8443` | `80`, `443` | `8443` allowed; `8000` not listed | Direct HTTP and HTTPS ports also published |
|
||||||
|
| Jitsi JVB | `10000/udp` | `10000/udp` | Allowed | Required media bridge traffic |
|
||||||
|
| Xray | `32443` | `8080` | Allowed | Public tunneling endpoint |
|
||||||
|
|
||||||
|
Additional UFW allowed ports with no matching Docker-published service in the 2026-06-24 Docker snapshot:
|
||||||
|
|
||||||
|
* `8080/tcp`
|
||||||
|
* `8085/tcp`
|
||||||
|
* `8444/tcp`
|
||||||
|
|
||||||
|
Database ports:
|
||||||
|
|
||||||
|
* PostgreSQL exposes `5432/tcp` only inside Docker.
|
||||||
|
* MSSQL exposes `1433/tcp` only inside Docker.
|
||||||
|
* DbGate exposes `3000/tcp` only inside Docker.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Topology Summary
|
||||||
|
|
||||||
|
```text
|
||||||
|
Internet
|
||||||
|
-> Nginx Proxy Manager
|
||||||
|
-> proxy network
|
||||||
|
-> Gitea
|
||||||
|
-> OpenProject
|
||||||
|
-> Portainer
|
||||||
|
-> DbGate
|
||||||
|
-> Xray
|
||||||
|
-> Jitsi Web
|
||||||
|
-> BaGet
|
||||||
|
|
||||||
|
internal network
|
||||||
|
-> PostgreSQL
|
||||||
|
-> Microsoft SQL Server Express
|
||||||
|
-> backend service database access
|
||||||
|
|
||||||
|
isolated networks
|
||||||
|
-> jitsi-docker-jitsi-meet-aa76415_meet.jitsi
|
||||||
|
-> xray_default
|
||||||
|
-> gitea-runner_default
|
||||||
|
-> monitoring stack network
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Default Docker Networks
|
||||||
|
|
||||||
|
Docker default networks remain present:
|
||||||
|
|
||||||
|
* `bridge`
|
||||||
|
* `host`
|
||||||
|
* `none`
|
||||||
|
|
||||||
|
These are system defaults and are not the preferred routing model for SilverLinux application services.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification Checklist
|
||||||
|
|
||||||
|
Periodically verify:
|
||||||
|
|
||||||
|
* PostgreSQL and MSSQL are attached only to private networks required by their consumers
|
||||||
|
* Nginx Proxy Manager remains the only reverse proxy for HTTP services
|
||||||
|
* Nginx Proxy Manager routes match the documented proxy-host table in `docs/domains.md`
|
||||||
|
* DbGate authentication is enabled and tested
|
||||||
|
* DbGate and Portainer have an access restriction policy
|
||||||
|
* Xray exposure policy is documented and monitored
|
||||||
|
* Jitsi Web is reachable through `proxy`
|
||||||
|
* Jitsi internal components remain attached to `jitsi-docker-jitsi-meet-aa76415_meet.jitsi`
|
||||||
|
* The desired Xray attachment is reconciled with the fact that `xray_default` currently has no running containers
|
||||||
|
* Direct host-published ports are intentional and protected by firewall policy
|
||||||
|
* UFW-only allowed ports have documented owners
|
||||||
|
* Prometheus targets remain healthy
|
||||||
|
* Grafana datasource connection remains healthy
|
||||||
|
* Unused Docker networks are removed only after confirming they are not active dependencies
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/services.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/monitoring.md
|
||||||
|
* docs/decisions.md
|
||||||
|
* nginx-proxy-manager/README.md
|
||||||
+359
@@ -0,0 +1,359 @@
|
|||||||
|
# Roadmap
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document tracks planned SilverLinux infrastructure improvements.
|
||||||
|
|
||||||
|
The roadmap focuses on observability, access control, security hardening, platform services and backup maturity.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Planned Capabilities
|
||||||
|
|
||||||
|
### Collaboration And Storage
|
||||||
|
|
||||||
|
#### Nextcloud
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Self-hosted file sharing
|
||||||
|
* Team document storage
|
||||||
|
* Optional collaboration layer for internal operations
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Observability
|
||||||
|
|
||||||
|
#### Grafana And Prometheus
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Metrics collection
|
||||||
|
* Dashboards and visualization
|
||||||
|
* Host and container health monitoring
|
||||||
|
* Alerting foundation
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Completed
|
||||||
|
```
|
||||||
|
|
||||||
|
Completed components:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
|
||||||
|
* Prometheus UI validated
|
||||||
|
* Prometheus targets validated
|
||||||
|
* Grafana datasource connected to Prometheus
|
||||||
|
* Initial dashboards created and validated
|
||||||
|
* Alertmanager email routing validated
|
||||||
|
|
||||||
|
Alerting:
|
||||||
|
|
||||||
|
* Incident grouping implemented
|
||||||
|
* Severity-based routing implemented
|
||||||
|
* Alert deduplication implemented
|
||||||
|
* Multi-recipient email alerts implemented
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Loki
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Central log aggregation
|
||||||
|
* Log exploration through Grafana
|
||||||
|
* Faster incident investigation
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Sentry
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Application error tracking
|
||||||
|
* Release health visibility
|
||||||
|
* Exception diagnostics for deployed apps
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Identity And Access
|
||||||
|
|
||||||
|
#### Authelia
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Identity and access management for exposed admin areas
|
||||||
|
* SSO gateway for sensitive services
|
||||||
|
* Additional protection for DbGate, Portainer, Gitea admin areas and OpenProject admin areas
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Security Hardening
|
||||||
|
|
||||||
|
#### Fail2Ban Upgrade
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Improve brute-force protection
|
||||||
|
* Expand jail coverage beyond SSH where practical
|
||||||
|
* Align detection with exposed administrative services
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### CrowdSec
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Collaborative intrusion detection
|
||||||
|
* Behavior-based blocking
|
||||||
|
* Additional protection for public endpoints
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Cloudflare Rate Limiting And WAF
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Rate limiting for exposed admin areas
|
||||||
|
* WAF rules for common attack patterns
|
||||||
|
* Brute-force protection before traffic reaches SilverLinux
|
||||||
|
|
||||||
|
Target areas:
|
||||||
|
|
||||||
|
* DbGate
|
||||||
|
* Portainer
|
||||||
|
* Gitea administrator areas
|
||||||
|
* OpenProject administrator areas
|
||||||
|
* Prototype and demo endpoints where appropriate
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Platform Services
|
||||||
|
|
||||||
|
#### Harbor
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Docker image registry
|
||||||
|
* Internal image distribution
|
||||||
|
* Container artifact management
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### SonarQube
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Code quality scanning
|
||||||
|
* Security scanning
|
||||||
|
* Technical debt tracking
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Backstage
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Internal developer portal
|
||||||
|
* Service catalog
|
||||||
|
* Platform documentation entry point
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
#### Redis
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Caching layer for databases and high-traffic application reads
|
||||||
|
* Session storage where supported by applications
|
||||||
|
* Future scaling support
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backup And Restore
|
||||||
|
|
||||||
|
#### Restic
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Versioned backup jobs
|
||||||
|
* Restore workflows
|
||||||
|
* Encrypted backups
|
||||||
|
* Better backup retention management
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Planned
|
||||||
|
```
|
||||||
|
|
||||||
|
Current backup status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Backup v5.3 production
|
||||||
|
```
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
|
||||||
|
* Daily cron backup
|
||||||
|
* Email reports
|
||||||
|
* HTML reports
|
||||||
|
* Automatic archive generation
|
||||||
|
* Automatic cleanup
|
||||||
|
* Backup metrics export
|
||||||
|
* Restore validation
|
||||||
|
* Lock file protection
|
||||||
|
* Disk space validation
|
||||||
|
* Central logging
|
||||||
|
* Structured failure handling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Priority Phases
|
||||||
|
|
||||||
|
### Phase 1 - Immediate Impact
|
||||||
|
|
||||||
|
Items:
|
||||||
|
|
||||||
|
* Loki
|
||||||
|
* Redis
|
||||||
|
* Authelia
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
|
||||||
|
* Grafana
|
||||||
|
* Prometheus
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* Alertmanager
|
||||||
|
* Backup metrics integration
|
||||||
|
* Incident intelligence
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 2 - Security And Stability
|
||||||
|
|
||||||
|
Items:
|
||||||
|
|
||||||
|
* CrowdSec
|
||||||
|
* Sentry
|
||||||
|
* Fail2Ban upgrade
|
||||||
|
* Cloudflare rate limiting and WAF
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
|
||||||
|
* Backup v5.3 automation
|
||||||
|
* Restore validation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3 - Scale And Enterprise Services
|
||||||
|
|
||||||
|
Items:
|
||||||
|
|
||||||
|
* SonarQube
|
||||||
|
* Harbor Docker registry
|
||||||
|
* Backstage portal
|
||||||
|
* Nextcloud
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation Requirements
|
||||||
|
|
||||||
|
Each roadmap item should receive documentation before deployment:
|
||||||
|
|
||||||
|
* Service purpose
|
||||||
|
* Docker Compose location
|
||||||
|
* Data and backup paths
|
||||||
|
* Network attachments
|
||||||
|
* Public exposure policy
|
||||||
|
* Authentication model
|
||||||
|
* Secrets required
|
||||||
|
* Restore procedure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/services.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/network.md
|
||||||
|
* docs/backups.md
|
||||||
|
* docs/monitoring.md
|
||||||
|
* docs/decisions.md
|
||||||
+228
@@ -0,0 +1,228 @@
|
|||||||
|
# Secrets Management
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux uses a centralized secrets file for shared credentials and sensitive configuration.
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
This file is stored on the server and is never committed to Git.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
The secrets file provides a single location for:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* Database passwords
|
||||||
|
* Application secrets
|
||||||
|
* OAuth client secrets
|
||||||
|
* Future API keys
|
||||||
|
|
||||||
|
Applications should load secrets using:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
env_file:
|
||||||
|
- /srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current Variables
|
||||||
|
|
||||||
|
### Email
|
||||||
|
|
||||||
|
```text
|
||||||
|
SMTP_HOST
|
||||||
|
SMTP_PORT
|
||||||
|
SMTP_USERNAME
|
||||||
|
SMTP_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Future services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
```text
|
||||||
|
POSTGRES_ROOT_PASSWORD
|
||||||
|
POSTGRES_OPENPROJECT_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* OpenProject
|
||||||
|
* Gitea
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Microsoft SQL Server
|
||||||
|
|
||||||
|
```text
|
||||||
|
MSSQL_SA_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* Microsoft SQL Server 2022 Express
|
||||||
|
* DbGate's MSSQL connection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
```text
|
||||||
|
OPENPROJECT_SECRET_KEY_BASE
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* OpenProject
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea Actions Runner
|
||||||
|
|
||||||
|
```text
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* The global `silverlinux-runner`
|
||||||
|
* Runner registration and reconnection
|
||||||
|
|
||||||
|
Repository workflow credentials, including `BAGET_API_KEY`, are stored in Gitea under **Repository Settings -> Actions -> Secrets** and are not stored in repositories.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Jitsi
|
||||||
|
|
||||||
|
```text
|
||||||
|
JICOFO_AUTH_PASSWORD
|
||||||
|
JVB_AUTH_PASSWORD
|
||||||
|
JIBRI_XMPP_PASSWORD
|
||||||
|
JIBRI_RECORDER_PASSWORD
|
||||||
|
JIGASI_XMPP_PASSWORD
|
||||||
|
JIGASI_TRANSCRIBER_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* Jitsi Meet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Future OAuth
|
||||||
|
|
||||||
|
```text
|
||||||
|
GOOGLE_CLIENT_ID
|
||||||
|
GOOGLE_CLIENT_SECRET
|
||||||
|
|
||||||
|
GITHUB_CLIENT_ID
|
||||||
|
GITHUB_CLIENT_SECRET
|
||||||
|
|
||||||
|
MICROSOFT_CLIENT_ID
|
||||||
|
MICROSOFT_CLIENT_SECRET
|
||||||
|
```
|
||||||
|
|
||||||
|
Future use:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Other applications
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DbGate Credential Migration
|
||||||
|
|
||||||
|
The running DbGate deployment currently has its login credential in the server-side Compose configuration. Move the password to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
DBGATE_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
The repository Compose definition already references `DBGATE_PASSWORD` and contains no real password.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Migration pending
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
* Never commit secrets to Git.
|
||||||
|
* Never store passwords directly in docker-compose files.
|
||||||
|
* Never share the contents of company.env.
|
||||||
|
* Use environment variables whenever possible.
|
||||||
|
* Use `.env.example` files for documentation.
|
||||||
|
* Rotate credentials immediately if exposure is suspected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Requirements
|
||||||
|
|
||||||
|
The following file must be included in server backups:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Loss of this file may prevent applications from starting correctly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recovery Procedure
|
||||||
|
|
||||||
|
If the server must be rebuilt:
|
||||||
|
|
||||||
|
1. Restore `/srv/secrets/company.env`
|
||||||
|
2. Verify file permissions
|
||||||
|
3. Deploy Docker stacks
|
||||||
|
4. Verify services can access required variables
|
||||||
|
5. Verify SMTP functionality
|
||||||
|
6. Verify database connectivity
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
The secrets file contains credentials for multiple services.
|
||||||
|
|
||||||
|
Access should be restricted to system administrators only.
|
||||||
|
|
||||||
|
Recommended permissions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 600 /srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Recommended ownership:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
root:root
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documents
|
||||||
|
|
||||||
|
* docs/email.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/server.md
|
||||||
|
* docs/backups.md
|
||||||
@@ -0,0 +1,380 @@
|
|||||||
|
# Security
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux hosts critical infrastructure for Silver Solutions.
|
||||||
|
|
||||||
|
This document describes the security measures implemented on the server and operational security requirements.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Access Control
|
||||||
|
|
||||||
|
### SSH Access
|
||||||
|
|
||||||
|
SSH access is limited to authorized administrators.
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
|
||||||
|
* SSH key authentication
|
||||||
|
* Password login discouraged
|
||||||
|
* Root login disabled
|
||||||
|
|
||||||
|
Primary user:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ubuntu
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Firewall
|
||||||
|
|
||||||
|
### UFW
|
||||||
|
|
||||||
|
UFW is enabled and used as the primary host firewall.
|
||||||
|
|
||||||
|
Verified allowed incoming ports from `sudo ufw status verbose`:
|
||||||
|
|
||||||
|
| Port | Purpose |
|
||||||
|
| ---- | ------- |
|
||||||
|
| 22 | SSH |
|
||||||
|
| 80 | HTTP |
|
||||||
|
| 443 | HTTPS |
|
||||||
|
| 2222 | Gitea Git SSH |
|
||||||
|
| 10000/udp | Jitsi JVB media |
|
||||||
|
| 8085 | Explicitly allowed non-standard TCP port |
|
||||||
|
| 8443 | Explicitly allowed non-standard HTTPS port |
|
||||||
|
| 8444 | Explicitly allowed non-standard TCP port |
|
||||||
|
| 8080 | Explicitly allowed non-standard TCP port |
|
||||||
|
| 32443 | Xray public tunneling endpoint |
|
||||||
|
|
||||||
|
Default policy:
|
||||||
|
|
||||||
|
* deny incoming
|
||||||
|
* allow outgoing
|
||||||
|
* deny routed
|
||||||
|
|
||||||
|
All other ports should remain blocked unless explicitly required.
|
||||||
|
|
||||||
|
Known runtime-published non-standard ports from the 2026-06-24 Docker snapshot:
|
||||||
|
|
||||||
|
| Port | Service | UFW state | Notes |
|
||||||
|
| ---- | ------- | --------- | ----- |
|
||||||
|
| 81 | Nginx Proxy Manager | Not listed as allowed | Admin interface is published by Docker, but not allowed by UFW snapshot |
|
||||||
|
| 2222 | Gitea | Allowed | Git SSH |
|
||||||
|
| 32443 | Xray | Allowed | Public tunneling endpoint |
|
||||||
|
| 5555 | BaGet | Not listed as allowed | Direct HTTP port is published by Docker, but not allowed by UFW snapshot |
|
||||||
|
| 8000 | Jitsi Web | Not listed as allowed | Direct HTTP port is published by Docker, but not allowed by UFW snapshot |
|
||||||
|
| 8443 | Jitsi Web | Allowed | Direct HTTPS port |
|
||||||
|
| 10000/udp | Jitsi JVB | Allowed | Required media bridge traffic |
|
||||||
|
| 8082 | OpenProject | Not listed as allowed | Direct HTTP port is published by Docker, but not allowed by UFW snapshot |
|
||||||
|
|
||||||
|
These ports must either be intentionally allowed and documented in UFW, or blocked at the host firewall if only Nginx Proxy Manager should be public.
|
||||||
|
|
||||||
|
UFW also allows `8080`, `8085` and `8444`, but no matching Docker-published service was identified in the 2026-06-24 Docker snapshot. These rules should be reviewed and removed if they are no longer required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Intrusion Protection
|
||||||
|
|
||||||
|
### Fail2Ban
|
||||||
|
|
||||||
|
Fail2Ban is enabled.
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Detect brute-force attacks
|
||||||
|
* Automatically block malicious IP addresses
|
||||||
|
* Protect SSH access
|
||||||
|
|
||||||
|
Planned improvements:
|
||||||
|
|
||||||
|
* Upgrade Fail2Ban coverage
|
||||||
|
* Add CrowdSec for collaborative intrusion detection
|
||||||
|
* Add Cloudflare rate limiting and WAF for exposed administrative endpoints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets Management
|
||||||
|
|
||||||
|
Shared secrets are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* PostgreSQL passwords
|
||||||
|
* MSSQL SA password
|
||||||
|
* OpenProject secrets
|
||||||
|
* Future OAuth secrets
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
* Never commit secrets to Git
|
||||||
|
* Never share secrets in documentation
|
||||||
|
* Never hardcode passwords in Docker Compose files
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/secrets.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSL Certificates
|
||||||
|
|
||||||
|
SSL certificates are managed through Nginx Proxy Manager.
|
||||||
|
|
||||||
|
Certificates are automatically renewed.
|
||||||
|
|
||||||
|
All public services should be accessible through HTTPS only.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Public Exposure
|
||||||
|
|
||||||
|
Public HTTP and HTTPS services are routed through the `proxy` Docker network and Nginx Proxy Manager.
|
||||||
|
|
||||||
|
Publicly exposed services:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Portainer
|
||||||
|
* DbGate
|
||||||
|
* Xray
|
||||||
|
* Jitsi Web
|
||||||
|
* BaGet
|
||||||
|
|
||||||
|
High-sensitivity exposure:
|
||||||
|
|
||||||
|
* DbGate exposes a database administration interface and must always require authentication and HTTPS.
|
||||||
|
* Xray exposes tunneling capability and must be monitored for abuse, unexpected traffic and unauthorized use.
|
||||||
|
* Portainer exposes Docker management and must be restricted to trusted administrators.
|
||||||
|
|
||||||
|
Nginx Proxy Manager findings from the 2026-06-24 proxy-host snapshot:
|
||||||
|
|
||||||
|
* No proxy host had an Nginx Proxy Manager access list assigned.
|
||||||
|
* DbGate was enabled without SSL Force, HTTP/2 or HSTS.
|
||||||
|
* Gitea, Jitsi Meet and BaGet were enabled without SSL Force.
|
||||||
|
* Plane.so has been removed from containers, Nginx Proxy Manager and server certificate storage.
|
||||||
|
* `cicd.silveressence.net` is intentionally enabled as a frequently changing prototype deployment endpoint.
|
||||||
|
* `exactsyncer.silveressence.net` is intentionally enabled as a client-facing Exact Online syncer demo endpoint.
|
||||||
|
|
||||||
|
Priority hardening:
|
||||||
|
|
||||||
|
1. Enable SSL Force for all HTTPS public service routes unless there is a documented exception.
|
||||||
|
2. Add an access list or equivalent restriction for DbGate and Portainer.
|
||||||
|
3. Define explicit exposure and authentication expectations for prototype and demo endpoints.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Email Security
|
||||||
|
|
||||||
|
Outgoing email is provided through Gmail SMTP.
|
||||||
|
|
||||||
|
Credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
* Use Gmail App Passwords only
|
||||||
|
* Never store personal account passwords
|
||||||
|
* Rotate credentials if exposure is suspected
|
||||||
|
|
||||||
|
Sender address:
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### Current
|
||||||
|
|
||||||
|
* Local user accounts
|
||||||
|
* Strong passwords
|
||||||
|
|
||||||
|
### Planned
|
||||||
|
|
||||||
|
Future OAuth providers:
|
||||||
|
|
||||||
|
* Google OAuth2
|
||||||
|
* GitHub OAuth2
|
||||||
|
* Authelia SSO for exposed admin areas
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
* Store client secrets in company.env
|
||||||
|
* Use least-privilege scopes
|
||||||
|
* Disable unused authentication providers
|
||||||
|
|
||||||
|
Planned protected areas:
|
||||||
|
|
||||||
|
* DbGate
|
||||||
|
* Portainer
|
||||||
|
* Gitea administrator areas
|
||||||
|
* OpenProject administrator areas
|
||||||
|
|
||||||
|
### Disabled
|
||||||
|
|
||||||
|
* OpenID authentication
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
OpenID is not required and increases attack surface.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Two-Factor Authentication
|
||||||
|
|
||||||
|
Where supported:
|
||||||
|
|
||||||
|
* Enable 2FA for administrator accounts
|
||||||
|
* Encourage 2FA for all users
|
||||||
|
|
||||||
|
Priority:
|
||||||
|
|
||||||
|
1. Gitea administrators
|
||||||
|
2. OpenProject administrators
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Security
|
||||||
|
|
||||||
|
PostgreSQL and Microsoft SQL Server are not exposed publicly.
|
||||||
|
|
||||||
|
Database access is restricted to Docker internal networks.
|
||||||
|
|
||||||
|
Applications and DbGate communicate with the database containers through the `internal` Docker network.
|
||||||
|
|
||||||
|
DbGate is the public administration entry point and must require authentication and HTTPS. Its web interface is routed through Nginx Proxy Manager; database ports `5432` and `1433` remain private.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Connectivity Layer Security
|
||||||
|
|
||||||
|
Xray is classified as a network tunneling and connectivity layer, not as an application service.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
* Keep the Xray service isolated from private database networks unless a documented need exists.
|
||||||
|
* Monitor logs and traffic patterns for abuse.
|
||||||
|
* Review access policy after configuration changes.
|
||||||
|
* Keep secrets, UUIDs, keys and endpoint credentials outside the repository.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Security
|
||||||
|
|
||||||
|
Services are isolated through Docker containers.
|
||||||
|
|
||||||
|
Principles:
|
||||||
|
|
||||||
|
* Public services should be exposed only through Nginx Proxy Manager
|
||||||
|
* Internal services should not expose ports publicly
|
||||||
|
* Services should communicate through Docker networks
|
||||||
|
* Containers should run with the minimum required privileges
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
* proxy
|
||||||
|
* internal
|
||||||
|
* jitsi-docker-jitsi-meet-aa76415_meet.jitsi
|
||||||
|
* xray_default
|
||||||
|
* gitea-runner_default
|
||||||
|
|
||||||
|
Network model:
|
||||||
|
|
||||||
|
* `internal` is for private database and backend traffic.
|
||||||
|
* `proxy` is for public HTTP and HTTPS services controlled by Nginx Proxy Manager.
|
||||||
|
* Isolated stack networks are used for Jitsi, Xray and CI/CD runner separation.
|
||||||
|
* `xray_default` currently exists without a running container attached; the active `xray` container is attached to `proxy`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System Updates
|
||||||
|
|
||||||
|
The operating system and containers should be updated regularly.
|
||||||
|
|
||||||
|
Recommendations:
|
||||||
|
|
||||||
|
* Apply Ubuntu security updates
|
||||||
|
* Update Docker images periodically
|
||||||
|
* Remove unused containers and images
|
||||||
|
* Review security advisories for critical services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Security
|
||||||
|
|
||||||
|
Backups must include:
|
||||||
|
|
||||||
|
* Configuration files
|
||||||
|
* Docker Compose files
|
||||||
|
* Application data
|
||||||
|
* PostgreSQL databases
|
||||||
|
* Shared secrets
|
||||||
|
|
||||||
|
Backups must never be stored inside public repositories.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Review Checklist
|
||||||
|
|
||||||
|
Periodically verify:
|
||||||
|
|
||||||
|
* SSH keys are current
|
||||||
|
* Unused accounts are removed
|
||||||
|
* Fail2Ban is active
|
||||||
|
* Planned CrowdSec and Cloudflare WAF status is reviewed
|
||||||
|
* UFW is active
|
||||||
|
* SSL certificates are valid
|
||||||
|
* Secrets are not stored in repositories
|
||||||
|
* Backups are functioning
|
||||||
|
* Administrator accounts have 2FA enabled
|
||||||
|
* DbGate login is enforced
|
||||||
|
* DbGate proxy route has SSL Force and an access restriction policy
|
||||||
|
* Xray exposure policy is still valid
|
||||||
|
* Public services are still routed only through Nginx Proxy Manager
|
||||||
|
* Removed proxy hosts and unused certificates stay removed unless explicitly approved
|
||||||
|
* Prototype and demo proxy hosts have documented owners and exposure expectations
|
||||||
|
* Direct host-published ports are intentional or blocked by UFW
|
||||||
|
* UFW rules `8080`, `8085` and `8444` still have a documented owner
|
||||||
|
* Review application logs
|
||||||
|
* Review Docker logs
|
||||||
|
* Review authentication failures
|
||||||
|
* Review Fail2Ban bans
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Incident Response
|
||||||
|
|
||||||
|
If a credential is exposed:
|
||||||
|
|
||||||
|
1. Rotate the credential immediately.
|
||||||
|
2. Update `/srv/secrets/company.env`.
|
||||||
|
3. Restart affected services.
|
||||||
|
4. Review logs for unauthorized access.
|
||||||
|
5. Update documentation if required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/backups.md
|
||||||
|
* docs/email.md
|
||||||
|
* docs/network.md
|
||||||
|
* docs/roadmap.md
|
||||||
|
* nginx-proxy-manager/README.md
|
||||||
+442
@@ -0,0 +1,442 @@
|
|||||||
|
# Server Information
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux is the primary self-hosted infrastructure server for Silver Solutions.
|
||||||
|
|
||||||
|
The server hosts source control, project management, collaboration, communication and supporting infrastructure services.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Host Information
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
| ---------------- | ----------------------- |
|
||||||
|
| Hostname | silverlinux |
|
||||||
|
| Provider | OVH |
|
||||||
|
| Operating System | Ubuntu Server 24.04 LTS |
|
||||||
|
| Public IP | 51.255.83.140 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
| Resource | Value |
|
||||||
|
| -------- | -------------------- |
|
||||||
|
| CPU | Intel Xeon-D 1520 |
|
||||||
|
| Memory | 32 GB RAM |
|
||||||
|
| Storage | 2 × 480 GB SSD RAID1 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installed Software
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Container hosting
|
||||||
|
* Service isolation
|
||||||
|
* Deployment management
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Multi-container application deployment
|
||||||
|
* Service management
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Primary PostgreSQL database platform
|
||||||
|
|
||||||
|
### Microsoft SQL Server Express
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private SQL Server platform for compatible applications
|
||||||
|
|
||||||
|
### Fail2Ban
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* SSH brute-force protection
|
||||||
|
|
||||||
|
### UFW
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Firewall management
|
||||||
|
|
||||||
|
### Monitoring Stack
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Metrics collection
|
||||||
|
* Monitoring dashboards
|
||||||
|
* Host metrics
|
||||||
|
* Docker container metrics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Networks
|
||||||
|
|
||||||
|
### internal
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Private communication between services.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* Gitea → PostgreSQL
|
||||||
|
* OpenProject → PostgreSQL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### proxy
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Public-facing services behind Nginx Proxy Manager.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
* Portainer
|
||||||
|
* DbGate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### jitsi-docker-jitsi-meet-aa76415_meet.jitsi
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Isolated Jitsi communication cluster.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* jitsi-web
|
||||||
|
* jitsi-jvb
|
||||||
|
* jitsi-jicofo
|
||||||
|
* jitsi-prosody
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### xray_default
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Compose-created tunneling and connectivity network for Xray.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* No running containers were attached in the 2026-06-24 runtime snapshot
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### gitea-runner_default
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Default Compose network for the Gitea Actions runner stack.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* gitea-runner
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running Services
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
* Portainer
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* BaGet
|
||||||
|
* Gitea Actions Runner
|
||||||
|
* Microsoft SQL Server 2022 Express
|
||||||
|
* DbGate
|
||||||
|
* Xray
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
### Docker Services
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea
|
||||||
|
/srv/docker/openproject
|
||||||
|
/srv/docker/postgres
|
||||||
|
/srv/docker/jitsi
|
||||||
|
/srv/docker/portainer
|
||||||
|
/srv/docker/nginx-proxy-manager
|
||||||
|
/srv/docker/baget
|
||||||
|
/srv/docker/gitea-runner
|
||||||
|
/srv/docker/mssql
|
||||||
|
/srv/docker/dbgate
|
||||||
|
/srv/docker/xray
|
||||||
|
/srv/docker/monitoring
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Shared Secrets
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* Database passwords
|
||||||
|
* Application secrets
|
||||||
|
* MSSQL SA password
|
||||||
|
* Future DbGate password
|
||||||
|
* Future OAuth credentials
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backups
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/backups
|
||||||
|
```
|
||||||
|
|
||||||
|
Suggested structure:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/backups/daily
|
||||||
|
/srv/backups/weekly
|
||||||
|
/srv/backups/monthly
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Data Locations
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea/data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/openproject/assets
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/postgres/data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Microsoft SQL Server Express
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/mssql/data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DbGate
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/dbgate/data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Nginx Proxy Manager
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/data
|
||||||
|
/srv/docker/nginx-proxy-manager/letsencrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Jitsi
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/jitsi
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BaGet
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/baget/data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea Actions Runner
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
Runner:
|
||||||
|
|
||||||
|
```text
|
||||||
|
silverlinux-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Xray
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/xray
|
||||||
|
```
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Published port:
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.0.0:32443 -> 8080/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
Image:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ghcr.io/xtls/xray-core:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Runtime note:
|
||||||
|
|
||||||
|
The `xray_default` network exists, but the running `xray` container was attached only to `proxy` in the 2026-06-24 runtime snapshot.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Monitoring Stack
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/monitoring
|
||||||
|
```
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Grafana
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
|
||||||
|
Validated:
|
||||||
|
|
||||||
|
* Prometheus targets
|
||||||
|
* Grafana Prometheus datasource
|
||||||
|
* Backup metrics
|
||||||
|
* Host metrics
|
||||||
|
* Docker metrics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSH Access
|
||||||
|
|
||||||
|
Primary user:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ubuntu
|
||||||
|
```
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
|
||||||
|
* SSH key authentication
|
||||||
|
* Root login disabled
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Implemented:
|
||||||
|
|
||||||
|
* UFW enabled
|
||||||
|
* Fail2Ban enabled
|
||||||
|
* Shared secrets stored outside Git repositories
|
||||||
|
* SSL certificates managed through Nginx Proxy Manager
|
||||||
|
* PostgreSQL not exposed publicly
|
||||||
|
* MSSQL port 1433 not exposed publicly
|
||||||
|
* Database administration is available only through authenticated HTTPS access to DbGate
|
||||||
|
* Xray is not attached to the private database network and is monitored as a tunneling endpoint
|
||||||
|
* OpenID disabled in Gitea
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Email
|
||||||
|
|
||||||
|
Sender address:
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
SMTP credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Disaster Recovery
|
||||||
|
|
||||||
|
This repository should contain enough information to rebuild the SilverLinux environment from scratch.
|
||||||
|
|
||||||
|
Recovery priorities:
|
||||||
|
|
||||||
|
1. Restore secrets
|
||||||
|
2. Restore PostgreSQL
|
||||||
|
3. Restore Nginx Proxy Manager
|
||||||
|
4. Restore Gitea
|
||||||
|
5. Restore OpenProject
|
||||||
|
6. Restore remaining services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/backups.md
|
||||||
|
* docs/services.md
|
||||||
|
* docs/network.md
|
||||||
|
* docs/domains.md
|
||||||
@@ -0,0 +1,599 @@
|
|||||||
|
# Services
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document lists all services running on SilverLinux and their purpose.
|
||||||
|
|
||||||
|
Generated state reference:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026-06-25 infrastructure review
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running Services
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Primary shared database platform
|
||||||
|
* Application data storage
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Microsoft SQL Server Express
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Secondary database platform for SQL Server compatibility
|
||||||
|
* Support future applications requiring Microsoft SQL Server
|
||||||
|
* Extend the platform beyond PostgreSQL-only workloads
|
||||||
|
|
||||||
|
Image:
|
||||||
|
|
||||||
|
```text
|
||||||
|
mcr.microsoft.com/mssql/server:2022-latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
Exposure:
|
||||||
|
|
||||||
|
* Port 1433 is not published
|
||||||
|
* Not routed through Nginx Proxy Manager
|
||||||
|
* Private database access only
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://git.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Source control
|
||||||
|
* Git repositories
|
||||||
|
* Pull requests
|
||||||
|
* Issue tracking
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### OpenProject
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://team.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Project management
|
||||||
|
* Work packages
|
||||||
|
* Time tracking
|
||||||
|
* Team collaboration
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Jitsi Meet
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://meet.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Video conferencing
|
||||||
|
* Team meetings
|
||||||
|
* Customer meetings
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Portainer
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://portainer.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Docker administration
|
||||||
|
* Stack deployment
|
||||||
|
* Container monitoring
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Nginx Proxy Manager
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Reverse proxy
|
||||||
|
* SSL termination
|
||||||
|
* Domain routing
|
||||||
|
* Certificate management
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Prometheus
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Metrics collection
|
||||||
|
* Alert rule engine
|
||||||
|
* Monitoring data storage
|
||||||
|
* Scrape targets for system, Docker and backup metrics
|
||||||
|
|
||||||
|
Scrapes:
|
||||||
|
|
||||||
|
* Prometheus
|
||||||
|
* Node Exporter
|
||||||
|
* cAdvisor
|
||||||
|
* SilverLinux backup metrics
|
||||||
|
|
||||||
|
Alert categories:
|
||||||
|
|
||||||
|
* Backup
|
||||||
|
* System pressure
|
||||||
|
* Monitoring health
|
||||||
|
* Database availability
|
||||||
|
* Container health
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Grafana
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Monitoring dashboards
|
||||||
|
* Metrics visualization
|
||||||
|
* Prometheus datasource frontend
|
||||||
|
|
||||||
|
Dashboards:
|
||||||
|
|
||||||
|
* Custom backup dashboard
|
||||||
|
* Custom system dashboard
|
||||||
|
* Docker monitoring dashboard
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
The imported Prometheus 2.0 Overview dashboard is not compatible with the installed Prometheus version `3.5.4`. This is a third-party dashboard compatibility issue, not an infrastructure problem.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Alertmanager
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Alert routing
|
||||||
|
* Email notifications
|
||||||
|
* Incident grouping
|
||||||
|
* Alert deduplication
|
||||||
|
* Severity-based routing
|
||||||
|
|
||||||
|
Recipients:
|
||||||
|
|
||||||
|
* `oclick021@gmail.com`
|
||||||
|
* `martin@silversolutions.nl`
|
||||||
|
|
||||||
|
Incident groups:
|
||||||
|
|
||||||
|
* `backup_failure`
|
||||||
|
* `system_pressure`
|
||||||
|
* `storage_pressure`
|
||||||
|
* `database_outage`
|
||||||
|
* `monitoring_failure`
|
||||||
|
* `container_health`
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Node Exporter
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Host metrics collection
|
||||||
|
* CPU, memory and disk metrics
|
||||||
|
* Textfile Collector endpoint for SilverLinux backup metrics
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### cAdvisor
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Docker container metrics
|
||||||
|
* Container CPU, memory and runtime visibility
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BaGet
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://nuget.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private NuGet repository
|
||||||
|
* Internal Silver.* package distribution
|
||||||
|
* Package source for CI/CD
|
||||||
|
* Package source for team development
|
||||||
|
|
||||||
|
Access:
|
||||||
|
|
||||||
|
* Routed through Nginx Proxy Manager
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea Actions Runner
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
Image:
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea/act_runner:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Runner Name:
|
||||||
|
|
||||||
|
```text
|
||||||
|
silverlinux-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
Type:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Global Runner
|
||||||
|
```
|
||||||
|
|
||||||
|
Labels:
|
||||||
|
|
||||||
|
* `ubuntu-latest`
|
||||||
|
* `ubuntu-24.04`
|
||||||
|
* `ubuntu-22.04`
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DbGate
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://dbgate.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Browser-based PostgreSQL administration
|
||||||
|
* Browser-based MSSQL administration
|
||||||
|
* Database explorer and debugging interface
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
* `internal` for private database connectivity
|
||||||
|
* `proxy` for Nginx Proxy Manager
|
||||||
|
|
||||||
|
Security:
|
||||||
|
|
||||||
|
* Publicly reachable through the proxy layer
|
||||||
|
* HTTPS enforced
|
||||||
|
* DbGate username and password required
|
||||||
|
* Authentication must remain hardened and periodically verified
|
||||||
|
* Database ports remain private
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Xray
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Connectivity and tunneling layer
|
||||||
|
* Improve long-distance connectivity stability to SilverLinux
|
||||||
|
* Maintain secure routing paths when direct connectivity is limited
|
||||||
|
|
||||||
|
Classification:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Network tunneling / connectivity layer
|
||||||
|
```
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
* `proxy`
|
||||||
|
|
||||||
|
Runtime ports:
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.0.0:32443 -> 8080/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
Image:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ghcr.io/xtls/xray-core:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Runtime note:
|
||||||
|
|
||||||
|
* The `xray_default` network exists, but the running `xray` container was attached only to `proxy` in the 2026-06-24 runtime snapshot.
|
||||||
|
|
||||||
|
Security:
|
||||||
|
|
||||||
|
* Public tunneling endpoint exposure must be monitored
|
||||||
|
* Access policy and abuse monitoring must be reviewed regularly
|
||||||
|
* Not classified as an application backend service
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Infrastructure
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Container hosting
|
||||||
|
* Service isolation
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Internal Docker Network
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private communication between services
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Proxy Docker Network
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* HTTP and HTTPS service exposure through Nginx Proxy Manager
|
||||||
|
* Shared public routing layer for web-facing services
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Isolated Docker Networks
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Keep specialized infrastructure stacks isolated from application backends
|
||||||
|
* Separate Jitsi, Xray and CI/CD runner traffic from shared database traffic
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
* `jitsi-docker-jitsi-meet-aa76415_meet.jitsi`
|
||||||
|
* `xray_default`
|
||||||
|
* `gitea-runner_default`
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Shared Secrets
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* Database passwords
|
||||||
|
* Application secrets
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Active
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Removed Services
|
||||||
|
|
||||||
|
## Planned Services
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/roadmap.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Phase 1:
|
||||||
|
|
||||||
|
* Loki
|
||||||
|
* Redis
|
||||||
|
* Authelia
|
||||||
|
|
||||||
|
Phase 2:
|
||||||
|
|
||||||
|
* CrowdSec
|
||||||
|
* Sentry
|
||||||
|
* Restic
|
||||||
|
* Fail2Ban upgrade
|
||||||
|
* Cloudflare rate limiting and WAF
|
||||||
|
|
||||||
|
Phase 3:
|
||||||
|
|
||||||
|
* SonarQube
|
||||||
|
* Harbor
|
||||||
|
* Backstage
|
||||||
|
* Nextcloud
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Plane.so
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
OpenProject was selected as the primary project management platform. Plane.so is not used and will not be used.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Removed
|
||||||
|
```
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
|
||||||
|
* Containers removed
|
||||||
|
* Nginx Proxy Manager route removed
|
||||||
|
* Unused SSL certificate removed from the server
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/network.md
|
||||||
|
* docs/roadmap.md
|
||||||
|
* docs/monitoring.md
|
||||||
|
* docs/domains.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/backups.md
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
USER_UID: 1000
|
||||||
|
USER_GID: 1000
|
||||||
|
GITEA__database__DB_TYPE: postgres
|
||||||
|
GITEA__database__HOST: postgres:5432
|
||||||
|
GITEA__database__NAME: gitea
|
||||||
|
GITEA__database__USER: postgres
|
||||||
|
GITEA__database__PASSWD: Saeed123!
|
||||||
|
GITEA__server__DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__ROOT_URL: https://git.silveressence.net/
|
||||||
|
GITEA__server__SSH_DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__SSH_PORT: 2222
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/gitea/data:/data
|
||||||
|
ports:
|
||||||
|
- "2222:22"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
+400
@@ -0,0 +1,400 @@
|
|||||||
|
# Gitea
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Gitea is the self-hosted Git platform used by Silver Solutions.
|
||||||
|
|
||||||
|
It provides:
|
||||||
|
|
||||||
|
* Git repository hosting
|
||||||
|
* Pull requests
|
||||||
|
* Issue tracking
|
||||||
|
* Wiki support
|
||||||
|
* Releases
|
||||||
|
* CI/CD integration
|
||||||
|
* Package registry support
|
||||||
|
|
||||||
|
Gitea serves as the central source control platform for SilverLinux infrastructure and application development.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
### URL
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://git.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Name
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea/gitea:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Networks
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Gitea is used for:
|
||||||
|
|
||||||
|
* Source control
|
||||||
|
* Infrastructure repositories
|
||||||
|
* Application repositories
|
||||||
|
* Pull requests
|
||||||
|
* Issue management
|
||||||
|
* Release management
|
||||||
|
* Gitea Actions CI/CD pipelines
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
Database:
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
Database Host:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Database User:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Current password source:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POSTGRES_ROOT_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Future improvement:
|
||||||
|
|
||||||
|
Create a dedicated Gitea database user and password.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Email Configuration
|
||||||
|
|
||||||
|
Sender Address:
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Password reset emails
|
||||||
|
* Account notifications
|
||||||
|
* Repository notifications
|
||||||
|
* User invitations
|
||||||
|
|
||||||
|
SMTP configuration is loaded from:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SMTP_HOST
|
||||||
|
SMTP_PORT
|
||||||
|
SMTP_USERNAME
|
||||||
|
SMTP_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### Current
|
||||||
|
|
||||||
|
* Local user accounts
|
||||||
|
* Email login
|
||||||
|
* Password login
|
||||||
|
|
||||||
|
### Disabled
|
||||||
|
|
||||||
|
OpenID authentication is disabled.
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
OpenID is not required and increases the attack surface.
|
||||||
|
|
||||||
|
### Planned
|
||||||
|
|
||||||
|
Future authentication providers:
|
||||||
|
|
||||||
|
* Google OAuth2
|
||||||
|
* GitHub OAuth2
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Easier onboarding of freelancers
|
||||||
|
* Easier onboarding of external collaborators
|
||||||
|
* Reduced password management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSH Access
|
||||||
|
|
||||||
|
SSH Domain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
git.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
SSH Port:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2222
|
||||||
|
```
|
||||||
|
|
||||||
|
Clone example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone ssh://git@git.silveressence.net:2222/username/repository.git
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Storage
|
||||||
|
|
||||||
|
Application Data:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Repositories
|
||||||
|
* Attachments
|
||||||
|
* Configuration
|
||||||
|
* Actions data
|
||||||
|
* Package registry data
|
||||||
|
* User information
|
||||||
|
|
||||||
|
This directory is critical and must be included in backups.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gitea Actions
|
||||||
|
|
||||||
|
Gitea Actions is enabled in `app.ini` and available globally.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
### Global Runner
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Location | `/srv/docker/gitea-runner` |
|
||||||
|
| Image | `gitea/act_runner:latest` |
|
||||||
|
| Name | `silverlinux-runner` |
|
||||||
|
| Type | Global Runner |
|
||||||
|
| Status | Operational |
|
||||||
|
|
||||||
|
Labels:
|
||||||
|
|
||||||
|
* `ubuntu-latest`
|
||||||
|
* `ubuntu-24.04`
|
||||||
|
* `ubuntu-22.04`
|
||||||
|
|
||||||
|
The runner registration token is loaded from `GITEA_RUNNER_REGISTRATION_TOKEN` in `/srv/secrets/company.env`.
|
||||||
|
|
||||||
|
### Package Publishing
|
||||||
|
|
||||||
|
Silver 2.0 uses `.gitea/workflows/package.yml` to build and publish NuGet packages to BaGet. A push to `net-8-version` triggers packaging when the commit message contains `[Package]`.
|
||||||
|
|
||||||
|
The publishing credential is stored as the repository Actions secret `BAGET_API_KEY`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
Gitea and its Actions runner use infrastructure secrets stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POSTGRES_ROOT_PASSWORD
|
||||||
|
|
||||||
|
SMTP_HOST
|
||||||
|
SMTP_PORT
|
||||||
|
SMTP_USERNAME
|
||||||
|
SMTP_PASSWORD
|
||||||
|
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
The Gitea container uses the database and SMTP variables. The Actions runner uses `GITEA_RUNNER_REGISTRATION_TOKEN`.
|
||||||
|
|
||||||
|
Future variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
GOOGLE_CLIENT_ID
|
||||||
|
GOOGLE_CLIENT_SECRET
|
||||||
|
|
||||||
|
GITHUB_CLIENT_ID
|
||||||
|
GITHUB_CLIENT_SECRET
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Configuration
|
||||||
|
|
||||||
|
Volume Mapping:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea/data:/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Port Mapping:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2222:22
|
||||||
|
```
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP traffic is routed through Nginx Proxy Manager.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Administration
|
||||||
|
|
||||||
|
View Logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker restart gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
Open Shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it gitea bash
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Requirements
|
||||||
|
|
||||||
|
The following items must be backed up:
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
### Application Data
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/gitea/data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Secrets
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Without these items, a complete restoration is not possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recovery Checklist
|
||||||
|
|
||||||
|
To restore Gitea:
|
||||||
|
|
||||||
|
1. Restore PostgreSQL database.
|
||||||
|
2. Restore Gitea data directory.
|
||||||
|
3. Restore company.env secrets.
|
||||||
|
4. Deploy Docker Compose stack.
|
||||||
|
5. Verify SMTP configuration.
|
||||||
|
6. Verify SSH access.
|
||||||
|
7. Verify access through Nginx Proxy Manager.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Roadmap
|
||||||
|
|
||||||
|
### Short Term
|
||||||
|
|
||||||
|
* Enable 2FA for administrator accounts
|
||||||
|
* Configure backup automation
|
||||||
|
* Configure Google OAuth2
|
||||||
|
* Configure GitHub OAuth2
|
||||||
|
|
||||||
|
### Long Term
|
||||||
|
|
||||||
|
* Deploy applications directly from Gitea
|
||||||
|
* Expand package publishing to additional repositories
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Services
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* OpenProject
|
||||||
|
* Portainer
|
||||||
|
* BaGet
|
||||||
|
* Gitea Actions Runner
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/backups.md
|
||||||
|
* postgres/README.md
|
||||||
|
* docs/cicd.md
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
USER_UID: 1000
|
||||||
|
USER_GID: 1000
|
||||||
|
GITEA__database__DB_TYPE: postgres
|
||||||
|
GITEA__database__HOST: postgres:5432
|
||||||
|
GITEA__database__NAME: gitea
|
||||||
|
GITEA__database__USER: postgres
|
||||||
|
GITEA__database__PASSWD: Saeed123!
|
||||||
|
GITEA__server__DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__ROOT_URL: https://git.silveressence.net/
|
||||||
|
GITEA__server__SSH_DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__SSH_PORT: 2222
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/gitea/data:/data
|
||||||
|
ports:
|
||||||
|
- "2222:22"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
PUBLIC_URL=https://meet.silveressence.net
|
||||||
|
|
||||||
|
HTTP_PORT=8000
|
||||||
|
HTTPS_PORT=8443
|
||||||
|
|
||||||
|
TZ=Europe/Amsterdam
|
||||||
|
|
||||||
|
ENABLE_AUTH=1
|
||||||
|
ENABLE_GUESTS=1
|
||||||
|
AUTH_TYPE=internal
|
||||||
|
|
||||||
|
JVB_ADVERTISE_IPS=51.255.83.140
|
||||||
|
|
||||||
|
JICOFO_AUTH_PASSWORD=
|
||||||
|
JVB_AUTH_PASSWORD=
|
||||||
|
JIBRI_XMPP_PASSWORD=
|
||||||
|
JIBRI_RECORDER_PASSWORD=
|
||||||
|
JIGASI_XMPP_PASSWORD=
|
||||||
|
JIGASI_TRANSCRIBER_PASSWORD=
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# Jitsi Meet
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Jitsi Meet provides video conferencing capabilities for Silver Solutions.
|
||||||
|
|
||||||
|
URL:
|
||||||
|
|
||||||
|
https://meet.silveressence.net
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
- Team meetings
|
||||||
|
- Customer meetings
|
||||||
|
- Screen sharing
|
||||||
|
- Browser-based conferencing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Current configuration:
|
||||||
|
|
||||||
|
- Internal authentication enabled
|
||||||
|
- Guest access enabled
|
||||||
|
|
||||||
|
Configuration stored in:
|
||||||
|
|
||||||
|
/srv/docker/jitsi/jitsi-docker-jitsi-meet-aa76415/.env
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Important Secrets
|
||||||
|
|
||||||
|
Stored in:
|
||||||
|
|
||||||
|
/srv/secrets/company.env
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
- JICOFO_AUTH_PASSWORD
|
||||||
|
- JVB_AUTH_PASSWORD
|
||||||
|
- JIBRI_XMPP_PASSWORD
|
||||||
|
- JIBRI_RECORDER_PASSWORD
|
||||||
|
- JIGASI_XMPP_PASSWORD
|
||||||
|
- JIGASI_TRANSCRIBER_PASSWORD
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ports
|
||||||
|
|
||||||
|
| Port | Purpose |
|
||||||
|
|--------|---------|
|
||||||
|
| 80 | HTTP |
|
||||||
|
| 443 | HTTPS |
|
||||||
|
| 10000/UDP | Media Traffic |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Location
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
|
||||||
|
/srv/docker/jitsi
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- docs/server.md
|
||||||
|
- docs/security.md
|
||||||
|
- docs/secrets.md
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
# Microsoft SQL Server Express
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Microsoft SQL Server 2022 Express runs alongside PostgreSQL for Silver projects that require Microsoft SQL Server compatibility.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
Verified version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Microsoft SQL Server 2022 Express Edition (64-bit)
|
||||||
|
Linux
|
||||||
|
Version 16.0.4255.1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Container | `mssql` |
|
||||||
|
| Image | `mcr.microsoft.com/mssql/server:2022-latest` |
|
||||||
|
| Edition | Express |
|
||||||
|
| Docker network | `internal` |
|
||||||
|
| Compose location | `/srv/docker/mssql/docker-compose.yml` |
|
||||||
|
| Data location | `/srv/docker/mssql/data` |
|
||||||
|
|
||||||
|
Port `1433` is not published by Docker or exposed through Nginx Proxy Manager. Applications connect privately over the `internal` Docker network using hostname `mssql`.
|
||||||
|
|
||||||
|
Server-side administration must use `docker exec` or another container attached to `internal`; there is no host-bound SQL port in the current configuration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
The SA password is stored outside the repository:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
MSSQL_SA_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Never commit the value to Git or place it directly in the Compose file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
Docker Compose must be given the secrets file for interpolation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /srv/docker/mssql
|
||||||
|
docker compose --env-file /srv/secrets/company.env up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
The Compose `env_file:` setting passes variables into the container. It does not make them available while Compose resolves `${MSSQL_SA_PASSWORD}`, which is why `--env-file` is required.
|
||||||
|
|
||||||
|
Validate startup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker ps
|
||||||
|
docker logs mssql
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected log message:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SQL Server is now ready for client connections.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Directory Permissions
|
||||||
|
|
||||||
|
The SQL Server container runs as UID and GID `10001`. For a new, empty deployment, initialize the bind-mounted directory with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /srv/docker/mssql/data
|
||||||
|
sudo chown -R 10001:10001 /srv/docker/mssql/data
|
||||||
|
sudo chmod -R 700 /srv/docker/mssql/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not delete or recreate the directory after databases exist. Removing `/srv/docker/mssql/data` destroys the persisted SQL Server data.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Variable Is Not Set
|
||||||
|
|
||||||
|
If Compose reports that `MSSQL_SA_PASSWORD` is unset and defaults to a blank string, use the required `docker compose --env-file /srv/secrets/company.env up -d` command.
|
||||||
|
|
||||||
|
### System Directory Permission Denied
|
||||||
|
|
||||||
|
If `[/.system]` cannot be created, verify that `/srv/docker/mssql/data` is owned by `10001:10001` with mode `700`.
|
||||||
|
|
||||||
|
### Password Validation Failed
|
||||||
|
|
||||||
|
Confirm that the password meets SQL Server complexity requirements and that Compose resolved `MSSQL_SA_PASSWORD` from the secrets file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/services.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/backups.md
|
||||||
|
* dbgate/README.md
|
||||||
|
* postgres/README.md
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
services:
|
||||||
|
mssql:
|
||||||
|
image: mcr.microsoft.com/mssql/server:2022-latest
|
||||||
|
container_name: mssql
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- /srv/secrets/company.env
|
||||||
|
environment:
|
||||||
|
ACCEPT_EULA: Y
|
||||||
|
MSSQL_PID: Express
|
||||||
|
MSSQL_SA_PASSWORD: ${MSSQL_SA_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/mssql/data:/var/opt/mssql
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
# Nginx Proxy Manager
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Nginx Proxy Manager (NPM) is the public entry point for all internet-facing services hosted on SilverLinux.
|
||||||
|
|
||||||
|
It provides:
|
||||||
|
|
||||||
|
* Reverse proxy routing
|
||||||
|
* SSL certificate management
|
||||||
|
* HTTPS termination
|
||||||
|
* Domain forwarding
|
||||||
|
* Centralized access to services
|
||||||
|
|
||||||
|
All public services should be exposed through Nginx Proxy Manager instead of directly exposing application ports.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
Container Name:
|
||||||
|
|
||||||
|
```text
|
||||||
|
nginx-proxy-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
Image:
|
||||||
|
|
||||||
|
```text
|
||||||
|
jc21/nginx-proxy-manager:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Docker Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ports
|
||||||
|
|
||||||
|
| Port | Purpose |
|
||||||
|
| ---- | ---------------------------------- |
|
||||||
|
| 80 | HTTP |
|
||||||
|
| 81 | Nginx Proxy Manager Administration |
|
||||||
|
| 443 | HTTPS |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Storage
|
||||||
|
|
||||||
|
### Application Data
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/data
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Proxy host configuration
|
||||||
|
* Access lists
|
||||||
|
* Users
|
||||||
|
* Application settings
|
||||||
|
* SSL metadata
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SSL Certificates
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/letsencrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Let's Encrypt certificates
|
||||||
|
* Private keys
|
||||||
|
* Renewal information
|
||||||
|
|
||||||
|
This folder is critical for disaster recovery.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Responsibilities
|
||||||
|
|
||||||
|
Nginx Proxy Manager is responsible for:
|
||||||
|
|
||||||
|
### Reverse Proxy
|
||||||
|
|
||||||
|
Routing incoming requests to Docker containers.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
| Domain | Target Service |
|
||||||
|
| --------------------------- | -------------- |
|
||||||
|
| git.silveressence.net | Gitea |
|
||||||
|
| team.silveressence.net | OpenProject |
|
||||||
|
| meet.silveressence.net | Jitsi |
|
||||||
|
| portainer.silveressence.net | Portainer |
|
||||||
|
| nuget.silveressence.net | BaGet |
|
||||||
|
| dbgate.silveressence.net | DbGate |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SSL Certificates
|
||||||
|
|
||||||
|
Provides:
|
||||||
|
|
||||||
|
* HTTPS encryption
|
||||||
|
* Certificate renewal
|
||||||
|
* Certificate management
|
||||||
|
|
||||||
|
All public services should use HTTPS.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Domain Management
|
||||||
|
|
||||||
|
Centralized management for:
|
||||||
|
|
||||||
|
* Domains
|
||||||
|
* Subdomains
|
||||||
|
* SSL certificates
|
||||||
|
* Proxy routing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Configuration
|
||||||
|
|
||||||
|
Volumes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/data:/data
|
||||||
|
/srv/docker/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Applications exposed through NPM must be connected to the proxy network.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Administration
|
||||||
|
|
||||||
|
Web Interface:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://portainer.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Nginx Proxy Manager Admin:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://SERVER-IP:81
|
||||||
|
```
|
||||||
|
|
||||||
|
or through the configured domain if one exists.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Requirements
|
||||||
|
|
||||||
|
The following directories must be backed up:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/nginx-proxy-manager/data
|
||||||
|
/srv/docker/nginx-proxy-manager/letsencrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
Without these directories:
|
||||||
|
|
||||||
|
* SSL certificates are lost
|
||||||
|
* Proxy configurations are lost
|
||||||
|
* Domain mappings must be recreated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
* Only ports 80 and 443 should be exposed publicly.
|
||||||
|
* Administrative access should be restricted.
|
||||||
|
* SSL certificates should be renewed automatically.
|
||||||
|
* Services should never be exposed directly to the internet when NPM can proxy them.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Services
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
* Portainer
|
||||||
|
* BaGet
|
||||||
|
* DbGate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/domains.md
|
||||||
|
* docs/backups.md
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
services:
|
||||||
|
nginx-proxy-manager:
|
||||||
|
image: jc21/nginx-proxy-manager:latest
|
||||||
|
container_name: nginx-proxy-manager
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "81:81"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/nginx-proxy-manager/data:/data
|
||||||
|
- /srv/docker/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
services:
|
||||||
|
openproject:
|
||||||
|
image: openproject/openproject:17
|
||||||
|
container_name: openproject
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
env_file:
|
||||||
|
- /srv/secrets/company.env
|
||||||
|
|
||||||
|
environment:
|
||||||
|
SECRET_KEY_BASE: ${OPENPROJECT_SECRET_KEY_BASE}
|
||||||
|
OPENPROJECT_HOST__NAME: team.silveressence.net
|
||||||
|
OPENPROJECT_HTTPS: "true"
|
||||||
|
|
||||||
|
DATABASE_URL: postgres://openproject:${POSTGRES_OPENPROJECT_PASSWORD}@postgres:5432/openproject
|
||||||
|
|
||||||
|
OPENPROJECT_EMAIL__DELIVERY__METHOD: smtp
|
||||||
|
OPENPROJECT_SMTP__ADDRESS: ${SMTP_HOST}
|
||||||
|
OPENPROJECT_SMTP__PORT: "${SMTP_PORT}"
|
||||||
|
OPENPROJECT_SMTP__DOMAIN: silveressence.net
|
||||||
|
OPENPROJECT_SMTP__AUTHENTICATION: login
|
||||||
|
OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO: "true"
|
||||||
|
OPENPROJECT_SMTP__USER__NAME: ${SMTP_USERNAME}
|
||||||
|
OPENPROJECT_SMTP__PASSWORD: ${SMTP_PASSWORD}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/openproject/assets:/var/openproject/assets
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
# OpenProject
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
OpenProject is the project management and collaboration platform used by Silver Solutions.
|
||||||
|
|
||||||
|
It provides:
|
||||||
|
|
||||||
|
* Project management
|
||||||
|
* Task tracking
|
||||||
|
* Work packages
|
||||||
|
* Time tracking
|
||||||
|
* Roadmaps
|
||||||
|
* Team collaboration
|
||||||
|
* Document management
|
||||||
|
|
||||||
|
OpenProject replaces the previously planned Plane.so deployment.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
### URL
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://team.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Name
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject/openproject:17
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Network
|
||||||
|
|
||||||
|
```text
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
OpenProject is used for:
|
||||||
|
|
||||||
|
* Project planning
|
||||||
|
* Task management
|
||||||
|
* Development tracking
|
||||||
|
* Internal collaboration
|
||||||
|
* Customer project management
|
||||||
|
* Team planning
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
Database:
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
Database User:
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
Database Host:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Database access is provided through the internal Docker network.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Email Configuration
|
||||||
|
|
||||||
|
Sender Address:
|
||||||
|
|
||||||
|
```text
|
||||||
|
noreply@silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Password reset emails
|
||||||
|
* User notifications
|
||||||
|
* Work package notifications
|
||||||
|
* Mention notifications
|
||||||
|
* Project updates
|
||||||
|
|
||||||
|
SMTP credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Storage
|
||||||
|
|
||||||
|
Assets Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/openproject/assets
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains:
|
||||||
|
|
||||||
|
* Attachments
|
||||||
|
* Uploaded files
|
||||||
|
* Application assets
|
||||||
|
* User generated content
|
||||||
|
|
||||||
|
This directory must be included in backups.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
The following values are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POSTGRES_OPENPROJECT_PASSWORD
|
||||||
|
OPENPROJECT_SECRET_KEY_BASE
|
||||||
|
|
||||||
|
SMTP_HOST
|
||||||
|
SMTP_PORT
|
||||||
|
SMTP_USERNAME
|
||||||
|
SMTP_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Secrets must never be committed to Git.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Current Authentication:
|
||||||
|
|
||||||
|
* Local accounts
|
||||||
|
|
||||||
|
Future Considerations:
|
||||||
|
|
||||||
|
* Google OAuth2
|
||||||
|
* GitHub OAuth2
|
||||||
|
* Microsoft Entra ID
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Configuration
|
||||||
|
|
||||||
|
Volume Mapping:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/openproject/assets:/var/openproject/assets
|
||||||
|
```
|
||||||
|
|
||||||
|
Port Mapping:
|
||||||
|
|
||||||
|
```text
|
||||||
|
8082:80
|
||||||
|
```
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
OpenProject should not be exposed directly to the internet.
|
||||||
|
|
||||||
|
Access should be routed through Nginx Proxy Manager.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Administration
|
||||||
|
|
||||||
|
View Logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker restart openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
Open Shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it openproject bash
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Requirements
|
||||||
|
|
||||||
|
The following items must be backed up:
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
### Assets
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/docker/openproject/assets
|
||||||
|
```
|
||||||
|
|
||||||
|
### Secrets
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Without these items, a complete restoration is not possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recovery Checklist
|
||||||
|
|
||||||
|
To restore OpenProject:
|
||||||
|
|
||||||
|
1. Restore PostgreSQL database.
|
||||||
|
2. Restore OpenProject assets directory.
|
||||||
|
3. Restore company.env secrets.
|
||||||
|
4. Deploy Docker Compose stack.
|
||||||
|
5. Verify SMTP configuration.
|
||||||
|
6. Verify access through Nginx Proxy Manager.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Services
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* Gitea
|
||||||
|
* Portainer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/backups.md
|
||||||
|
* postgres/README.md
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
services:
|
||||||
|
openproject:
|
||||||
|
image: openproject/openproject:17
|
||||||
|
container_name: openproject
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
env_file:
|
||||||
|
- /srv/secrets/company.env
|
||||||
|
|
||||||
|
environment:
|
||||||
|
SECRET_KEY_BASE: ${OPENPROJECT_SECRET_KEY_BASE}
|
||||||
|
OPENPROJECT_HOST__NAME: team.silveressence.net
|
||||||
|
OPENPROJECT_HTTPS: "true"
|
||||||
|
|
||||||
|
DATABASE_URL: postgres://openproject:${POSTGRES_OPENPROJECT_PASSWORD}@postgres:5432/openproject
|
||||||
|
|
||||||
|
OPENPROJECT_EMAIL__DELIVERY__METHOD: smtp
|
||||||
|
OPENPROJECT_SMTP__ADDRESS: ${SMTP_HOST}
|
||||||
|
OPENPROJECT_SMTP__PORT: "${SMTP_PORT}"
|
||||||
|
OPENPROJECT_SMTP__DOMAIN: silveressence.net
|
||||||
|
OPENPROJECT_SMTP__AUTHENTICATION: login
|
||||||
|
OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO: "true"
|
||||||
|
OPENPROJECT_SMTP__USER__NAME: ${SMTP_USERNAME}
|
||||||
|
OPENPROJECT_SMTP__PASSWORD: ${SMTP_PASSWORD}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/openproject/assets:/var/openproject/assets
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
# Portainer
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Portainer provides a web-based management interface for Docker on SilverLinux.
|
||||||
|
|
||||||
|
It is used to manage containers, networks, volumes, images and Docker stacks through a graphical interface instead of using the command line.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
### URL
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://portainer.silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Name
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer/portainer-ce:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Network
|
||||||
|
|
||||||
|
```text
|
||||||
|
proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Portainer is used for:
|
||||||
|
|
||||||
|
* Managing Docker containers
|
||||||
|
* Managing Docker networks
|
||||||
|
* Managing Docker volumes
|
||||||
|
* Viewing logs
|
||||||
|
* Deploying Docker stacks
|
||||||
|
* Monitoring running services
|
||||||
|
* Performing container maintenance
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Storage
|
||||||
|
|
||||||
|
### Docker Socket
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/run/docker.sock
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows Portainer to communicate with the Docker engine.
|
||||||
|
|
||||||
|
### Portainer Data
|
||||||
|
|
||||||
|
Docker Volume:
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer_portainer_data
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* User accounts
|
||||||
|
* Configuration
|
||||||
|
* Stack definitions
|
||||||
|
* Environment settings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Portainer has administrative access to Docker.
|
||||||
|
|
||||||
|
Because Portainer uses the Docker socket, users with Portainer administrator access effectively have administrative access to the server.
|
||||||
|
|
||||||
|
Only trusted administrators should have access.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Requirements
|
||||||
|
|
||||||
|
The following volume should be included in backups:
|
||||||
|
|
||||||
|
```text
|
||||||
|
portainer_portainer_data
|
||||||
|
```
|
||||||
|
|
||||||
|
Loss of this volume will result in:
|
||||||
|
|
||||||
|
* Loss of Portainer users
|
||||||
|
* Loss of stack definitions
|
||||||
|
* Loss of Portainer configuration
|
||||||
|
|
||||||
|
Docker containers and application data remain unaffected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Network Configuration
|
||||||
|
|
||||||
|
Portainer is connected to the Docker proxy network.
|
||||||
|
|
||||||
|
Applications exposed through Nginx Proxy Manager can communicate with Portainer through this network.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
View logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs portainer
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker restart portainer
|
||||||
|
```
|
||||||
|
|
||||||
|
Open shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it portainer /bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Services
|
||||||
|
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* Docker
|
||||||
|
* PostgreSQL
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/backups.md
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
services:
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer-ce:latest
|
||||||
|
container_name: portainer
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- portainer_data:/data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
portainer_data:
|
||||||
|
name: portainer_portainer_data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
env_file:
|
||||||
|
- /srv/secrets/company.env
|
||||||
|
|
||||||
|
environment:
|
||||||
|
USER_UID: "1000"
|
||||||
|
USER_GID: "1000"
|
||||||
|
|
||||||
|
GITEA__database__DB_TYPE: postgres
|
||||||
|
GITEA__database__HOST: postgres:5432
|
||||||
|
GITEA__database__NAME: gitea
|
||||||
|
GITEA__database__USER: postgres
|
||||||
|
GITEA__database__PASSWD: ${POSTGRES_ROOT_PASSWORD}
|
||||||
|
|
||||||
|
GITEA__server__DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__ROOT_URL: https://git.silveressence.net/
|
||||||
|
GITEA__server__SSH_DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__SSH_PORT: "2222"
|
||||||
|
|
||||||
|
GITEA__mailer__ENABLED: "true"
|
||||||
|
GITEA__mailer__FROM: noreply@silveressence.net
|
||||||
|
GITEA__mailer__PROTOCOL: smtp+starttls
|
||||||
|
GITEA__mailer__SMTP_ADDR: ${SMTP_HOST}
|
||||||
|
GITEA__mailer__SMTP_PORT: "${SMTP_PORT}"
|
||||||
|
GITEA__mailer__USER: ${SMTP_USERNAME}
|
||||||
|
GITEA__mailer__PASSWD: ${SMTP_PASSWORD}
|
||||||
|
|
||||||
|
GITEA__openid__ENABLE_OPENID_SIGNIN: "false"
|
||||||
|
GITEA__openid__ENABLE_OPENID_SIGNUP: "false"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/gitea/data:/data
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "2222:22"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
# PostgreSQL
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
PostgreSQL is the primary open-source database platform for SilverLinux and coexists with Microsoft SQL Server 2022 Express.
|
||||||
|
|
||||||
|
Multiple applications use the same PostgreSQL instance while maintaining separate databases and database users.
|
||||||
|
|
||||||
|
This approach simplifies:
|
||||||
|
|
||||||
|
* Backup management
|
||||||
|
* Monitoring
|
||||||
|
* Security
|
||||||
|
* Resource utilization
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Information
|
||||||
|
|
||||||
|
Container Name:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Application databases
|
||||||
|
* Centralized data storage
|
||||||
|
* Shared database platform
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current Databases
|
||||||
|
|
||||||
|
### gitea
|
||||||
|
|
||||||
|
Owner:
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Source control and repository management.
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
```text
|
||||||
|
gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### openproject
|
||||||
|
|
||||||
|
Owner:
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Project management and collaboration.
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
```text
|
||||||
|
openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### postgres
|
||||||
|
|
||||||
|
Owner:
|
||||||
|
|
||||||
|
```text
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Administrative database.
|
||||||
|
|
||||||
|
Used for PostgreSQL administration and maintenance.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Ownership
|
||||||
|
|
||||||
|
| Database | Owner |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| gitea | gitea |
|
||||||
|
| openproject | openproject |
|
||||||
|
| postgres | postgres |
|
||||||
|
|
||||||
|
Each application should use its own dedicated database user whenever possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Credentials
|
||||||
|
|
||||||
|
Credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Current variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POSTGRES_ROOT_PASSWORD
|
||||||
|
POSTGRES_OPENPROJECT_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Future variables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POSTGRES_GITEA_PASSWORD
|
||||||
|
POSTGRES_BAGET_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Passwords must never be committed to Git repositories.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Administration
|
||||||
|
|
||||||
|
Open PostgreSQL shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it postgres psql -U postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### List Databases
|
||||||
|
|
||||||
|
```sql
|
||||||
|
\l
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### List Roles
|
||||||
|
|
||||||
|
```sql
|
||||||
|
\du
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### List Connections
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM pg_stat_activity;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Create Database
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE DATABASE myapp;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Create User
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE USER myapp WITH PASSWORD 'StrongPassword';
|
||||||
|
```
|
||||||
|
|
||||||
|
Grant permissions:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE myapp TO myapp;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup
|
||||||
|
|
||||||
|
Create database backup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec postgres pg_dump -U postgres openproject > openproject.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Create full cluster backup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec postgres pg_dumpall -U postgres > postgres-full-backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Restore
|
||||||
|
|
||||||
|
Restore database:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -i postgres psql -U postgres openproject < openproject.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Restore complete cluster:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -i postgres psql -U postgres < postgres-full-backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
* PostgreSQL is not exposed publicly.
|
||||||
|
* Database traffic is restricted to Docker internal networks.
|
||||||
|
* Credentials are stored in `/srv/secrets/company.env`.
|
||||||
|
* Administrative access should use the `postgres` role only when necessary.
|
||||||
|
* Applications should use dedicated database users.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
Useful commands:
|
||||||
|
|
||||||
|
Database size:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT pg_database.datname,
|
||||||
|
pg_size_pretty(pg_database_size(pg_database.datname))
|
||||||
|
FROM pg_database;
|
||||||
|
```
|
||||||
|
|
||||||
|
Current connections:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT count(*) FROM pg_stat_activity;
|
||||||
|
```
|
||||||
|
|
||||||
|
PostgreSQL version:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT version();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Disaster Recovery
|
||||||
|
|
||||||
|
Minimum requirements for recovery:
|
||||||
|
|
||||||
|
* PostgreSQL container configuration
|
||||||
|
* Database backups
|
||||||
|
* `/srv/secrets/company.env`
|
||||||
|
* Docker network configuration
|
||||||
|
|
||||||
|
Without the secrets file, applications may not be able to reconnect to their databases after restoration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Services
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* DbGate
|
||||||
|
* Microsoft SQL Server Express
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
* docs/backups.md
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
env_file:
|
||||||
|
- /srv/secrets/company.env
|
||||||
|
|
||||||
|
environment:
|
||||||
|
USER_UID: "1000"
|
||||||
|
USER_GID: "1000"
|
||||||
|
|
||||||
|
GITEA__database__DB_TYPE: postgres
|
||||||
|
GITEA__database__HOST: postgres:5432
|
||||||
|
GITEA__database__NAME: gitea
|
||||||
|
GITEA__database__USER: postgres
|
||||||
|
GITEA__database__PASSWD: ${POSTGRES_ROOT_PASSWORD}
|
||||||
|
|
||||||
|
GITEA__server__DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__ROOT_URL: https://git.silveressence.net/
|
||||||
|
GITEA__server__SSH_DOMAIN: git.silveressence.net
|
||||||
|
GITEA__server__SSH_PORT: "2222"
|
||||||
|
|
||||||
|
GITEA__mailer__ENABLED: "true"
|
||||||
|
GITEA__mailer__FROM: noreply@silveressence.net
|
||||||
|
GITEA__mailer__PROTOCOL: smtp+starttls
|
||||||
|
GITEA__mailer__SMTP_ADDR: ${SMTP_HOST}
|
||||||
|
GITEA__mailer__SMTP_PORT: "${SMTP_PORT}"
|
||||||
|
GITEA__mailer__USER: ${SMTP_USERNAME}
|
||||||
|
GITEA__mailer__PASSWD: ${SMTP_PASSWORD}
|
||||||
|
|
||||||
|
GITEA__openid__ENABLE_OPENID_SIGNIN: "false"
|
||||||
|
GITEA__openid__ENABLE_OPENID_SIGNUP: "false"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /srv/docker/gitea/data:/data
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "2222:22"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
|
external: true
|
||||||
Reference in New Issue
Block a user