Compare commits

..

33 Commits

Author SHA1 Message Date
John
a0271a88ef updated readme 2025-11-29 17:23:31 +00:00
John
e92389a44a moved authentik to core stack 2025-11-29 17:11:00 +00:00
John
40b0d23f57 Netdata Deployed to Production 2025-11-24 20:14:41 +00:00
John
5a20b9809c disabled service: Crowdsec 2025-11-24 18:47:32 +00:00
John
bbfc5843d8 applying fix #3 to middlewares 2025-11-24 13:56:15 +00:00
John
39c368ebd5 applying fix attempt #2 to middlewares 2025-11-24 13:22:55 +00:00
John
98ea915ce8 applying fix attempt #1 to middleware 2025-11-24 13:20:51 +00:00
John
dfa81b3396 added authentik middleware 2025-11-24 13:17:58 +00:00
John
5938bd3cdd Dozzle Deployed to Production 2025-11-24 11:51:22 +00:00
John
3050f28460 Wiki.js Deployed to Production 2025-11-21 18:49:56 +00:00
John
51187de49a 2025-11-17 23:23:44 +00:00
John
fad38a229f Moved config to core 2025-11-17 23:22:55 +00:00
John
72a9f0ae54 2025-11-16 18:12:32 -05:00
John
bdac46a6c0 2025-11-16 18:08:07 -05:00
John
82bf22006d 2025-11-16 18:07:09 -05:00
John
45235aafe5 2025-11-16 17:40:30 -05:00
John
6fc47a50a2 2025-11-16 17:40:02 -05:00
John
3e9fa63083 2025-11-16 17:38:56 -05:00
John
cc3ab19e53 2025-11-16 17:37:44 -05:00
John
96ccb78c5c 2025-11-16 17:36:22 -05:00
John
72c0a68836 2025-11-16 17:26:36 -05:00
John
fae1e7f227 2025-11-16 17:25:42 -05:00
John
f474ea3484 2025-11-16 17:23:21 -05:00
John
2279f8cf4b 2025-11-16 17:22:35 -05:00
John
10b98f1dba UPDATE: 2025-16-11 2025-11-16 17:21:58 -05:00
John
60c5158267 UPDATE: 2025-16-11 2025-11-16 17:09:35 -05:00
John
f6f110d964 Added Readme file. 2025-11-16 16:40:09 -05:00
John
ff9934a0c7 PeerTube Deployed to Production 2025-11-16 15:47:54 -05:00
John
f76a07ea8b Update Fix Issue #1: Commented out health check config instead of removing. 2025-11-16 15:31:56 -05:00
John
35c19dcd49 TEMP Fix Issue #1: Removed Tracker app's Healthcheck section. 2025-11-16 15:29:21 -05:00
John
20feed2b30 Deployed Core to Production 2025-11-16 15:20:16 -05:00
John
c353bb1c78 Update gitignore 2025-11-16 15:19:38 -05:00
John
f50667712d Moved to core stack 2025-11-16 15:19:26 -05:00
13 changed files with 1035 additions and 771 deletions

5
.gitignore vendored
View File

@@ -1,4 +1,5 @@
traefik/dynamic.yml
traefik/static.yml
core/dynamic.yml
core/static.yml
crowdsec/acquis.yaml
traefik/acquis.yaml
core/acquis.yaml

686
README.md Normal file
View 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`*

View File

@@ -1,4 +1,105 @@
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:
image: redis:alpine
command: --save 60 1 --loglevel warning
@@ -109,11 +210,15 @@ services:
memory: 512M
depends_on:
- redis
networks:
frostlabs:
external: true
secrets:
postgres-master:
cloudflare_api_token:
external: true
auth-key:
external: true
postgres-master:
external: true

View File

@@ -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

View File

@@ -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`

View File

@@ -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
View 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
View 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
View 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

View File

@@ -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

View File

@@ -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/default.conf:/etc/nginx/conf.d/default.conf:ro
- /home/doc/projects/swarm-data/webfiles/production/taylors-development:/usr/share/nginx/html:ro
healthcheck:
test: [ "CMD-SHELL", "curl -f http://localhost:80 || exit 1" ]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
# healthcheck:
# test: [ "CMD-SHELL", "curl -f http://localhost:80 || exit 1" ]
# interval: 30s
# timeout: 5s
# retries: 3
# start_period: 10s
deploy:
replicas: 1
placement:

View File

@@ -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
View 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