v2.11.0 dca6537

network-groups.md RawHistoryFolder

Network Groups

Group multiple applications into shared networks for inter-service communication.

Configuration

[network_groups]
"backend" = ["app.mydomain.com", "api.mydomain.com"]
"monitoring" = ["grafana.mydomain.com", "prometheus.mydomain.com"]

Syntax

[network_groups]
"<group-name>" = ["<domain>", "<domain>", ...]
Component Description
group-name Name for the shared network
domains List of routes that share this network

How It Works

Network groups create shared Docker networks for multiple applications:

[network_groups]
"backend" = ["app.mydomain.com", "api.mydomain.com"]

Creates a shared network: gordon-backend

┌────────────────────────────────────────────────┐
│ gordon-backend                                 │
│                                                │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐  │
│  │   App    │←──→│   API    │←──→│ Postgres │  │
│  │  :3000   │    │  :8080   │    │  :5432   │  │
│  └──────────┘    └──────────┘    └──────────┘  │
│                                                │
└────────────────────────────────────────────────┘

Service Discovery

Applications in the same group can communicate using container names:

[routes]
"app.mydomain.com" = "frontend:latest"
"api.mydomain.com" = "backend:latest"

[network_groups]
"services" = ["app.mydomain.com", "api.mydomain.com"]

Server-side code (SSR, API routes) can reach other containers by name:

// In server-side code (SSR / API route) - NOT browser JavaScript
const response = await fetch("http://backend:8080/api/data");

Browser clients should use the public route instead:

// In browser JavaScript
const response = await fetch("https://api.mydomain.com/api/data");

Shared Attachments

Combine network groups with attachments for shared services:

[network_groups]
"backend" = ["app.mydomain.com", "api.mydomain.com"]

[attachments]
"backend" = ["postgres:latest", "redis:latest"]

Both app.mydomain.com and api.mydomain.com can access:

  • postgres:5432
  • redis:6379

Multiple Groups

An application can only be in one network group:

# Each app belongs to one group
[network_groups]
"customer-facing" = ["app.mydomain.com", "api.mydomain.com"]
"internal" = ["admin.mydomain.com", "metrics.mydomain.com"]

Mixed Isolation

Combine network groups with per-app attachments:

[network_groups]
"backend" = ["app.mydomain.com", "api.mydomain.com"]

[attachments]
# Shared by both apps
"backend" = ["redis:latest", "rabbitmq:latest"]

# App-specific databases
"app.mydomain.com" = ["app-postgres:latest"]
"api.mydomain.com" = ["api-postgres:latest"]

Result:

  • Shared: Redis and RabbitMQ
  • Isolated: Each app has its own Postgres

Examples

Microservices Architecture

[routes]
"orders.mydomain.com" = "orders-service:latest"
"inventory.mydomain.com" = "inventory-service:latest"
"shipping.mydomain.com" = "shipping-service:latest"
"payments.mydomain.com" = "payments-service:latest"

[network_groups]
"order-processing" = ["orders.mydomain.com", "inventory.mydomain.com", "shipping.mydomain.com"]
"payment-processing" = ["payments.mydomain.com"]

[attachments]
"order-processing" = ["rabbitmq:latest"]
"payments.mydomain.com" = ["payments-db:latest"]

Monitoring Stack

[routes]
"grafana.mydomain.com" = "grafana/grafana:latest"
"prometheus.mydomain.com" = "prom/prometheus:latest"
"alertmanager.mydomain.com" = "prom/alertmanager:latest"

[network_groups]
"monitoring" = ["grafana.mydomain.com", "prometheus.mydomain.com", "alertmanager.mydomain.com"]

[attachments]
"monitoring" = ["prometheus-data:latest"]

Multi-Tenant SaaS

[routes]
"app.saas.com" = "saas-app:latest"
"api.saas.com" = "saas-api:latest"
"admin.saas.com" = "saas-admin:latest"

# API and App share backend services
[network_groups]
"platform" = ["app.saas.com", "api.saas.com"]

# Admin is isolated
[attachments]
"platform" = ["postgres:latest", "redis:latest", "elasticsearch:latest"]
"admin.saas.com" = ["admin-db:latest"]

Network Naming

Group networks are named: {network_prefix}-{group-name}

