Repository navigation
Expand file tree
/
Copy pathdocker-compose.yaml
More file actions
67 lines (65 loc) · 3.62 KB
/
Copy pathdocker-compose.yaml
File metadata and controls
67 lines (65 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# ── PRODUCTION / OFFLINE RUNTIME ─────────────────────────────────────────────
# Uses a pre-built image. No internet access required.
# The image must be loaded first:
# docker load -i watchdog.tar
#
# Usage:
# cp .env.example .env # fill in SLACK_WEBHOOK_URL and any other channel secrets
# docker compose up -d
#
# To build a new image (requires internet):
# docker compose -f docker-compose.build.yaml build
# ─────────────────────────────────────────────────────────────────────────────
services:
# ── Watchdog Agent ──────────────────────────────────────────────────────────
docker-container-watchdog:
# Pinned to the release in WATCHDOG_VERSION (written to .env by install.sh)
# so an upgrade cannot keep running a stale image that still answers to
# :latest. Falls back to :latest for manual, unversioned installs.
image: watchdog:${WATCHDOG_VERSION:-latest}
container_name: docker-container-watchdog
restart: always # always restart — watchdog must never stay down
network_mode: host # must reach all container IPs across all Docker networks
env_file: .env
environment:
WATCHDOG_CONFIG: /etc/watchdog/watchdog-config.yaml
# install.sh writes the operator's answer to .env; this is only the default.
WATCHDOG_HOST: ${WATCHDOG_HOST:-CyberController-Server}
volumes:
# Read Docker socket to monitor all containers on the host
- /var/run/docker.sock:/var/run/docker.sock:ro
# Config file (read-only mount)
- ./watchdog-config.yaml:/etc/watchdog/watchdog-config.yaml:ro
# watchdog.py is deliberately NOT bind-mounted: this container holds the
# Docker socket, so write access to the host copy would be host root.
# Code ships inside the image — rebuild to pick up changes.
# Persistent log storage — written directly to host folder
- ./watchdog:/var/log/watchdog
# ── Hardening ────────────────────────────────────────────────────────────
# Defaults to root (0:0) for zero-config manual installs — the socket is
# host-root-equivalent for any user anyway. install.sh instead populates
# WATCHDOG_UID/WATCHDOG_GID/DOCKER_GID in .env to run this non-root.
user: "${WATCHDOG_UID:-0}:${WATCHDOG_GID:-0}"
group_add:
- "${DOCKER_GID:-0}"
read_only: true # immutable root filesystem
tmpfs:
- /tmp
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
# ── Resource limits — contain a leak/runaway to this container, not the host ─
mem_limit: 256m
mem_reservation: 128m
memswap_limit: 256m # no swap beyond mem_limit — hits the limit and restarts instead of degrading the host
# must stay >= mem_limit if you raise it, or Docker rejects this config
mem_swappiness: 0 # avoid swapping this container's pages — needed when host kernel lacks swap accounting (memswap_limit is then unenforceable)
cpus: "0.50"
pids_limit: 200
healthcheck:
test: ["CMD", "python3", "-c", "import docker; docker.from_env().ping()"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s