Compare commits
7 Commits
master
...
db42baa33e
| Author | SHA1 | Date | |
|---|---|---|---|
| db42baa33e | |||
| 4c2da84795 | |||
| ab461a5c08 | |||
| a8e23d3036 | |||
| b43f2b790e | |||
| efbdfb241c | |||
| 02a7ac7971 |
@@ -1,16 +1,135 @@
|
|||||||
# 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
|
||||||
|
|
||||||
|
### Planned
|
||||||
|
|
||||||
|
* Sentry
|
||||||
|
* Nextcloud
|
||||||
|
|
||||||
|
### 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
|
||||||
|
* 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/backups.md
|
||||||
|
* docs/security.md
|
||||||
|
* docs/secrets.md
|
||||||
|
|||||||
+259
@@ -0,0 +1,259 @@
|
|||||||
|
# SilverLinux Infrastructure Summary
|
||||||
|
|
||||||
|
Last Updated: 2026-06-22
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Infrastructure
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Container hosting
|
||||||
|
* Service isolation
|
||||||
|
|
||||||
|
### Internal Network
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Private communication between services
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### Centralized Secrets
|
||||||
|
|
||||||
|
All shared credentials are stored in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Roadmap
|
||||||
|
|
||||||
|
### Phase 1
|
||||||
|
|
||||||
|
* Enable Google OAuth2
|
||||||
|
* Enable GitHub OAuth2
|
||||||
|
* Configure automated backups
|
||||||
|
|
||||||
|
### Phase 2
|
||||||
|
|
||||||
|
* Expand package publishing to additional repositories
|
||||||
|
|
||||||
|
### Phase 3
|
||||||
|
|
||||||
|
* Deploy Sentry
|
||||||
|
|
||||||
|
### Phase 4
|
||||||
|
|
||||||
|
* Automated deployment to Windows IIS servers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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,112 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
Secrets are stored in:
|
||||||
|
|
||||||
|
/srv/secrets/company.env
|
||||||
|
|
||||||
|
Never hardcode credentials.
|
||||||
|
|
||||||
|
Always use env_file.
|
||||||
|
|
||||||
|
## Docker Networks
|
||||||
|
|
||||||
|
proxy
|
||||||
|
internal
|
||||||
|
|
||||||
|
MSSQL is attached only to `internal`. DbGate is attached to both `internal` and `proxy`.
|
||||||
|
|
||||||
|
## 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`.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Read all files in:
|
||||||
|
|
||||||
|
docs/
|
||||||
|
|
||||||
|
and the README.md of each service folder before making infrastructure recommendations.
|
||||||
|
|
||||||
|
## 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
|
||||||
+365
@@ -0,0 +1,365 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
Importance:
|
||||||
|
|
||||||
|
Critical
|
||||||
|
|
||||||
|
Do not rely on copying live database files as the only backup method.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup Storage
|
||||||
|
|
||||||
|
Current Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/backups
|
||||||
|
```
|
||||||
|
|
||||||
|
Suggested Structure:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/backups/
|
||||||
|
├── daily
|
||||||
|
├── weekly
|
||||||
|
└── monthly
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Retention Policy
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
* postgres/README.md
|
||||||
|
* gitea/README.md
|
||||||
|
* openproject/README.md
|
||||||
|
* mssql/README.md
|
||||||
|
* dbgate/README.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,337 @@
|
|||||||
|
# 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
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Decisions
|
||||||
|
|
||||||
|
Document future decisions using the following template:
|
||||||
|
|
||||||
|
Date:
|
||||||
|
|
||||||
|
Decision:
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
Alternatives Considered:
|
||||||
|
|
||||||
|
Status:
|
||||||
+246
@@ -0,0 +1,246 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Primary Domain
|
||||||
|
|
||||||
|
```text
|
||||||
|
silveressence.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Used for:
|
||||||
|
|
||||||
|
* Public services
|
||||||
|
* Subdomains
|
||||||
|
* SSL certificates
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Active Domains
|
||||||
|
|
||||||
|
### 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
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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
|
||||||
|
* nginx-proxy-manager/README.md
|
||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
# Email Configuration
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
SilverLinux uses a centralized SMTP configuration for application email delivery.
|
||||||
|
|
||||||
|
Email is used for:
|
||||||
|
|
||||||
|
* Password resets
|
||||||
|
* User invitations
|
||||||
|
* Notifications
|
||||||
|
* System alerts
|
||||||
|
* 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Applications
|
||||||
|
|
||||||
|
Future services should use the centralized SMTP configuration whenever possible.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* BaGet
|
||||||
|
* CI/CD notifications
|
||||||
|
* Monitoring systems
|
||||||
|
* 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
* openproject/README.md
|
||||||
|
* gitea/README.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,265 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
Allowed ports:
|
||||||
|
|
||||||
|
| Port | Purpose |
|
||||||
|
| ---- | ------- |
|
||||||
|
| 22 | SSH |
|
||||||
|
| 80 | HTTP |
|
||||||
|
| 443 | HTTPS |
|
||||||
|
|
||||||
|
All other ports should remain blocked unless explicitly required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Intrusion Protection
|
||||||
|
|
||||||
|
### Fail2Ban
|
||||||
|
|
||||||
|
Fail2Ban is enabled.
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Detect brute-force attacks
|
||||||
|
* Automatically block malicious IP addresses
|
||||||
|
* Protect SSH access
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
* Store client secrets in company.env
|
||||||
|
* Use least-privilege scopes
|
||||||
|
* Disable unused authentication providers
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
* UFW is active
|
||||||
|
* SSL certificates are valid
|
||||||
|
* Secrets are not stored in repositories
|
||||||
|
* Backups are functioning
|
||||||
|
* Administrator accounts have 2FA enabled
|
||||||
|
* 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
|
||||||
|
* nginx-proxy-manager/README.md
|
||||||
+332
@@ -0,0 +1,332 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running Services
|
||||||
|
|
||||||
|
* PostgreSQL
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
* Jitsi Meet
|
||||||
|
* Portainer
|
||||||
|
* Nginx Proxy Manager
|
||||||
|
* BaGet
|
||||||
|
* Gitea Actions Runner
|
||||||
|
* Microsoft SQL Server 2022 Express
|
||||||
|
* DbGate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
* 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/domains.md
|
||||||
@@ -0,0 +1,343 @@
|
|||||||
|
# Services
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document lists all services running on SilverLinux and their purpose.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running Services
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Shared database platform
|
||||||
|
* Application data storage
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
* Gitea
|
||||||
|
* OpenProject
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Running
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Microsoft SQL Server Express
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* Support applications requiring Microsoft SQL Server
|
||||||
|
* Run alongside PostgreSQL as a private database platform
|
||||||
|
|
||||||
|
Image:
|
||||||
|
|
||||||
|
```text
|
||||||
|
mcr.microsoft.com/mssql/server:2022-latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
internal
|
||||||
|
```
|
||||||
|
|
||||||
|
Exposure:
|
||||||
|
|
||||||
|
* Port 1433 is not published
|
||||||
|
* Not routed through Nginx Proxy Manager
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Operational
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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 MSSQL administration
|
||||||
|
* Browser-based PostgreSQL administration
|
||||||
|
|
||||||
|
Networks:
|
||||||
|
|
||||||
|
* `internal` for private database connectivity
|
||||||
|
* `proxy` for Nginx Proxy Manager
|
||||||
|
|
||||||
|
Security:
|
||||||
|
|
||||||
|
* HTTPS enforced
|
||||||
|
* DbGate username and password required
|
||||||
|
* Database ports remain private
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Shared Secrets
|
||||||
|
|
||||||
|
Location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/srv/secrets/company.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
* SMTP credentials
|
||||||
|
* Database passwords
|
||||||
|
* Application secrets
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Active
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Removed Services
|
||||||
|
|
||||||
|
### Plane.so
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
OpenProject was selected as the primary project management platform.
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Removed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* docs/server.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