Group Network Name
backend gordon-backend
monitoring gordon-monitoring
order-processing gordon-order-processing
source
1# Network Groups
2
3Group multiple applications into shared networks for inter-service communication.
4
5## Configuration
6
7```toml
8[network_groups]
9"backend" = ["app.mydomain.com", "api.mydomain.com"]
10"monitoring" = ["grafana.mydomain.com", "prometheus.mydomain.com"]
11```
12
13## Syntax
14
15```toml
16[network_groups]
17"<group-name>" = ["<domain>", "<domain>", ...]
18```
19
20| Component | Description |
21|-----------|-------------|
22| `group-name` | Name for the shared network |
23| `domains` | List of routes that share this network |
24
25## How It Works
26
27Network groups create shared Docker networks for multiple applications:
28
29```toml
30[network_groups]
31"backend" = ["app.mydomain.com", "api.mydomain.com"]
32```
33
34Creates a shared network: `gordon-backend`
35
36```
37┌────────────────────────────────────────────────┐
38│ gordon-backend                                 │
39│                                                │
40│  ┌──────────┐    ┌──────────┐    ┌──────────┐  │
41│  │   App    │←──→│   API    │←──→│ Postgres │  │
42│  │  :3000   │    │  :8080   │    │  :5432   │  │
43│  └──────────┘    └──────────┘    └──────────┘  │
44│                                                │
45└────────────────────────────────────────────────┘
46```
47
48## Service Discovery
49
50Applications in the same group can communicate using container names:
51
52```toml
53[routes]
54"app.mydomain.com" = "frontend:latest"
55"api.mydomain.com" = "backend:latest"
56
57[network_groups]
58"services" = ["app.mydomain.com", "api.mydomain.com"]
59```
60
61Server-side code (SSR, API routes) can reach other containers by name:
62```javascript
63// In server-side code (SSR / API route) - NOT browser JavaScript
64const response = await fetch("http://backend:8080/api/data");
65```
66
67Browser clients should use the public route instead:
68```javascript
69// In browser JavaScript
70const response = await fetch("https://api.mydomain.com/api/data");
71```
72
73## Shared Attachments
74
75Combine network groups with attachments for shared services:
76
77```toml
78[network_groups]
79"backend" = ["app.mydomain.com", "api.mydomain.com"]
80
81[attachments]
82"backend" = ["postgres:latest", "redis:latest"]
83```
84
85Both `app.mydomain.com` and `api.mydomain.com` can access:
86- `postgres:5432`
87- `redis:6379`
88
89## Multiple Groups
90
91An application can only be in one network group:
92
93```toml
94# Each app belongs to one group
95[network_groups]
96"customer-facing" = ["app.mydomain.com", "api.mydomain.com"]
97"internal" = ["admin.mydomain.com", "metrics.mydomain.com"]
98```
99
100## Mixed Isolation
101
102Combine network groups with per-app attachments:
103
104```toml
105[network_groups]
106"backend" = ["app.mydomain.com", "api.mydomain.com"]
107
108[attachments]
109# Shared by both apps
110"backend" = ["redis:latest", "rabbitmq:latest"]
111
112# App-specific databases
113"app.mydomain.com" = ["app-postgres:latest"]
114"api.mydomain.com" = ["api-postgres:latest"]
115```
116
117Result:
118- Shared: Redis and RabbitMQ
119- Isolated: Each app has its own Postgres
120
121## Examples
122
123### Microservices Architecture
124
125```toml
126[routes]
127"orders.mydomain.com" = "orders-service:latest"
128"inventory.mydomain.com" = "inventory-service:latest"
129"shipping.mydomain.com" = "shipping-service:latest"
130"payments.mydomain.com" = "payments-service:latest"
131
132[network_groups]
133"order-processing" = ["orders.mydomain.com", "inventory.mydomain.com", "shipping.mydomain.com"]
134"payment-processing" = ["payments.mydomain.com"]
135
136[attachments]
137"order-processing" = ["rabbitmq:latest"]
138"payments.mydomain.com" = ["payments-db:latest"]
139```
140
141### Monitoring Stack
142
143```toml
144[routes]
145"grafana.mydomain.com" = "grafana/grafana:latest"
146"prometheus.mydomain.com" = "prom/prometheus:latest"
147"alertmanager.mydomain.com" = "prom/alertmanager:latest"
148
149[network_groups]
150"monitoring" = ["grafana.mydomain.com", "prometheus.mydomain.com", "alertmanager.mydomain.com"]
151
152[attachments]
153"monitoring" = ["prometheus-data:latest"]
154```
155
156### Multi-Tenant SaaS
157
158```toml
159[routes]
160"app.saas.com" = "saas-app:latest"
161"api.saas.com" = "saas-api:latest"
162"admin.saas.com" = "saas-admin:latest"
163
164# API and App share backend services
165[network_groups]
166"platform" = ["app.saas.com", "api.saas.com"]
167
168# Admin is isolated
169[attachments]
170"platform" = ["postgres:latest", "redis:latest", "elasticsearch:latest"]
171"admin.saas.com" = ["admin-db:latest"]
172```
173
174## Network Naming
175
176Group networks are named: `{network_prefix}-{group-name}`
177
178| Group | Network Name |
179|-------|--------------|
180| `backend` | `gordon-backend` |
181| `monitoring` | `gordon-monitoring` |
182| `order-processing` | `gordon-order-processing` |
183
184## Related
185
186- [Network Isolation](./network-isolation.md)
187- [Attachments](./attachments.md)
188- [Routes](./routes.md)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close