Files
silverlinux-infra/docs/network.md
T

401 lines
9.3 KiB
Markdown

# Network Architecture
## Overview
SilverLinux uses Docker networks to separate public entry points, private service communication and isolated infrastructure stacks.
Current model:
* `internal` for private databases and backend service traffic
* `proxy` for HTTP and HTTPS services routed by Nginx Proxy Manager
* Isolated stack networks for specialized infrastructure such as Jitsi, Xray, monitoring, Sentry and CI/CD runners
Verified runtime snapshot:
```text
2026-06-24 10:15 CEST, with Nextcloud and Sentry evidence added from 2026-07-08 server output
```
---
## Network Layers
### Internal Layer
Purpose:
* Private database access
* Backend-to-database communication
* Service traffic that should not be reachable from the internet
Network:
```text
internal
```
Services:
* PostgreSQL
* Microsoft SQL Server Express
* Gitea backend connectivity
* OpenProject backend connectivity
* DbGate database connectivity
Policy:
* Database ports must not be published on the host
* Database engines must not be routed through Nginx Proxy Manager
* Only containers that require private backend access should join this network
---
### Proxy Layer
Purpose:
* Public HTTP and HTTPS entry point
* SSL termination
* Domain routing through Nginx Proxy Manager
Network:
```text
proxy
```
Public services:
* Gitea
* OpenProject
* Portainer
* DbGate
* Xray
* Jitsi Web
* BaGet
* Nextcloud
* Sentry
Internal monitoring services:
* Prometheus
* Grafana
* Node Exporter
* cAdvisor
* Alertmanager
Verified subnet:
```text
172.18.0.0/16
```
Policy:
* Nginx Proxy Manager is the single reverse proxy system
* HTTP services should be exposed through Nginx Proxy Manager instead of direct host ports
* Public management and administration services require strong authentication
---
### Isolated Infrastructure Layers
Purpose:
* Keep specialized stacks separate from the shared application and database networks
* Limit cross-service traffic to only the attachments each stack requires
Networks:
```text
jitsi-docker-jitsi-meet-aa76415_meet.jitsi
xray_default
gitea-runner_default
monitoring stack network
sentry-self-hosted_default
```
#### jitsi-docker-jitsi-meet-aa76415_meet.jitsi
Purpose:
* Isolated Jitsi communication cluster
Services:
* jitsi-web
* jitsi-jvb
* jitsi-jicofo
* jitsi-prosody
Public attachment:
* All currently running Jitsi containers also attach to `proxy`.
* Public user access is expected through the Jitsi Web component.
Verified subnet:
```text
172.20.0.0/16
```
#### xray_default
Purpose:
* Isolated tunneling and connectivity system
* Compose-created network for the Xray stack
Services:
* No running containers were attached in the 2026-06-24 runtime snapshot
Public attachment:
* The running `xray` container is attached to `proxy`.
* The running `xray` container was not attached to `xray_default` in the 2026-06-24 runtime snapshot.
Verified subnet:
```text
172.22.0.0/16
```
#### Gluetun PIA VPN Gateway
Purpose:
* Containerized VPN gateway for Private Internet Access (PIA)
* Isolate VPN traffic from host networking and production services
Services:
* `gluetun-pia`
* `xray-pia` (via `container:gluetun-pia` network mode)
Notes:
* `gluetun-pia` routes selected container traffic through PIA WireGuard
* `xray-pia` is a secondary VLESS endpoint that uses the Gluetun VPN gateway
* Production `xray` remains isolated on the direct OVH path
Verified isolation:
* VPN traffic is contained inside the `gluetun-pia` container namespace
* Host routing remains unchanged by VPN activity
#### gitea-runner_default
Purpose:
* Runner execution and workflow isolation
* Keep build traffic separate from public services and private databases unless explicit access is required
Runtime attachment:
* `gitea-runner` is attached to both `gitea-runner_default` and `internal`.
Verified subnet:
```text
172.21.0.0/16
```
#### Monitoring Stack Network
Purpose:
* Dedicated monitoring stack communication
* Prometheus scraping of monitoring targets
* Grafana datasource connectivity to Prometheus
Services:
* Prometheus
* Grafana
* Node Exporter
* cAdvisor
* Alertmanager
Validated:
* Prometheus scrapes Prometheus
* Prometheus scrapes Node Exporter
* Prometheus scrapes cAdvisor
* Prometheus scrapes SilverLinux backup metrics
* Grafana connects to Prometheus
* Alertmanager routes monitoring alerts
#### nextcloud_nextcloud_internal
Purpose:
* Private Nextcloud application, database and cache traffic
* Keep Nextcloud PostgreSQL and Redis away from the public proxy layer
Services:
* `nextcloud`
* `nextcloud-db`
* `nextcloud-redis`
Public attachment:
* Only the `nextcloud` web container also attaches to `proxy`.
* `nextcloud-db` and `nextcloud-redis` are internal-only.
Verified subnet:
```text
172.27.0.0/16
```
#### sentry-self-hosted_default
Purpose:
* Internal Sentry event processing, storage and worker communication
* Keep Sentry backing services isolated from shared application networks
Services:
* Sentry web, relay, worker, cron and consumer services
* Kafka
* Snuba
* ClickHouse
* PostgreSQL
* Redis
* SeaweedFS
Public attachment:
* Public access is through Nginx Proxy Manager at `sentry.silveressence.net`.
* The public entry container is `sentry-self-hosted-nginx-1`.
* Sentry databases, queues and workers must remain internal to the Sentry deployment.
Verified subnet:
```text
172.25.0.0/16
```
---
## Runtime-Published Ports
The current Docker runtime includes these host-published ports.
| Service | Published port | Container port | UFW state | Notes |
| --- | --- | --- | --- | --- |
| Nginx Proxy Manager | `80`, `81`, `443` | `80`, `81`, `443` | `80` and `443` allowed; `81` not listed | Public proxy and NPM admin interface |
| Gitea | `2222` | `22` | Allowed | Git SSH access |
| OpenProject | `8082` | `80` | Not listed as allowed | Direct HTTP port also published |
| BaGet | `5555` | `80` | Not listed as allowed | Direct HTTP port also published |
| Jitsi Web | `8000`, `8443` | `80`, `443` | `8443` allowed; `8000` not listed | Direct HTTP and HTTPS ports also published |
| Jitsi JVB | `10000/udp` | `10000/udp` | Allowed | Required media bridge traffic |
| Xray | `32443` | `8080` | Allowed | Public tunneling endpoint |
| Sentry nginx | `9000` | `80` | Not listed as allowed | Nginx Proxy Manager forwards to `sentry-self-hosted-nginx-1:80`; direct host port should be reviewed |
Nextcloud runtime exposure from the 2026-07-08 snapshot:
* `nextcloud` exposes `80/tcp` only inside Docker and is routed through Nginx Proxy Manager.
* `nextcloud-db` exposes `5432/tcp` only inside Docker.
* `nextcloud-redis` exposes `6379/tcp` only inside Docker.
* No host-published ports were shown for the Nextcloud stack.
Additional UFW allowed ports with no matching Docker-published service in the 2026-06-24 Docker snapshot:
* `8080/tcp`
* `8085/tcp`
* `8444/tcp`
Database ports:
* PostgreSQL exposes `5432/tcp` only inside Docker.
* MSSQL exposes `1433/tcp` only inside Docker.
* DbGate exposes `3000/tcp` only inside Docker.
Sentry runtime exposure:
* `sentry.silveressence.net` is routed through Nginx Proxy Manager to `sentry-self-hosted-nginx-1:80`.
* `sentry-self-hosted-nginx-1` publishes `0.0.0.0:9000 -> 80/tcp`.
* Sentry backing services should not publish host ports.
---
## Topology Summary
```text
Internet
-> Nginx Proxy Manager
-> proxy network
-> Gitea
-> OpenProject
-> Portainer
-> DbGate
-> Xray
-> Jitsi Web
-> BaGet
-> Nextcloud
-> Sentry
internal network
-> PostgreSQL
-> Microsoft SQL Server Express
-> backend service database access
isolated networks
-> jitsi-docker-jitsi-meet-aa76415_meet.jitsi
-> xray_default
-> gitea-runner_default
-> monitoring stack network
-> nextcloud_nextcloud_internal
-> sentry-self-hosted_default
```
---
## Default Docker Networks
Docker default networks remain present:
* `bridge`
* `host`
* `none`
These are system defaults and are not the preferred routing model for SilverLinux application services.
---
## Verification Checklist
Periodically verify:
* PostgreSQL and MSSQL are attached only to private networks required by their consumers
* Nginx Proxy Manager remains the only reverse proxy for HTTP services
* Nginx Proxy Manager routes match the documented proxy-host table in `docs/domains.md`
* DbGate authentication is enabled and tested
* DbGate and Portainer have an access restriction policy
* Xray exposure policy is documented and monitored
* Jitsi Web is reachable through `proxy`
* Jitsi internal components remain attached to `jitsi-docker-jitsi-meet-aa76415_meet.jitsi`
* The desired Xray attachment is reconciled with the fact that `xray_default` currently has no running containers
* Direct host-published ports are intentional and protected by firewall policy
* Sentry host-published port `9000` has a documented owner and firewall policy
* UFW-only allowed ports have documented owners
* Prometheus targets remain healthy
* Grafana datasource connection remains healthy
* Nextcloud remains routed through Nginx Proxy Manager without host-published database or Redis ports
* Sentry remains routed through Nginx Proxy Manager with internal backing services isolated
* Unused Docker networks are removed only after confirming they are not active dependencies
---
## Related Documentation
* docs/services.md
* docs/security.md
* docs/monitoring.md
* docs/decisions.md
* nginx-proxy-manager/README.md