Compare commits
33 Commits
f4b46d2926
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0271a88ef | ||
|
|
e92389a44a | ||
|
|
40b0d23f57 | ||
|
|
5a20b9809c | ||
|
|
bbfc5843d8 | ||
|
|
39c368ebd5 | ||
|
|
98ea915ce8 | ||
|
|
dfa81b3396 | ||
|
|
5938bd3cdd | ||
|
|
3050f28460 | ||
|
|
51187de49a | ||
|
|
fad38a229f | ||
|
|
72a9f0ae54 | ||
|
|
bdac46a6c0 | ||
|
|
82bf22006d | ||
|
|
45235aafe5 | ||
|
|
6fc47a50a2 | ||
|
|
3e9fa63083 | ||
|
|
cc3ab19e53 | ||
|
|
96ccb78c5c | ||
|
|
72c0a68836 | ||
|
|
fae1e7f227 | ||
|
|
f474ea3484 | ||
|
|
2279f8cf4b | ||
|
|
10b98f1dba | ||
|
|
60c5158267 | ||
|
|
f6f110d964 | ||
|
|
ff9934a0c7 | ||
|
|
f76a07ea8b | ||
|
|
35c19dcd49 | ||
|
|
20feed2b30 | ||
|
|
c353bb1c78 | ||
|
|
f50667712d |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
traefik/dynamic.yml
|
core/dynamic.yml
|
||||||
traefik/static.yml
|
core/static.yml
|
||||||
crowdsec/acquis.yaml
|
crowdsec/acquis.yaml
|
||||||
traefik/acquis.yaml
|
traefik/acquis.yaml
|
||||||
|
core/acquis.yaml
|
||||||
686
README.md
Normal file
686
README.md
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
# Docker Swarm Cluster Report
|
||||||
|
|
||||||
|
**Generated**: 2025-11-29 17:13:31 UTC
|
||||||
|
|
||||||
|
## Swarm Cluster Overview
|
||||||
|
|
||||||
|
### Node Status
|
||||||
|
|
||||||
|
| p0-compute | Ready | Active | Reachable | 29.0.4 |
|
||||||
|
| p1-control | Ready | Active | Reachable | 29.0.4 |
|
||||||
|
| p2-control | Ready | Active | Reachable | 29.0.4 |
|
||||||
|
| p3-control | Ready | Active | Leader | 29.0.4 |
|
||||||
|
| p4-compute | Ready | Active | Reachable | 29.0.4 |
|
||||||
|
| p5-compute | Ready | Active | Reachable | 29.0.4 |
|
||||||
|
|
||||||
|
**Cluster Details**:
|
||||||
|
- Cluster ID: iutii5nymo40dsgcuxnfdh6jr
|
||||||
|
- Created: 2025-11-13 14:34:48.038680238 +0000 UTC
|
||||||
|
- Total Nodes: 6
|
||||||
|
- Manager Nodes: 6
|
||||||
|
- Engine Version: 29.0.4
|
||||||
|
- Operating System: Ubuntu 24.04.3 LTS
|
||||||
|
- Kernel: 6.8.0-88-generic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hardware Details
|
||||||
|
|
||||||
|
### p0-compute (Current Node)
|
||||||
|
|
||||||
|
**Processor**:
|
||||||
|
```
|
||||||
|
Architecture: x86_64
|
||||||
|
CPU(s): 16
|
||||||
|
On-line CPU(s) list: 0-15
|
||||||
|
Model name: AMD Ryzen 7 5800H with Radeon Graphics
|
||||||
|
Thread(s) per core: 2
|
||||||
|
Core(s) per socket: 8
|
||||||
|
Socket(s): 1
|
||||||
|
CPU(s) scaling MHz: 83%
|
||||||
|
CPU max MHz: 4463.0000
|
||||||
|
CPU min MHz: 400.0000
|
||||||
|
NUMA node0 CPU(s): 0-15
|
||||||
|
```
|
||||||
|
|
||||||
|
**Memory**:
|
||||||
|
```
|
||||||
|
total used free shared buff/cache available
|
||||||
|
Mem: 28Gi 2.2Gi 7.7Gi 2.4Mi 18Gi 26Gi
|
||||||
|
Swap: 8.0Gi 0B 8.0Gi
|
||||||
|
```
|
||||||
|
|
||||||
|
**Storage**:
|
||||||
|
```
|
||||||
|
Filesystem Size Used Avail Use% Mounted on
|
||||||
|
/dev/mapper/ubuntu--vg-ubuntu--lv 98G 39G 55G 42% /
|
||||||
|
/dev/nvme0n1p2 2.0G 198M 1.6G 11% /boot
|
||||||
|
/dev/nvme0n1p1 1.1G 6.2M 1.1G 1% /boot/efi
|
||||||
|
```
|
||||||
|
|
||||||
|
**Block Devices**:
|
||||||
|
```
|
||||||
|
NAME SIZE TYPE MOUNTPOINT FSTYPE
|
||||||
|
nvme0n1 953.9G disk
|
||||||
|
├─nvme0n1p1 1G part /boot/efi vfat
|
||||||
|
├─nvme0n1p2 2G part /boot ext4
|
||||||
|
└─nvme0n1p3 950.8G part LVM2_member
|
||||||
|
└─ubuntu--vg-ubuntu--lv 100G lvm / ext4
|
||||||
|
```
|
||||||
|
|
||||||
|
**Network Interfaces**:
|
||||||
|
```
|
||||||
|
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
||||||
|
inet 127.0.0.1/8 scope host lo
|
||||||
|
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||||
|
inet 10.0.4.11/24 metric 100 brd 10.0.4.255 scope global dynamic enp1s0
|
||||||
|
3: wlo1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
|
||||||
|
4: docker_gwbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
||||||
|
inet 172.18.0.1/16 brd 172.18.255.255 scope global docker_gwbridge
|
||||||
|
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
|
||||||
|
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
|
||||||
|
106: vethb68b357@if105: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
211: veth281d180@if210: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
215: veth07de1c1@if214: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
219: vethbb8c162@if218: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
225: veth26a4063@if224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
231: veth7d33e67@if230: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
237: veth5e29c61@if236: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
|
||||||
|
```
|
||||||
|
|
||||||
|
**System Load**:
|
||||||
|
```
|
||||||
|
17:13:31 up 8 days, 4:59, 3 users, load average: 0.30, 0.16, 0.19
|
||||||
|
Load: 0.30 0.16 0.19 1/849 3444576
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remote Nodes
|
||||||
|
|
||||||
|
#### p1-control (10.0.4.12)
|
||||||
|
|
||||||
|
**CPU**: `Cortex-A76`
|
||||||
|
**Cores**: `4`
|
||||||
|
**Memory**: `N/A`
|
||||||
|
**Storage**: `235G total, 8.9G used, 216G available (4% used)`
|
||||||
|
**Uptime**: `up 1 week, 1 day, 4 hours, 58 minutes`
|
||||||
|
|
||||||
|
#### p2-control (10.0.4.13)
|
||||||
|
|
||||||
|
**CPU**: `Cortex-A76`
|
||||||
|
**Cores**: `4`
|
||||||
|
**Memory**: `N/A`
|
||||||
|
**Storage**: `117G total, 7.3G used, 105G available (7% used)`
|
||||||
|
**Uptime**: `up 1 week, 1 day, 4 hours, 56 minutes`
|
||||||
|
|
||||||
|
#### p3-control (10.0.4.14)
|
||||||
|
|
||||||
|
**CPU**: `Cortex-A76`
|
||||||
|
**Cores**: `4`
|
||||||
|
**Memory**: `N/A`
|
||||||
|
**Storage**: `470G total, 6.9G used, 444G available (2% used)`
|
||||||
|
**Uptime**: `up 1 week, 1 day, 4 hours, 55 minutes`
|
||||||
|
|
||||||
|
#### p4-compute (10.0.4.15)
|
||||||
|
|
||||||
|
**CPU**: `12th Gen Intel(R) Core(TM) i5-12600K`
|
||||||
|
**Cores**: `5`
|
||||||
|
**Memory**: `N/A`
|
||||||
|
**Storage**: `60G total, 22G used, 36G available (38% used)`
|
||||||
|
**Uptime**: `up 28 minutes`
|
||||||
|
|
||||||
|
#### p5-compute (10.0.4.16)
|
||||||
|
|
||||||
|
**CPU**: `12th Gen Intel(R) Core(TM) i5-12600K`
|
||||||
|
**Cores**: `5`
|
||||||
|
**Memory**: `N/A`
|
||||||
|
**Storage**: `60G total, 20G used, 38G available (34% used)`
|
||||||
|
**Uptime**: `up 28 minutes`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Storage Infrastructure
|
||||||
|
|
||||||
|
### Mounted Filesystems
|
||||||
|
```
|
||||||
|
Filesystem Size Used Avail Use% Mounted on
|
||||||
|
10.0.4.10:/mnt/user/frostlabs 4.6T 815G 3.8T 18% /home/doc/projects/homelab
|
||||||
|
```
|
||||||
|
|
||||||
|
### GlusterFS Shared Storage
|
||||||
|
```
|
||||||
|
localhost:swarm-data on /home/doc/projects/swarm-data type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072,_netdev)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Application Data Usage**:
|
||||||
|
```
|
||||||
|
1.3G /home/doc/projects/swarm-data/n8n
|
||||||
|
815M /home/doc/projects/swarm-data/paperless
|
||||||
|
65M /home/doc/projects/swarm-data/crowdsec
|
||||||
|
26M /home/doc/projects/swarm-data/traefik
|
||||||
|
13M /home/doc/projects/swarm-data/leantime
|
||||||
|
873K /home/doc/projects/swarm-data/portainer
|
||||||
|
295K /home/doc/projects/swarm-data/webfiles
|
||||||
|
148K /home/doc/projects/swarm-data/authentik
|
||||||
|
101K /home/doc/projects/swarm-data/cluster-reports
|
||||||
|
25K /home/doc/projects/swarm-data/peertube
|
||||||
|
23K /home/doc/projects/swarm-data/pulse
|
||||||
|
14K /home/doc/projects/swarm-data/webservers
|
||||||
|
12K /home/doc/projects/swarm-data/wiki
|
||||||
|
11K /home/doc/projects/swarm-data/swarm-cluster-report.md
|
||||||
|
8.0K /home/doc/projects/swarm-data/outline
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Storage
|
||||||
|
```
|
||||||
|
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
|
||||||
|
Images 14 6 9.906GB 3.897GB (39%)
|
||||||
|
Containers 6 6 76.17MB 0B (0%)
|
||||||
|
Local Volumes 6 4 859.7MB 219B (0%)
|
||||||
|
Build Cache 43 0 2.718GB 2.718GB
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Volumes
|
||||||
|
```
|
||||||
|
DRIVER VOLUME NAME
|
||||||
|
local 2a12ce4d80ed228df0407922ec7e7ab4ec377a5bf1ba705c66af91c55b2a5fe9
|
||||||
|
local 253ac8ad683409f2b8c98984020595bc40e44f39cc2be9dda83c52b3948a5288
|
||||||
|
local e8b304d313cf8e6d5f916b407e3136eb8dce42113185395c0d4bdac187c54420
|
||||||
|
local netdata_netdatacache
|
||||||
|
local netdata_netdataconfig
|
||||||
|
local netdata_netdatalib
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
### Docker Networks
|
||||||
|
```
|
||||||
|
NETWORK ID NAME DRIVER SCOPE
|
||||||
|
96516fc92029 bridge bridge local
|
||||||
|
108989d65846 docker_gwbridge bridge local
|
||||||
|
uqtj8gddx10e frostlabs overlay swarm
|
||||||
|
91db06c956a7 host host local
|
||||||
|
wkdnemyo9t0m ingress overlay swarm
|
||||||
|
d3024e25ac24 none null local
|
||||||
|
```
|
||||||
|
|
||||||
|
### Overlay Network Details (frostlabs)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Name": "frostlabs",
|
||||||
|
"Id": "uqtj8gddx10e5t4qdea05tt2c",
|
||||||
|
"Created": "2025-11-29T17:04:44.054714019Z",
|
||||||
|
"Scope": "swarm",
|
||||||
|
"Driver": "overlay",
|
||||||
|
"EnableIPv4": true,
|
||||||
|
"EnableIPv6": false,
|
||||||
|
"IPAM": {
|
||||||
|
"Driver": "default",
|
||||||
|
"Options": null,
|
||||||
|
"Config": [
|
||||||
|
{
|
||||||
|
"Subnet": "10.0.1.0/24",
|
||||||
|
"IPRange": "",
|
||||||
|
"Gateway": "10.0.1.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Internal": false,
|
||||||
|
"Attachable": true,
|
||||||
|
"Ingress": false,
|
||||||
|
"ConfigFrom": {
|
||||||
|
"Network": ""
|
||||||
|
},
|
||||||
|
"ConfigOnly": false,
|
||||||
|
"Options": {
|
||||||
|
"com.docker.network.driver.overlay.vxlanid_list": "4097"
|
||||||
|
},
|
||||||
|
"Labels": {},
|
||||||
|
"Peers": [
|
||||||
|
{
|
||||||
|
"Name": "4d3d131a9072",
|
||||||
|
"IP": "10.0.4.12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "2dc3e26647be",
|
||||||
|
"IP": "10.0.4.16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "0fa05fb4badc",
|
||||||
|
"IP": "10.0.4.14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "ba45d88141ad",
|
||||||
|
"IP": "10.0.4.13"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "d5e101a6aa8a",
|
||||||
|
"IP": "10.0.4.11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "532747b2bb73",
|
||||||
|
"IP": "10.0.4.15"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Containers": {
|
||||||
|
"387433afd0a4949b3f19ca2de1d397cfe7e8ddcd784686e72cbefd8fa8aeb70e": {
|
||||||
|
"Name": "netdata_netdata.vtgnge0wpukgwn3ct2c3ue81g.2uap80qv8lbrs5atilc2u3qia",
|
||||||
|
"EndpointID": "cc36398dc0cf6273ba8b4743dacfe0d517d4dc8b76d60af1fba6186e2d7f4549",
|
||||||
|
"MacAddress": "02:42:0a:00:01:75",
|
||||||
|
"IPv4Address": "10.0.1.117/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
},
|
||||||
|
"422044b5c056c63c580fc795e8519c603c8045562a14d9646d03274fd0acf324": {
|
||||||
|
"Name": "core_agent.vtgnge0wpukgwn3ct2c3ue81g.3ftzdym5g2cej9i3rineisqs7",
|
||||||
|
"EndpointID": "3c3bc64b2285a70a4587499c211c89333d816635232b571baee68314881c9d14",
|
||||||
|
"MacAddress": "02:42:0a:00:01:5c",
|
||||||
|
"IPv4Address": "10.0.1.92/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
},
|
||||||
|
"65b52609f5a5b103f1ec3412de4afbcfb7dfe54a9705f6120b3d931ce5fe1aae": {
|
||||||
|
"Name": "n8n_n8n.1.kv9s1hom7fk7olv4smstk7n43",
|
||||||
|
"EndpointID": "686d537fe00c8f733eb41169fafb0ce560e3ac5df25031ad6302a0c12115e523",
|
||||||
|
"MacAddress": "02:42:0a:00:01:6e",
|
||||||
|
"IPv4Address": "10.0.1.110/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
},
|
||||||
|
"7787e194dd2f76696d6858cceb4007bc4ab16e78b181f7a109388a23a92906d5": {
|
||||||
|
"Name": "core_redis.1.j1qqhrwydjyrlpxyhrjryfmhi",
|
||||||
|
"EndpointID": "7db1e8881a7ade0b3d3b9a751404b7358a6833c8c0b58b5929ff1b8cdfb7f9d9",
|
||||||
|
"MacAddress": "02:42:0a:00:01:63",
|
||||||
|
"IPv4Address": "10.0.1.99/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
},
|
||||||
|
"9ff8ccaa9e50caeafa27c2404aefe9306ac3ca65177d33c8100e453bb6eeaac2": {
|
||||||
|
"Name": "dozzle_dozzle.vtgnge0wpukgwn3ct2c3ue81g.xylxcjit84hequnjrbxbt5088",
|
||||||
|
"EndpointID": "bd7250dc9c019897f468d46569b7206a34e0004f3f58e1382b35637e6d18cee6",
|
||||||
|
"MacAddress": "02:42:0a:00:01:6c",
|
||||||
|
"IPv4Address": "10.0.1.108/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
},
|
||||||
|
"d773d035f9402422f6f1d0fd37a14d9f741d32576a59c52337fd5dfa5914871d": {
|
||||||
|
"Name": "peertube_peertube.1.xkkvqxwhryep4enozc0zsfbf1",
|
||||||
|
"EndpointID": "420575b413b02b6ecaf3e8c46fdb9cab0dbadb16b053c97011497f9f5f96a4e2",
|
||||||
|
"MacAddress": "02:42:0a:00:01:7f",
|
||||||
|
"IPv4Address": "10.0.1.127/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
},
|
||||||
|
"lb-frostlabs": {
|
||||||
|
"Name": "frostlabs-endpoint",
|
||||||
|
"EndpointID": "0a1eb5fb6b06df20ff9f0cbc75a04936a0028441138579bab0f1401730559377",
|
||||||
|
"MacAddress": "02:42:0a:00:01:60",
|
||||||
|
"IPv4Address": "10.0.1.96/24",
|
||||||
|
"IPv6Address": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Status": {
|
||||||
|
"IPAM": {
|
||||||
|
"Subnets": {
|
||||||
|
"10.0.1.0/24": {
|
||||||
|
"IPsInUse": 58,
|
||||||
|
"DynamicIPsAvailable": 198
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Published Ports
|
||||||
|
```
|
||||||
|
adminer_adminer:
|
||||||
|
core_agent:
|
||||||
|
core_authentik_server:
|
||||||
|
core_authentik_worker:
|
||||||
|
core_portainer: *:9000->9000/tcp
|
||||||
|
core_redis:
|
||||||
|
core_traefik: *:80->80/tcp, *:443->443/tcp, *:8082->8080/tcp
|
||||||
|
dozzle_dozzle: *:8080->8080/tcp
|
||||||
|
n8n_n8n: *:5678->5678/tcp
|
||||||
|
netdata_netdata: *:19999->19999/tcp
|
||||||
|
paperless_paperless_redis:
|
||||||
|
paperless_paperless_webserver:
|
||||||
|
peertube_peertube:
|
||||||
|
peertube_postgres: *:5432->5432/tcp
|
||||||
|
peertube_redis:
|
||||||
|
tracker_tracker-nginx: *:8180->80/tcp
|
||||||
|
wiki_wiki: *:3000->3000/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployed Services
|
||||||
|
|
||||||
|
### Stacks
|
||||||
|
```
|
||||||
|
NAME SERVICES
|
||||||
|
adminer 1
|
||||||
|
core 6
|
||||||
|
dozzle 1
|
||||||
|
n8n 1
|
||||||
|
netdata 1
|
||||||
|
paperless 2
|
||||||
|
peertube 3
|
||||||
|
tracker 1
|
||||||
|
wiki 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Services
|
||||||
|
```
|
||||||
|
ID NAME MODE REPLICAS IMAGE PORTS
|
||||||
|
m9omofpn9bw6 adminer_adminer replicated 1/1 adminer:latest
|
||||||
|
sj19vr2nw0kp core_agent global 6/6 portainer/agent:latest
|
||||||
|
5k4qkbgfeys8 core_authentik_server replicated 1/1 ghcr.io/goauthentik/server:2025.10.0
|
||||||
|
65qy6wmjbdsn core_authentik_worker replicated 1/1 ghcr.io/goauthentik/server:2025.10.0
|
||||||
|
xng4hh1x7spf core_portainer replicated 1/1 portainer/portainer-ce:latest *:9000->9000/tcp
|
||||||
|
cd0cvtzw8j0t core_redis replicated 1/1 redis:alpine
|
||||||
|
rjsk8v0lebc0 core_traefik replicated 1/1 traefik:v3.6.1 *:80->80/tcp, *:443->443/tcp, *:8082->8080/tcp
|
||||||
|
i6mu3tf3u5ef dozzle_dozzle global 6/6 amir20/dozzle:latest *:8080->8080/tcp
|
||||||
|
pp0cz85w2kdi n8n_n8n replicated 1/1 n8nio/n8n:latest *:5678->5678/tcp
|
||||||
|
kpe5e0aez8j0 netdata_netdata global 6/6 netdata/netdata:stable *:19999->19999/tcp
|
||||||
|
imy76qvd40hq paperless_paperless_redis replicated 1/1 redis:alpine
|
||||||
|
eqf52b9sgmcf paperless_paperless_webserver replicated 1/1 ghcr.io/paperless-ngx/paperless-ngx:latest
|
||||||
|
ysy9weeo8n41 peertube_peertube replicated 1/1 chocobozzz/peertube:production-bookworm
|
||||||
|
uyo4qxsa8r4v peertube_postgres replicated 1/1 postgres:17-alpine *:5432->5432/tcp
|
||||||
|
703wunzrgu99 peertube_redis replicated 1/1 redis:7-alpine
|
||||||
|
p32115n71f0s tracker_tracker-nginx replicated 1/1 nginx:alpine *:8180->80/tcp
|
||||||
|
sujusu1pzal8 wiki_wiki replicated 1/1 ghcr.io/requarks/wiki:2 *:3000->3000/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Distribution by Stack
|
||||||
|
|
||||||
|
#### Stack: adminer
|
||||||
|
```
|
||||||
|
adminer_adminer.1 p4-compute Running 7 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: core
|
||||||
|
```
|
||||||
|
core_agent.5lfnhogleddgqenj9pb3bnbiq p5-compute Running 8 minutes ago
|
||||||
|
core_agent.9k5wdjeo2pn6bgm6t3kni105w p4-compute Running 8 minutes ago
|
||||||
|
core_agent.lmqjm4tqh1dw12rn49b5zmsv7 p1-control Running 8 minutes ago
|
||||||
|
core_agent.v9u4wpdzqvjsw1d7v2nqnudjv p2-control Running 8 minutes ago
|
||||||
|
core_agent.vbd9ze987kd06kb6oorfziuga p3-control Running 8 minutes ago
|
||||||
|
core_agent.vtgnge0wpukgwn3ct2c3ue81g p0-compute Running 8 minutes ago
|
||||||
|
core_authentik_server.1 p1-control Running 8 minutes ago
|
||||||
|
core_authentik_worker.1 p5-compute Running 8 minutes ago
|
||||||
|
core_portainer.1 p2-control Running 8 minutes ago
|
||||||
|
core_redis.1 p0-compute Running 8 minutes ago
|
||||||
|
core_traefik.1 p3-control Running 8 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: dozzle
|
||||||
|
```
|
||||||
|
dozzle_dozzle.5lfnhogleddgqenj9pb3bnbiq p5-compute Running 7 minutes ago
|
||||||
|
dozzle_dozzle.9k5wdjeo2pn6bgm6t3kni105w p4-compute Running 7 minutes ago
|
||||||
|
dozzle_dozzle.lmqjm4tqh1dw12rn49b5zmsv7 p1-control Running 7 minutes ago
|
||||||
|
dozzle_dozzle.v9u4wpdzqvjsw1d7v2nqnudjv p2-control Running 7 minutes ago
|
||||||
|
dozzle_dozzle.vbd9ze987kd06kb6oorfziuga p3-control Running 7 minutes ago
|
||||||
|
dozzle_dozzle.vtgnge0wpukgwn3ct2c3ue81g p0-compute Running 7 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: n8n
|
||||||
|
```
|
||||||
|
n8n_n8n.1 p0-compute Running 6 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: netdata
|
||||||
|
```
|
||||||
|
netdata_netdata.5lfnhogleddgqenj9pb3bnbiq p5-compute Running 6 minutes ago
|
||||||
|
netdata_netdata.9k5wdjeo2pn6bgm6t3kni105w p4-compute Running 6 minutes ago
|
||||||
|
netdata_netdata.lmqjm4tqh1dw12rn49b5zmsv7 p1-control Running 6 minutes ago
|
||||||
|
netdata_netdata.v9u4wpdzqvjsw1d7v2nqnudjv p2-control Running 6 minutes ago
|
||||||
|
netdata_netdata.vbd9ze987kd06kb6oorfziuga p3-control Running 6 minutes ago
|
||||||
|
netdata_netdata.vtgnge0wpukgwn3ct2c3ue81g p0-compute Running 6 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: paperless
|
||||||
|
```
|
||||||
|
paperless_paperless_redis.1 p5-compute Running 6 minutes ago
|
||||||
|
paperless_paperless_webserver.1 p4-compute Running 6 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: peertube
|
||||||
|
```
|
||||||
|
peertube_peertube.1 p0-compute Running 6 minutes ago
|
||||||
|
peertube_postgres.1 p2-control Running 6 minutes ago
|
||||||
|
peertube_redis.1 p1-control Running 6 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: tracker
|
||||||
|
```
|
||||||
|
tracker_tracker-nginx.1 p5-compute Running 6 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stack: wiki
|
||||||
|
```
|
||||||
|
wiki_wiki.1 p4-compute Running 6 minutes ago
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Container Distribution
|
||||||
|
|
||||||
|
### Current Node Containers
|
||||||
|
```
|
||||||
|
NAMES IMAGE STATUS
|
||||||
|
peertube_peertube.1.xkkvqxwhryep4enozc0zsfbf1 chocobozzz/peertube:production-bookworm Up 6 minutes
|
||||||
|
n8n_n8n.1.kv9s1hom7fk7olv4smstk7n43 n8nio/n8n:latest Up 6 minutes (healthy)
|
||||||
|
netdata_netdata.vtgnge0wpukgwn3ct2c3ue81g.2uap80qv8lbrs5atilc2u3qia netdata/netdata:stable Up 7 minutes (healthy)
|
||||||
|
dozzle_dozzle.vtgnge0wpukgwn3ct2c3ue81g.xylxcjit84hequnjrbxbt5088 amir20/dozzle:latest Up 7 minutes
|
||||||
|
core_redis.1.j1qqhrwydjyrlpxyhrjryfmhi redis:alpine Up 8 minutes (healthy)
|
||||||
|
core_agent.vtgnge0wpukgwn3ct2c3ue81g.3ftzdym5g2cej9i3rineisqs7 portainer/agent:latest Up 8 minutes
|
||||||
|
```
|
||||||
|
|
||||||
|
### All Nodes Container Count
|
||||||
|
- p0-compute: 6 containers
|
||||||
|
- p1-control: 5 containers
|
||||||
|
- p2-control: 5 containers
|
||||||
|
- p3-control: 4 containers
|
||||||
|
- p4-compute: 6 containers
|
||||||
|
- p5-compute: 6 containers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Node Labels & Roles
|
||||||
|
|
||||||
|
```
|
||||||
|
p0-compute: map[task:compute]
|
||||||
|
p1-control: map[task:control]
|
||||||
|
p2-control: map[task:control]
|
||||||
|
p3-control: map[task:control]
|
||||||
|
p4-compute: map[task:compute]
|
||||||
|
p5-compute: map[task:compute]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cluster Configuration
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"NodeID": "vtgnge0wpukgwn3ct2c3ue81g",
|
||||||
|
"NodeAddr": "10.0.4.11",
|
||||||
|
"LocalNodeState": "active",
|
||||||
|
"ControlAvailable": true,
|
||||||
|
"Error": "",
|
||||||
|
"RemoteManagers": [
|
||||||
|
{
|
||||||
|
"NodeID": "vbd9ze987kd06kb6oorfziuga",
|
||||||
|
"Addr": "10.0.4.14:2377"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NodeID": "vtgnge0wpukgwn3ct2c3ue81g",
|
||||||
|
"Addr": "10.0.4.11:2377"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NodeID": "5lfnhogleddgqenj9pb3bnbiq",
|
||||||
|
"Addr": "10.0.4.16:2377"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NodeID": "9k5wdjeo2pn6bgm6t3kni105w",
|
||||||
|
"Addr": "10.0.4.15:2377"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NodeID": "lmqjm4tqh1dw12rn49b5zmsv7",
|
||||||
|
"Addr": "10.0.4.12:2377"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NodeID": "v9u4wpdzqvjsw1d7v2nqnudjv",
|
||||||
|
"Addr": "10.0.4.13:2377"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Nodes": 6,
|
||||||
|
"Managers": 6,
|
||||||
|
"Cluster": {
|
||||||
|
"ID": "iutii5nymo40dsgcuxnfdh6jr",
|
||||||
|
"Version": {
|
||||||
|
"Index": 135075
|
||||||
|
},
|
||||||
|
"CreatedAt": "2025-11-13T14:34:48.038680238Z",
|
||||||
|
"UpdatedAt": "2025-11-29T10:25:03.236675911Z",
|
||||||
|
"Spec": {
|
||||||
|
"Name": "default",
|
||||||
|
"Labels": {},
|
||||||
|
"Orchestration": {
|
||||||
|
"TaskHistoryRetentionLimit": 5
|
||||||
|
},
|
||||||
|
"Raft": {
|
||||||
|
"SnapshotInterval": 10000,
|
||||||
|
"KeepOldSnapshots": 0,
|
||||||
|
"LogEntriesForSlowFollowers": 500,
|
||||||
|
"ElectionTick": 10,
|
||||||
|
"HeartbeatTick": 1
|
||||||
|
},
|
||||||
|
"Dispatcher": {
|
||||||
|
"HeartbeatPeriod": 5000000000
|
||||||
|
},
|
||||||
|
"CAConfig": {
|
||||||
|
"NodeCertExpiry": 7776000000000000
|
||||||
|
},
|
||||||
|
"TaskDefaults": {},
|
||||||
|
"EncryptionConfig": {
|
||||||
|
"AutoLockManagers": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TLSInfo": {
|
||||||
|
"TrustRoot": "-----BEGIN CERTIFICATE-----\nMIIBajCCARCgAwIBAgIUOkVEhR7ir7HWSBC4Eoj71XBnCUgwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMjUxMTEzMTQzMDAwWhcNNDUxMTA4MTQz\nMDAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABPqdHvAk/XP51IaMZE8GWt2h90o8JsKoo1O8VS6Qs4yJ0N0HZ0vHmiIm9T3i\nkJ6Vhj6IfSBNBReFe3MVX3i4FvejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBSzhamb4jVwspS8Ceflk62jvU9AwDAKBggqhkjO\nPQQDAgNIADBFAiEAnduA5iS0SMX/jllJv8Y/XNgVoDcOTXs5gntn5uZOhwYCIEGD\nEsN73RfTYcLhmknpiMiiDnqAY6infpMC27w66iNz\n-----END CERTIFICATE-----\n",
|
||||||
|
"CertIssuerSubject": "MBMxETAPBgNVBAMTCHN3YXJtLWNh",
|
||||||
|
"CertIssuerPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+p0e8CT9c/nUhoxkTwZa3aH3SjwmwqijU7xVLpCzjInQ3QdnS8eaIib1PeKQnpWGPoh9IE0FF4V7cxVfeLgW9w=="
|
||||||
|
},
|
||||||
|
"RootRotationInProgress": false,
|
||||||
|
"DefaultAddrPool": [
|
||||||
|
"10.0.0.0/8"
|
||||||
|
],
|
||||||
|
"SubnetSize": 24,
|
||||||
|
"DataPathPort": 4789
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System Health
|
||||||
|
|
||||||
|
### Service Health Status
|
||||||
|
```
|
||||||
|
adminer_adminer 1/1
|
||||||
|
core_agent 6/6
|
||||||
|
core_authentik_server 1/1
|
||||||
|
core_authentik_worker 1/1
|
||||||
|
core_portainer 1/1
|
||||||
|
core_redis 1/1
|
||||||
|
core_traefik 1/1
|
||||||
|
dozzle_dozzle 6/6
|
||||||
|
n8n_n8n 1/1
|
||||||
|
netdata_netdata 6/6
|
||||||
|
paperless_paperless_redis 1/1
|
||||||
|
paperless_paperless_webserver 1/1
|
||||||
|
peertube_peertube 1/1
|
||||||
|
peertube_postgres 1/1
|
||||||
|
peertube_redis 1/1
|
||||||
|
tracker_tracker-nginx 1/1
|
||||||
|
wiki_wiki 1/1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node Availability
|
||||||
|
```
|
||||||
|
p0-compute Ready Active Reachable
|
||||||
|
p1-control Ready Active Reachable
|
||||||
|
p2-control Ready Active Reachable
|
||||||
|
p3-control Ready Active Leader
|
||||||
|
p4-compute Ready Active Reachable
|
||||||
|
p5-compute Ready Active Reachable
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Utilization (Current Node)
|
||||||
|
```
|
||||||
|
CPU Load: 0.36, 0.17, 0.20
|
||||||
|
Memory: Total: 28Gi, Used: 2.2Gi, Free: 7.7Gi, Available: 26Gi
|
||||||
|
Disk: Total: 98G, Used: 39G, Available: 55G, Use%: 42%
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Daemon Status
|
||||||
|
```
|
||||||
|
Server Version: 29.0.4
|
||||||
|
Storage Driver: overlay2
|
||||||
|
Logging Driver: json-file
|
||||||
|
Cgroup Driver: systemd
|
||||||
|
Kernel Version: 6.8.0-88-generic
|
||||||
|
Operating System: Ubuntu 24.04.3 LTS
|
||||||
|
OSType: linux
|
||||||
|
Architecture: x86_64
|
||||||
|
CPUs: 16
|
||||||
|
Total Memory: 28.31GiB
|
||||||
|
Docker Root Dir: /var/lib/docker
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
### Maintenance Tasks
|
||||||
|
- [ ] Review and prune unused Docker images: `docker image prune -a`
|
||||||
|
- [ ] Review and prune unused volumes: `docker volume prune`
|
||||||
|
- [ ] Check for service updates: Review each service for newer image versions
|
||||||
|
- [ ] Backup GlusterFS volumes to external storage
|
||||||
|
- [ ] Review container logs for errors: `docker service logs <service-name>`
|
||||||
|
- [ ] Test failover by cordoning a node: `docker node update --availability drain <node>`
|
||||||
|
|
||||||
|
### Monitoring Suggestions
|
||||||
|
- Consider deploying Prometheus + Grafana for metrics
|
||||||
|
- Implement centralized logging (ELK, Loki, or similar)
|
||||||
|
- Set up alerting for node failures
|
||||||
|
- Monitor GlusterFS health and replication status
|
||||||
|
- Track container restart counts
|
||||||
|
|
||||||
|
### Security Audit
|
||||||
|
- [ ] Ensure all services use specific version tags (not `latest`)
|
||||||
|
- [ ] Review published ports and restrict unnecessary exposure
|
||||||
|
- [ ] Implement Docker secrets for sensitive configuration
|
||||||
|
- [ ] Enable TLS for all inter-service communication
|
||||||
|
- [ ] Review CrowdSec rules and ban lists
|
||||||
|
- [ ] Audit Traefik configuration for security headers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This Docker Swarm cluster report was generated on **2025-11-29 17:13:31 UTC**.
|
||||||
|
|
||||||
|
**Cluster Statistics**:
|
||||||
|
- Nodes: 6 (6 managers)
|
||||||
|
- Stacks: 10
|
||||||
|
- Services: 17
|
||||||
|
- Containers: 6
|
||||||
|
- Images: 14
|
||||||
|
- Networks: 6
|
||||||
|
- Volumes: 6
|
||||||
|
|
||||||
|
**Status**: Cluster is operational and all manager nodes are reachable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Report generated by: `generate-swarm-report.sh`*
|
||||||
|
*Script location: `/home/doc/projects/swarm-data/cluster-reports`*
|
||||||
@@ -1,4 +1,105 @@
|
|||||||
services:
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:v3.6.1
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 443:443
|
||||||
|
- 8082:8080
|
||||||
|
environment:
|
||||||
|
- CF_DNS_API_TOKEN_FILE=/run/secrets/cloudflare_api_token
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./static.yml:/etc/traefik/traefik.yml:ro
|
||||||
|
- ./dynamic.yml:/etc/traefik/dynamic/dynamic.yml:ro
|
||||||
|
- /home/doc/projects/swarm-data/traefik/certificates:/certificates
|
||||||
|
- /home/doc/projects/swarm-data/traefik/logs:/var/log/traefik
|
||||||
|
secrets:
|
||||||
|
- cloudflare_api_token
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/ping" ]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.labels.task == control
|
||||||
|
|
||||||
|
# crowdsec:
|
||||||
|
# image: crowdsecurity/crowdsec:latest
|
||||||
|
# environment:
|
||||||
|
# # Disable online API enrollment (use for local setup)
|
||||||
|
# - DISABLE_ONLINE_API=false
|
||||||
|
# # Set collections to install
|
||||||
|
# - COLLECTIONS=crowdsecurity/traefik crowdsecurity/http-cve
|
||||||
|
# # Enable Prometheus metrics
|
||||||
|
# - METRICS_PORT=6060
|
||||||
|
# volumes:
|
||||||
|
# # Persistent CrowdSec configuration and data
|
||||||
|
# - /home/doc/projects/swarm-data/crowdsec/config:/etc/crowdsec
|
||||||
|
# - /home/doc/projects/swarm-data/crowdsec/data:/var/lib/crowdsec/data
|
||||||
|
# # Traefik access logs (read-only)
|
||||||
|
# - /home/doc/projects/swarm-data/traefik/logs:/var/log/traefik:ro
|
||||||
|
# # Acquis configuration
|
||||||
|
# - ./acquis.yaml:/etc/crowdsec/acquis.yaml:ro
|
||||||
|
# networks:
|
||||||
|
# - frostlabs
|
||||||
|
# deploy:
|
||||||
|
# mode: replicated
|
||||||
|
# replicas: 1
|
||||||
|
# placement:
|
||||||
|
# constraints:
|
||||||
|
# - node.labels.task == control
|
||||||
|
# restart_policy:
|
||||||
|
# condition: on-failure
|
||||||
|
# delay: 5s
|
||||||
|
# max_attempts: 3
|
||||||
|
# healthcheck:
|
||||||
|
# test: [ "CMD", "cscli", "version" ]
|
||||||
|
# interval: 30s
|
||||||
|
# timeout: 10s
|
||||||
|
# retries: 3
|
||||||
|
# start_period: 60s
|
||||||
|
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer-ce:latest
|
||||||
|
command: -H tcp://tasks.agent:9001 --tlsskipverify
|
||||||
|
volumes:
|
||||||
|
- /home/doc/projects/swarm-data/portainer:/data
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
ports:
|
||||||
|
- 9000:9000
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.labels.task == control
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.swarm.network=frostlabs"
|
||||||
|
- "traefik.http.routers.portainer.rule=Host(`portainer.frostlabs.me`)"
|
||||||
|
- "traefik.http.routers.portainer.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.portainer.tls=true"
|
||||||
|
- "traefik.http.routers.portainer.tls.certresolver=cloudflare"
|
||||||
|
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
|
||||||
|
|
||||||
|
agent:
|
||||||
|
image: portainer/agent:latest
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /var/lib/docker/volumes:/var/lib/docker/volumes
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
deploy:
|
||||||
|
mode: global
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:alpine
|
image: redis:alpine
|
||||||
command: --save 60 1 --loglevel warning
|
command: --save 60 1 --loglevel warning
|
||||||
@@ -109,11 +210,15 @@ services:
|
|||||||
memory: 512M
|
memory: 512M
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
frostlabs:
|
frostlabs:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
postgres-master:
|
cloudflare_api_token:
|
||||||
external: true
|
external: true
|
||||||
auth-key:
|
auth-key:
|
||||||
external: true
|
external: true
|
||||||
|
postgres-master:
|
||||||
|
external: true
|
||||||
@@ -1,478 +0,0 @@
|
|||||||
# CrowdSec with Traefik - User Guide
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
1. [Overview](#overview)
|
|
||||||
2. [Quick Reference](#quick-reference)
|
|
||||||
3. [Managing Decisions (Bans)](#managing-decisions-bans)
|
|
||||||
4. [Applying Protection to Services](#applying-protection-to-services)
|
|
||||||
5. [Monitoring & Metrics](#monitoring--metrics)
|
|
||||||
6. [Collections & Scenarios](#collections--scenarios)
|
|
||||||
7. [Community Integration](#community-integration)
|
|
||||||
8. [Troubleshooting](#troubleshooting)
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
CrowdSec is a collaborative IPS (Intrusion Prevention System) that protects your services by:
|
|
||||||
- Analyzing Traefik access logs for malicious patterns
|
|
||||||
- Automatically banning suspicious IPs
|
|
||||||
- Sharing threat intelligence with the community
|
|
||||||
- Providing centralized protection across all Traefik-proxied services
|
|
||||||
|
|
||||||
**Architecture:**
|
|
||||||
- **CrowdSec LAPI** (crowdsec_crowdsec) - Analyzes logs and maintains ban list
|
|
||||||
- **Traefik Bouncer** - Middleware that queries LAPI and blocks banned IPs
|
|
||||||
- **Access Logs** - Traefik logs analyzed by CrowdSec at `/home/doc/projects/swarm-data/traefik/logs/access.log`
|
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
### Access CrowdSec CLI
|
|
||||||
|
|
||||||
All commands must be run on the node where CrowdSec is deployed (p3-control):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# SSH to the CrowdSec node
|
|
||||||
ssh 10.0.4.14
|
|
||||||
|
|
||||||
# Run cscli commands
|
|
||||||
docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli [command]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Shortcut alias (add to .bashrc):**
|
|
||||||
```bash
|
|
||||||
alias cscli='ssh 10.0.4.14 "docker exec \$(docker ps -qf name=crowdsec_crowdsec) cscli"'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Essential Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# View all active bans
|
|
||||||
cscli decisions list
|
|
||||||
|
|
||||||
# View CrowdSec status
|
|
||||||
cscli metrics
|
|
||||||
|
|
||||||
# View detailed acquisition metrics
|
|
||||||
cscli metrics show acquisition
|
|
||||||
|
|
||||||
# List registered bouncers
|
|
||||||
cscli bouncers list
|
|
||||||
|
|
||||||
# View recent alerts
|
|
||||||
cscli alerts list
|
|
||||||
|
|
||||||
# Check hub status
|
|
||||||
cscli hub list
|
|
||||||
```
|
|
||||||
|
|
||||||
## Managing Decisions (Bans)
|
|
||||||
|
|
||||||
### View Active Bans
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List all active decisions
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions list'
|
|
||||||
|
|
||||||
# Filter by IP
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions list --ip 1.2.3.4'
|
|
||||||
|
|
||||||
# Filter by type
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions list --type ban'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manually Ban an IP
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ban for 4 hours
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions add --ip 1.2.3.4 --duration 4h --reason "Manual ban"'
|
|
||||||
|
|
||||||
# Ban for 1 day
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions add --ip 1.2.3.4 --duration 24h'
|
|
||||||
|
|
||||||
# Permanent ban
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions add --ip 1.2.3.4 --duration 0'
|
|
||||||
|
|
||||||
# Ban entire subnet
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions add --range 1.2.3.0/24 --duration 4h'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Unban (Delete Decision)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Unban specific IP
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions delete --ip 1.2.3.4'
|
|
||||||
|
|
||||||
# Delete all decisions
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions delete --all'
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Alerts
|
|
||||||
|
|
||||||
Alerts show what triggered a ban:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List recent alerts
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli alerts list'
|
|
||||||
|
|
||||||
# View alert details
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli alerts inspect <alert_id>'
|
|
||||||
|
|
||||||
# Filter alerts by IP
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli alerts list --ip 1.2.3.4'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Applying Protection to Services
|
|
||||||
|
|
||||||
### Protect Docker Swarm Services
|
|
||||||
|
|
||||||
To protect any service proxied by Traefik, add the `crowdsec` middleware to its labels:
|
|
||||||
|
|
||||||
**Example for a Docker Swarm service:**
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
myapp:
|
|
||||||
image: myapp:latest
|
|
||||||
networks:
|
|
||||||
- frostlabs
|
|
||||||
deploy:
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.myapp.rule=Host(`myapp.frostlabs.me`)"
|
|
||||||
- "traefik.http.routers.myapp.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.myapp.tls.certresolver=cloudflare"
|
|
||||||
# Add CrowdSec protection
|
|
||||||
- "traefik.http.routers.myapp.middlewares=crowdsec@file"
|
|
||||||
- "traefik.http.services.myapp.loadbalancer.server.port=8080"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Protect External Services (dynamic.yml)
|
|
||||||
|
|
||||||
For services defined in `/home/doc/projects/homelab/frostlabs/traefik/dynamic.yml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
http:
|
|
||||||
routers:
|
|
||||||
myservice:
|
|
||||||
rule: "Host(`myservice.frostlabs.me`)"
|
|
||||||
entryPoints:
|
|
||||||
- websecure
|
|
||||||
service: myservice
|
|
||||||
middlewares:
|
|
||||||
- crowdsec # Add this line
|
|
||||||
tls:
|
|
||||||
certResolver: cloudflare
|
|
||||||
```
|
|
||||||
|
|
||||||
### Chain Multiple Middlewares
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# In dynamic.yml
|
|
||||||
http:
|
|
||||||
routers:
|
|
||||||
protected-service:
|
|
||||||
middlewares:
|
|
||||||
- authentik # First: Authentication
|
|
||||||
- crowdsec # Second: IP filtering
|
|
||||||
- rate-limit # Third: Rate limiting
|
|
||||||
```
|
|
||||||
|
|
||||||
After making changes, reload Traefik:
|
|
||||||
```bash
|
|
||||||
docker service update --force traefik_traefik
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoring & Metrics
|
|
||||||
|
|
||||||
### Real-time Monitoring
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Overall metrics
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics'
|
|
||||||
|
|
||||||
# Log parsing metrics
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics show acquisition'
|
|
||||||
|
|
||||||
# Scenario metrics (what's triggering)
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics show scenarios'
|
|
||||||
|
|
||||||
# LAPI metrics (bouncer queries)
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics show lapi'
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Logs
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# CrowdSec service logs
|
|
||||||
docker service logs crowdsec_crowdsec --tail 50 --follow
|
|
||||||
|
|
||||||
# Traefik logs (on control node)
|
|
||||||
docker service logs traefik_traefik --tail 50 --follow
|
|
||||||
|
|
||||||
# Access log (what CrowdSec analyzes)
|
|
||||||
tail -f /home/doc/projects/swarm-data/traefik/logs/access.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Bouncer Status
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Verify bouncer is connected
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli bouncers list'
|
|
||||||
|
|
||||||
# Expected output:
|
|
||||||
# Name IP Address Valid Last API pull Type Version Auth Type
|
|
||||||
# traefik-bouncer ✔️ <timestamp> api-key
|
|
||||||
```
|
|
||||||
|
|
||||||
## Collections & Scenarios
|
|
||||||
|
|
||||||
### View Installed Collections
|
|
||||||
|
|
||||||
Collections are pre-packaged sets of parsers and scenarios:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List all collections
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections list'
|
|
||||||
|
|
||||||
# Currently installed:
|
|
||||||
# - crowdsecurity/traefik (Traefik-specific patterns)
|
|
||||||
# - crowdsecurity/http-cve (Common CVE exploits)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Install Additional Collections
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install SSH protection (if you expose SSH)
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections install crowdsecurity/sshd'
|
|
||||||
|
|
||||||
# Install WordPress protection
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections install crowdsecurity/wordpress'
|
|
||||||
|
|
||||||
# Install additional HTTP protections
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections install crowdsecurity/base-http-scenarios'
|
|
||||||
|
|
||||||
# Browse available collections
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections list -a'
|
|
||||||
```
|
|
||||||
|
|
||||||
After installing collections, restart CrowdSec:
|
|
||||||
```bash
|
|
||||||
docker service update --force crowdsec_crowdsec
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Active Scenarios
|
|
||||||
|
|
||||||
Scenarios are detection rules:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List enabled scenarios
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli scenarios list'
|
|
||||||
|
|
||||||
# Browse available scenarios
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli scenarios list -a'
|
|
||||||
|
|
||||||
# Install specific scenario
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli scenarios install crowdsecurity/http-probing'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Community Integration
|
|
||||||
|
|
||||||
### Enroll in CrowdSec Console
|
|
||||||
|
|
||||||
The Console provides centralized management and community blocklists:
|
|
||||||
|
|
||||||
1. **Create account:** https://app.crowdsec.net/signup
|
|
||||||
|
|
||||||
2. **Enroll your instance:**
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec -it $(docker ps -qf name=crowdsec_crowdsec) cscli console enroll <enrollment_key>'
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Verify enrollment:**
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli console status'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Benefits of Enrollment
|
|
||||||
|
|
||||||
- **Community Blocklist:** Automatically receive bans from the CrowdSec network
|
|
||||||
- **Centralized Dashboard:** View all your instances in one place
|
|
||||||
- **Alert Management:** Get notifications for attacks
|
|
||||||
- **Analytics:** Detailed attack reports and trends
|
|
||||||
|
|
||||||
### Subscribe to Blocklists
|
|
||||||
|
|
||||||
After enrollment, subscribe to community blocklists:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install blocklist collection
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections install crowdsecurity/seo-bots-whitelist'
|
|
||||||
|
|
||||||
# Enable community blocklist
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli capi register'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### CrowdSec Not Reading Logs
|
|
||||||
|
|
||||||
**Check if logs exist:**
|
|
||||||
```bash
|
|
||||||
ls -lh /home/doc/projects/swarm-data/traefik/logs/
|
|
||||||
```
|
|
||||||
|
|
||||||
**Verify acquisition:**
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics show acquisition'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Restart CrowdSec:**
|
|
||||||
```bash
|
|
||||||
docker service update --force crowdsec_crowdsec
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bouncer Not Blocking
|
|
||||||
|
|
||||||
**Check bouncer is registered:**
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli bouncers list'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Verify API key in Traefik config:**
|
|
||||||
```bash
|
|
||||||
cat /home/doc/projects/homelab/frostlabs/traefik/dynamic.yml | grep -A 5 crowdseclapikey
|
|
||||||
```
|
|
||||||
|
|
||||||
**Check Traefik can reach CrowdSec:**
|
|
||||||
```bash
|
|
||||||
docker service logs traefik_traefik --tail 50 | grep -i crowdsec
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Decision That Would Block You
|
|
||||||
|
|
||||||
**Test if an IP is banned:**
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions list --ip <your_ip>'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Whitelist your IP permanently:**
|
|
||||||
|
|
||||||
Edit `/home/doc/projects/homelab/frostlabs/crowdsec/acquis.yaml` and add to CrowdSec config:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create whitelist file
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) sh -c "echo \"name: crowdsecurity/whitelists
|
|
||||||
description: Whitelist trusted IPs
|
|
||||||
whitelist:
|
|
||||||
reason: trusted network
|
|
||||||
ip:
|
|
||||||
- 10.0.1.0/24
|
|
||||||
- 10.0.4.0/24
|
|
||||||
- <your_public_ip>
|
|
||||||
cidr:
|
|
||||||
- 10.0.0.0/8
|
|
||||||
\" > /etc/crowdsec/parsers/s02-enrich/whitelists.yaml"'
|
|
||||||
|
|
||||||
# Reload CrowdSec
|
|
||||||
docker service update --force crowdsec_crowdsec
|
|
||||||
```
|
|
||||||
|
|
||||||
### Performance Issues
|
|
||||||
|
|
||||||
**Check resource usage:**
|
|
||||||
```bash
|
|
||||||
docker stats $(docker ps -qf name=crowdsec_crowdsec)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Reduce log verbosity in static.yml:**
|
|
||||||
```yaml
|
|
||||||
log:
|
|
||||||
level: ERROR # Change from INFO
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reset CrowdSec Completely
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Remove all decisions
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions delete --all'
|
|
||||||
|
|
||||||
# Remove CrowdSec data
|
|
||||||
rm -rf /home/doc/projects/swarm-data/crowdsec/*
|
|
||||||
|
|
||||||
# Redeploy
|
|
||||||
cd /home/doc/projects/homelab/frostlabs/crowdsec
|
|
||||||
docker stack rm crowdsec
|
|
||||||
sleep 10
|
|
||||||
docker stack deploy -c stack.yml crowdsec
|
|
||||||
|
|
||||||
# Regenerate bouncer key (wait 30 seconds first)
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli bouncers add traefik-bouncer'
|
|
||||||
|
|
||||||
# Update API key in /home/doc/projects/homelab/frostlabs/traefik/dynamic.yml
|
|
||||||
# Then redeploy Traefik
|
|
||||||
docker stack deploy -c stack.yml traefik
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration Files
|
|
||||||
|
|
||||||
**Location:** `/home/doc/projects/homelab/frostlabs/crowdsec/`
|
|
||||||
|
|
||||||
- `stack.yml` - Docker Swarm service definition
|
|
||||||
- `acquis.yaml` - Log sources configuration
|
|
||||||
|
|
||||||
**Persistent Data:** `/home/doc/projects/swarm-data/crowdsec/`
|
|
||||||
|
|
||||||
- `config/` - CrowdSec configuration
|
|
||||||
- `data/` - Decision database and state
|
|
||||||
|
|
||||||
**Traefik Logs:** `/home/doc/projects/swarm-data/traefik/logs/`
|
|
||||||
|
|
||||||
- `access.log` - Analyzed by CrowdSec
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
1. **Start Conservative:** Monitor alerts before enabling aggressive scenarios
|
|
||||||
2. **Whitelist Trusted IPs:** Add your networks to `clientTrustedIPs` in dynamic.yml
|
|
||||||
3. **Test Changes:** Use `cscli decisions add` to test bans before deploying
|
|
||||||
4. **Monitor Metrics:** Regularly check `cscli metrics` to understand what's being blocked
|
|
||||||
5. **Update Regularly:** Keep collections updated with `cscli hub update && cscli hub upgrade`
|
|
||||||
6. **Enable Console:** Enroll for community protection and centralized management
|
|
||||||
7. **Apply Selectively:** Not all services need CrowdSec - use for public-facing services
|
|
||||||
8. **Combine Layers:** Use with authentik for authentication and rate-limit for additional protection
|
|
||||||
|
|
||||||
## Support & Resources
|
|
||||||
|
|
||||||
- **CrowdSec Documentation:** https://docs.crowdsec.net/
|
|
||||||
- **Hub (Collections/Scenarios):** https://hub.crowdsec.net/
|
|
||||||
- **Community Forum:** https://discourse.crowdsec.net/
|
|
||||||
- **Traefik Bouncer Plugin:** https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
|
||||||
|
|
||||||
## Maintenance Tasks
|
|
||||||
|
|
||||||
### Weekly
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check for new threats
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli alerts list | head -20'
|
|
||||||
|
|
||||||
# Review metrics
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Monthly
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Update hub
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli hub update'
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli hub upgrade'
|
|
||||||
|
|
||||||
# Update Docker images
|
|
||||||
docker service update --image crowdsecurity/crowdsec:latest crowdsec_crowdsec
|
|
||||||
docker service update --image traefik:latest traefik_traefik
|
|
||||||
```
|
|
||||||
|
|
||||||
### Quarterly
|
|
||||||
|
|
||||||
- Review and tune scenarios based on false positives
|
|
||||||
- Audit whitelisted IPs
|
|
||||||
- Check for new relevant collections
|
|
||||||
- Review ban durations in scenarios
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
# CrowdSec Quick Reference Card
|
|
||||||
|
|
||||||
## Setup Alias (Recommended)
|
|
||||||
|
|
||||||
Add to your `~/.bashrc`:
|
|
||||||
```bash
|
|
||||||
alias cscli='ssh 10.0.4.14 "docker exec \$(docker ps -qf name=crowdsec_crowdsec) cscli"'
|
|
||||||
```
|
|
||||||
|
|
||||||
Then use: `cscli decisions list` instead of the full command.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Most Common Commands
|
|
||||||
|
|
||||||
### View Active Bans
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions list'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ban an IP for 4 Hours
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions add --ip 1.2.3.4 --duration 4h'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Unban an IP
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions delete --ip 1.2.3.4'
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Recent Alerts (What Triggered Bans)
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli alerts list'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Status & Metrics
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verify Bouncer Connected
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli bouncers list'
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Installed Collections
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli collections list'
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Traefik Access Logs
|
|
||||||
```bash
|
|
||||||
tail -f /home/doc/projects/swarm-data/traefik/logs/access.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### View CrowdSec Logs
|
|
||||||
```bash
|
|
||||||
docker service logs crowdsec_crowdsec --tail 50 --follow
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Add Protection to a Service
|
|
||||||
|
|
||||||
### Docker Swarm Service (via labels)
|
|
||||||
```yaml
|
|
||||||
deploy:
|
|
||||||
labels:
|
|
||||||
- "traefik.http.routers.myapp.middlewares=crowdsec@file"
|
|
||||||
```
|
|
||||||
|
|
||||||
### External Service (in dynamic.yml)
|
|
||||||
```yaml
|
|
||||||
http:
|
|
||||||
routers:
|
|
||||||
myservice:
|
|
||||||
middlewares:
|
|
||||||
- crowdsec
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Restart CrowdSec
|
|
||||||
```bash
|
|
||||||
docker service update --force crowdsec_crowdsec
|
|
||||||
```
|
|
||||||
|
|
||||||
### Restart Traefik
|
|
||||||
```bash
|
|
||||||
docker service update --force traefik_traefik
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check if Logs Are Being Read
|
|
||||||
```bash
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli metrics show acquisition'
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Service Status
|
|
||||||
```bash
|
|
||||||
docker service ls | grep -E "crowdsec|traefik"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## File Locations
|
|
||||||
|
|
||||||
| Purpose | Path |
|
|
||||||
|---------|------|
|
|
||||||
| CrowdSec Stack | `/home/doc/projects/homelab/frostlabs/crowdsec/stack.yml` |
|
|
||||||
| Log Config | `/home/doc/projects/homelab/frostlabs/crowdsec/acquis.yaml` |
|
|
||||||
| Traefik Config | `/home/doc/projects/homelab/frostlabs/traefik/dynamic.yml` |
|
|
||||||
| Access Logs | `/home/doc/projects/swarm-data/traefik/logs/access.log` |
|
|
||||||
| CrowdSec Data | `/home/doc/projects/swarm-data/crowdsec/` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Emergency: I Locked Myself Out
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Delete all bans
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions delete --all'
|
|
||||||
|
|
||||||
# Or unban specific IP
|
|
||||||
ssh 10.0.4.14 'docker exec $(docker ps -qf name=crowdsec_crowdsec) cscli decisions delete --ip YOUR.IP.HERE'
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
For detailed information, see: `/home/doc/projects/homelab/frostlabs/crowdsec/GUIDE.md`
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
services:
|
|
||||||
crowdsec:
|
|
||||||
image: crowdsecurity/crowdsec:latest
|
|
||||||
environment:
|
|
||||||
# Disable online API enrollment (use for local setup)
|
|
||||||
- DISABLE_ONLINE_API=false
|
|
||||||
# Set collections to install
|
|
||||||
- COLLECTIONS=crowdsecurity/traefik crowdsecurity/http-cve
|
|
||||||
# Enable Prometheus metrics
|
|
||||||
- METRICS_PORT=6060
|
|
||||||
volumes:
|
|
||||||
# Persistent CrowdSec configuration and data
|
|
||||||
- /home/doc/projects/swarm-data/crowdsec/config:/etc/crowdsec
|
|
||||||
- /home/doc/projects/swarm-data/crowdsec/data:/var/lib/crowdsec/data
|
|
||||||
# Traefik access logs (read-only)
|
|
||||||
- /home/doc/projects/swarm-data/traefik/logs:/var/log/traefik:ro
|
|
||||||
# Acquis configuration
|
|
||||||
- ./acquis.yaml:/etc/crowdsec/acquis.yaml:ro
|
|
||||||
networks:
|
|
||||||
- frostlabs
|
|
||||||
deploy:
|
|
||||||
mode: replicated
|
|
||||||
replicas: 1
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.labels.task == control
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 5s
|
|
||||||
max_attempts: 3
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "cscli", "version"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 60s
|
|
||||||
|
|
||||||
networks:
|
|
||||||
frostlabs:
|
|
||||||
external: true
|
|
||||||
25
dozzle/stack.yml
Normal file
25
dozzle/stack.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
services:
|
||||||
|
dozzle:
|
||||||
|
image: amir20/dozzle:latest
|
||||||
|
environment:
|
||||||
|
- DOZZLE_MODE=swarm
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
deploy:
|
||||||
|
mode: global
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.swarm.network=frostlabs"
|
||||||
|
- "traefik.http.routers.dozzle.rule=Host(`logs.frostlabs.me`)"
|
||||||
|
- "traefik.http.routers.dozzle.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.dozzle.middlewares=authentik@file"
|
||||||
|
- "traefik.http.routers.dozzle.tls=true"
|
||||||
|
- "traefik.http.routers.dozzle.tls.certresolver=cloudflare"
|
||||||
|
- "traefik.http.services.dozzle.loadbalancer.server.port=8080"
|
||||||
|
networks:
|
||||||
|
frostlabs:
|
||||||
|
external: true
|
||||||
40
netdata/stack.yml
Normal file
40
netdata/stack.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
services:
|
||||||
|
netdata:
|
||||||
|
image: netdata/netdata:stable
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
cap_add:
|
||||||
|
- SYS_PTRACE
|
||||||
|
- SYS_ADMIN
|
||||||
|
ports:
|
||||||
|
- 19999:19999
|
||||||
|
volumes:
|
||||||
|
- netdataconfig:/etc/netdata
|
||||||
|
- netdatalib:/var/lib/netdata
|
||||||
|
- netdatacache:/var/cache/netdata
|
||||||
|
- /:/host/root:ro,rslave
|
||||||
|
- /etc/passwd:/host/etc/passwd:ro
|
||||||
|
- /etc/group:/host/etc/group:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /proc:/host/proc:ro
|
||||||
|
- /sys:/host/sys:ro
|
||||||
|
- /etc/os-release:/host/etc/os-release:ro
|
||||||
|
- /etc/hostname:/etc/hostname:ro
|
||||||
|
- /var/log:/host/var/log:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- /run/dbus:/run/dbus:ro
|
||||||
|
environment:
|
||||||
|
- NETDATA_CLAIM_TOKEN=QGvNtvYVjfMl2chb0jfqID9kEvKMpxkALxeXm-ukHKvTdSbvKwo7w1gwTYvRyzFl9sZs9aL0y0K-1uTVwh3COJxFBwhDgMQX3FfCEsnIX7gjRCcJZZNwV73NvrHfZglZlmOrPfM
|
||||||
|
- NETDATA_CLAIM_URL=https://app.netdata.cloud
|
||||||
|
- NETDATA_CLAIM_ROOMS=d4076c5b-a35f-4564-bf7b-9f67e8374a26
|
||||||
|
deploy:
|
||||||
|
mode: global
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
volumes:
|
||||||
|
netdataconfig:
|
||||||
|
netdatalib:
|
||||||
|
netdatacache:
|
||||||
|
networks:
|
||||||
|
frostlabs:
|
||||||
|
external: true
|
||||||
117
peertube/stack.yml
Normal file
117
peertube/stack.yml
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
services:
|
||||||
|
peertube:
|
||||||
|
image: chocobozzz/peertube:production-bookworm
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
environment:
|
||||||
|
# Database configuration - connecting to existing Postgres
|
||||||
|
- POSTGRES_USER=admin
|
||||||
|
- POSTGRES_PASSWORD=AllOfTheStars+1
|
||||||
|
- POSTGRES_DB=peertube
|
||||||
|
- POSTGRES_HOSTNAME=postgres
|
||||||
|
- POSTGRES_PORT=5432
|
||||||
|
- PEERTUBE_DB_HOSTNAME=postgres
|
||||||
|
- PEERTUBE_DB_PORT=5432
|
||||||
|
- PEERTUBE_DB_USERNAME=admin
|
||||||
|
- PEERTUBE_DB_PASSWORD=AllOfTheStars+1
|
||||||
|
- PEERTUBE_DB_NAME=peertube
|
||||||
|
# Redis configuration
|
||||||
|
- REDIS_HOSTNAME=redis
|
||||||
|
- PEERTUBE_REDIS_HOSTNAME=redis
|
||||||
|
# PeerTube configuration
|
||||||
|
- PEERTUBE_WEBSERVER_HOSTNAME=videos.frostlabs.me
|
||||||
|
- PEERTUBE_WEBSERVER_PORT=443
|
||||||
|
- PEERTUBE_WEBSERVER_HTTPS=true
|
||||||
|
- PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback", "10.0.1.0/24"]
|
||||||
|
# SMTP configuration - Gmail
|
||||||
|
- PEERTUBE_SMTP_HOSTNAME=smtp.gmail.com
|
||||||
|
- PEERTUBE_SMTP_PORT=587
|
||||||
|
- PEERTUBE_SMTP_USERNAME=frostlabs25@gmail.com
|
||||||
|
- PEERTUBE_SMTP_PASSWORD=tewo awqe ffhw rtun
|
||||||
|
- PEERTUBE_SMTP_FROM=frostlabs25@gmail.com
|
||||||
|
- PEERTUBE_SMTP_TLS=true
|
||||||
|
- PEERTUBE_SMTP_DISABLE_STARTTLS=false
|
||||||
|
- PEERTUBE_ADMIN_EMAIL=frostlabs25@gmail.com
|
||||||
|
# Secrets - loaded from Docker secrets as files
|
||||||
|
- PEERTUBE_SECRET=dfd1cad851c1a5b795131fd2033d46ef80c809b5ac30a3ce8e69b049587138a2
|
||||||
|
# secrets:
|
||||||
|
# - postgres-master
|
||||||
|
# - peertube-key
|
||||||
|
# - gmail-app-password
|
||||||
|
# ports:
|
||||||
|
# - target: 9000
|
||||||
|
# published: 9000
|
||||||
|
# mode: host
|
||||||
|
# - target: 1935
|
||||||
|
# published: 1935
|
||||||
|
# mode: host
|
||||||
|
volumes:
|
||||||
|
# - /home/doc/projects/swarm-data/appdata/peertube/assets:/app/client/dist
|
||||||
|
- /home/doc/projects/swarm-data/peertube/data:/data
|
||||||
|
# healthcheck:
|
||||||
|
# test: [ "CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9000/api/v1/config" ]
|
||||||
|
# interval: 30s
|
||||||
|
# timeout: 10s
|
||||||
|
# retries: 3
|
||||||
|
# start_period: 60s
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.labels.task == compute
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.peertube.rule=Host(`videos.frostlabs.me`)
|
||||||
|
- traefik.http.routers.peertube.entrypoints=websecure
|
||||||
|
- traefik.http.routers.peertube.tls=true
|
||||||
|
- traefik.http.routers.peertube.tls.certresolver=cloudflare
|
||||||
|
- traefik.http.services.peertube.loadbalancer.server.port=9000
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
volumes:
|
||||||
|
- /home/doc/projects/swarm-data/peertube/redis:/data
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "redis-cli", "ping" ]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.labels.task == control
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:17-alpine
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=admin
|
||||||
|
- POSTGRES_PASSWORD=AllOfTheStars+1
|
||||||
|
- POSTGRES_DB=peertube
|
||||||
|
volumes:
|
||||||
|
- /home/doc/projects/swarm-data/peertube/postgres:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.labels.task == control
|
||||||
|
|
||||||
|
networks:
|
||||||
|
frostlabs:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
# secrets:
|
||||||
|
# postgres-master:
|
||||||
|
# external: true
|
||||||
|
# peertube-key:
|
||||||
|
# external: true
|
||||||
|
# gmail-app-password:
|
||||||
|
# external: true
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
services:
|
|
||||||
portainer:
|
|
||||||
image: portainer/portainer-ce:latest
|
|
||||||
command: -H tcp://tasks.agent:9001 --tlsskipverify
|
|
||||||
volumes:
|
|
||||||
- /home/doc/projects/swarm-data/portainer:/data
|
|
||||||
networks:
|
|
||||||
- frostlabs
|
|
||||||
ports:
|
|
||||||
- 9000:9000
|
|
||||||
deploy:
|
|
||||||
mode: replicated
|
|
||||||
replicas: 1
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.labels.task == control
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.swarm.network=frostlabs"
|
|
||||||
- "traefik.http.routers.portainer.rule=Host(`portainer.frostlabs.me`)"
|
|
||||||
- "traefik.http.routers.portainer.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.portainer.tls=true"
|
|
||||||
- "traefik.http.routers.portainer.tls.certresolver=cloudflare"
|
|
||||||
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
|
|
||||||
|
|
||||||
agent:
|
|
||||||
image: portainer/agent:latest
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- /var/lib/docker/volumes:/var/lib/docker/volumes
|
|
||||||
networks:
|
|
||||||
- frostlabs
|
|
||||||
deploy:
|
|
||||||
mode: global
|
|
||||||
|
|
||||||
networks:
|
|
||||||
frostlabs:
|
|
||||||
external: true
|
|
||||||
@@ -9,12 +9,12 @@ services:
|
|||||||
- /home/doc/projects/swarm-data/webservers/production/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
- /home/doc/projects/swarm-data/webservers/production/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
- /home/doc/projects/swarm-data/webservers/production/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
- /home/doc/projects/swarm-data/webservers/production/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
- /home/doc/projects/swarm-data/webfiles/production/taylors-development:/usr/share/nginx/html:ro
|
- /home/doc/projects/swarm-data/webfiles/production/taylors-development:/usr/share/nginx/html:ro
|
||||||
healthcheck:
|
# healthcheck:
|
||||||
test: [ "CMD-SHELL", "curl -f http://localhost:80 || exit 1" ]
|
# test: [ "CMD-SHELL", "curl -f http://localhost:80 || exit 1" ]
|
||||||
interval: 30s
|
# interval: 30s
|
||||||
timeout: 5s
|
# timeout: 5s
|
||||||
retries: 3
|
# retries: 3
|
||||||
start_period: 10s
|
# start_period: 10s
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
placement:
|
placement:
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
services:
|
|
||||||
traefik:
|
|
||||||
image: traefik:v3.6.1
|
|
||||||
ports:
|
|
||||||
- 80:80
|
|
||||||
- 443:443
|
|
||||||
- 8082:8080
|
|
||||||
environment:
|
|
||||||
- CF_DNS_API_TOKEN_FILE=/run/secrets/cloudflare_api_token
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- ./static.yml:/etc/traefik/traefik.yml:ro
|
|
||||||
- ./dynamic.yml:/etc/traefik/dynamic/dynamic.yml:ro
|
|
||||||
- /home/doc/projects/swarm-data/traefik/certificates:/certificates
|
|
||||||
- /home/doc/projects/swarm-data/traefik/logs:/var/log/traefik
|
|
||||||
secrets:
|
|
||||||
- cloudflare_api_token
|
|
||||||
networks:
|
|
||||||
- frostlabs
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/ping" ]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
start_period: 30s
|
|
||||||
deploy:
|
|
||||||
mode: replicated
|
|
||||||
replicas: 1
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.labels.task == control
|
|
||||||
|
|
||||||
crowdsec:
|
|
||||||
image: crowdsecurity/crowdsec:latest
|
|
||||||
environment:
|
|
||||||
# Disable online API enrollment (use for local setup)
|
|
||||||
- DISABLE_ONLINE_API=false
|
|
||||||
# Set collections to install
|
|
||||||
- COLLECTIONS=crowdsecurity/traefik crowdsecurity/http-cve
|
|
||||||
# Enable Prometheus metrics
|
|
||||||
- METRICS_PORT=6060
|
|
||||||
volumes:
|
|
||||||
# Persistent CrowdSec configuration and data
|
|
||||||
- /home/doc/projects/swarm-data/crowdsec/config:/etc/crowdsec
|
|
||||||
- /home/doc/projects/swarm-data/crowdsec/data:/var/lib/crowdsec/data
|
|
||||||
# Traefik access logs (read-only)
|
|
||||||
- /home/doc/projects/swarm-data/traefik/logs:/var/log/traefik:ro
|
|
||||||
# Acquis configuration
|
|
||||||
- ./acquis.yaml:/etc/crowdsec/acquis.yaml:ro
|
|
||||||
networks:
|
|
||||||
- frostlabs
|
|
||||||
deploy:
|
|
||||||
mode: replicated
|
|
||||||
replicas: 1
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.labels.task == control
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 5s
|
|
||||||
max_attempts: 3
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "cscli", "version" ]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 60s
|
|
||||||
|
|
||||||
networks:
|
|
||||||
frostlabs:
|
|
||||||
external: true
|
|
||||||
|
|
||||||
secrets:
|
|
||||||
cloudflare_api_token:
|
|
||||||
external: true
|
|
||||||
52
wiki/stack.yml
Normal file
52
wiki/stack.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
services:
|
||||||
|
wiki:
|
||||||
|
image: ghcr.io/requarks/wiki:2
|
||||||
|
secrets:
|
||||||
|
- postgres-master
|
||||||
|
entrypoint: [ "/bin/sh", "-c" ]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
export DB_PASS=$$(cat /run/secrets/postgres-master)
|
||||||
|
node server
|
||||||
|
environment:
|
||||||
|
DB_TYPE: postgres
|
||||||
|
DB_HOST: 10.0.4.10
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_USER: admin
|
||||||
|
DB_NAME: wiki
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
networks:
|
||||||
|
- frostlabs
|
||||||
|
volumes:
|
||||||
|
- /home/doc/projects/swarm-data/wiki/config:/config
|
||||||
|
- /home/doc/projects/swarm-data/wiki/data:/data
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.labels.task == compute
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
delay: 5s
|
||||||
|
max_attempts: 3
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 2G
|
||||||
|
reservations:
|
||||||
|
memory: 512M
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.swarm.network=frostlabs
|
||||||
|
- traefik.http.routers.wiki.rule=Host(`wiki.frostlabs.me`)
|
||||||
|
- traefik.http.routers.wiki.entrypoints=websecure
|
||||||
|
- traefik.http.routers.wiki.tls=true
|
||||||
|
- traefik.http.routers.wiki.tls.certresolver=cloudflare
|
||||||
|
- traefik.http.services.wiki.loadbalancer.server.port=3000
|
||||||
|
networks:
|
||||||
|
frostlabs:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
postgres-master:
|
||||||
|
external: true
|
||||||
Reference in New Issue
Block a user