DaemonEye Docker Deployment#
Guide
This guide provides comprehensive instructions for deploying
DaemonEye using Docker and Docker Compose, including containerization,
orchestration, and production deployment strategies.
Table of Contents#
[TOC]
Docker Overview#
DaemonEye is designed to run efficiently in containerized
environments, providing:
- Isolation: Process monitoring within container
boundaries - Scalability: Easy horizontal scaling and load
balancing - Portability: Consistent deployment across different
environments - Security: Container-based privilege isolation
- Orchestration: Integration with Kubernetes and
other orchestration platforms
Container Architecture#
DaemonEye uses a multi-container architecture:
- procmond: Privileged process monitoring daemon
- daemoneye-agent: User-space orchestrator and
alerting - daemoneye-cli: Command-line interface and
management
Container Images#
NOTE: Docker images are not yet published. Official
Docker images are planned for future releases. For now, please build
DaemonEye from source (see Building from
Source below).
Planned Official Images#
The following Docker images are planned but not yet available:
Core Images (Aspirational):
# Process monitoring daemondocker pull daemoneye/procmond:latestdocker pull daemoneye/procmond:1.0.0# Agent orchestratordocker pull daemoneye/daemoneye-agent:latestdocker pull daemoneye/daemoneye-agent:1.0.0# CLI interfacedocker pull daemoneye/daemoneye-cli:latestdocker pull daemoneye/daemoneye-cli:1.0.0
Planned Image Tags:
latest: Latest stable release1.0.0: Specific version1.0.0-alpine: Alpine Linux variant (smaller size)1.0.0-debian: Debian-based variantdev: Development buildsrc-1.0.0: Release candidate
Image Variants#
Alpine Linux (Recommended):
# Smaller size, security-focusedFROM alpine:3.18RUNapk add --no-cache ca-certificatesCOPY procmond /usr/local/bin/ENTRYPOINT ["procmond"]
Debian:
# Full-featured, larger sizeFROM debian:bookworm-slimRUNapt-get update &&apt-get install -y ca-certificates &&rm-rf /var/lib/apt/lists/*COPY procmond /usr/local/bin/ENTRYPOINT ["procmond"]
Distroless:
# Minimal attack surfaceFROM gcr.io/distroless/cc-debian12COPY procmond /usr/local/bin/ENTRYPOINT ["procmond"]
Building from Source#
Since official Docker images are not yet available, you can build
DaemonEye images from the source repository:
Clone the Repository#
git clone https://github.com/EvilBit-Labs/DaemonEye.gitcd DaemonEye
Build with Multi-Stage#
Dockerfile
Create a Dockerfile in the repository root:
# Build stageFROM rust:1.91-bookworm AS builderWORKDIR /appCOPY . .RUNcargo build --release--bin procmondRUNcargo build --release--bin daemoneye-agentRUNcargo build --release--bin daemoneye-cli# Runtime stage - procmondFROM debian:bookworm-slim AS procmond-runtimeRUNapt-get update &&apt-get install -y ca-certificates &&rm-rf /var/lib/apt/lists/*COPY--from=builder /app/target/release/procmond /usr/local/bin/procmondENTRYPOINT ["procmond"]# Runtime stage - daemoneye-agentFROM debian:bookworm-slim AS agent-runtimeRUNapt-get update &&apt-get install -y ca-certificates &&rm-rf /var/lib/apt/lists/*COPY--from=builder /app/target/release/daemoneye-agent /usr/local/bin/daemoneye-agentENTRYPOINT ["daemoneye-agent"]# Runtime stage - daemoneye-cliFROM debian:bookworm-slim AS cli-runtimeRUNapt-get update &&apt-get install -y ca-certificates &&rm-rf /var/lib/apt/lists/*COPY--from=builder /app/target/release/daemoneye-cli /usr/local/bin/daemoneye-cliENTRYPOINT ["daemoneye-cli"]
Build Images Locally#
# Build procmond imagedocker build -t daemoneye/procmond:latest \--target procmond-runtime \ .# Build daemoneye-agent image (similar approach with different binary)docker build -t daemoneye/daemoneye-agent:latest \--target agent-runtime \ .# Build daemoneye-cli imagedocker build -t daemoneye/daemoneye-cli:latest \--target cli-runtime \ .
Tag Versions#
docker tag daemoneye/procmond:latest daemoneye/procmond:1.0.0docker tag daemoneye/daemoneye-agent:latest daemoneye/daemoneye-agent:1.0.0docker tag daemoneye/daemoneye-cli:latest daemoneye/daemoneye-cli:1.0.0
Verify Built Images#
# List all built DaemonEye imagesdocker images daemoneye/*# Verify each image runs and reports its versiondocker run --rm daemoneye/procmond:latest --versiondocker run --rm daemoneye/daemoneye-agent:latest --versiondocker run --rm daemoneye/daemoneye-cli:latest --version# Inspect image metadata (architecture, size, layers)docker inspect daemoneye/procmond:latestdocker inspect daemoneye/daemoneye-agent:latestdocker inspect daemoneye/daemoneye-cli:latest
Basic Docker Deployment#
Note: The examples below assume Docker images are
available. Until official images are published, build images locally
from source (see Building from
Source above).
Single Container Deployment#
Run Process Monitor:
# Basic rundocker run -d\--name daemoneye-procmond \--privileged\-v /var/lib/daemoneye:/data \-v /var/log/daemoneye:/logs \ daemoneye/procmond:latest# With custom configurationdocker run -d\--name daemoneye-procmond \--privileged\-v /etc/daemoneye:/config \-v /var/lib/daemoneye:/data \-v /var/log/daemoneye:/logs \-e DaemonEye_LOG_LEVEL=info \ daemoneye/procmond:latest --config /config/config.yaml
Run Agent:
# Basic rundocker run -d\--name daemoneye-agent \--link daemoneye-procmond:procmond \-v /var/lib/daemoneye:/data \-v /var/log/daemoneye:/logs \ daemoneye/daemoneye-agent:latest# With custom configurationdocker run -d\--name daemoneye-agent \--link daemoneye-procmond:procmond \-v /etc/daemoneye:/config \-v /var/lib/daemoneye:/data \-v /var/log/daemoneye:/logs \-e DaemonEye_LOG_LEVEL=info \ daemoneye/daemoneye-agent:latest --config /config/config.yaml
Run CLI:
# Interactive CLIdocker run -it\--rm\--link daemoneye-agent:agent \-v /var/lib/daemoneye:/data \ daemoneye/daemoneye-cli:latest# Execute specific commanddocker run --rm\--link daemoneye-agent:agent \-v /var/lib/daemoneye:/data \ daemoneye/daemoneye-cli:latest query "SELECT * FROM processes LIMIT 10"
Multi-Container Deployment#
Create Network:
# Create custom networkdocker network create daemoneye-network# Run with custom networkdocker run -d\--name daemoneye-procmond \--network daemoneye-network \--privileged\-v /var/lib/daemoneye:/data \ daemoneye/procmond:latestdocker run -d\--name daemoneye-agent \--network daemoneye-network \-v /var/lib/daemoneye:/data \ daemoneye/daemoneye-agent:latest
Docker Compose Deployment#
Note: The examples below use Docker image names.
Until official images are published, update the image references to use
your locally-built images (e.g., change
daemoneye/procmond:latestto your local image
reference).
Basic Docker Compose#
docker-compose.yml:
version:'3.8'services:procmond:image: daemoneye/procmond:latestcontainer_name: daemoneye-procmondprivileged:truevolumes:- /var/lib/daemoneye:/data- /var/log/daemoneye:/logs- ./config:/config:roenvironment:- DaemonEye_LOG_LEVEL=info- DaemonEye_DATA_DIR=/data- DaemonEye_LOG_DIR=/logscommand:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkdaemoneye-agent:image: daemoneye/daemoneye-agent:latestcontainer_name: daemoneye-agentdepends_on:- procmondvolumes:- /var/lib/daemoneye:/data- /var/log/daemoneye:/logs- ./config:/config:roenvironment:- DaemonEye_LOG_LEVEL=info- DaemonEye_DATA_DIR=/data- DaemonEye_LOG_DIR=/logscommand:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkdaemoneye-cli:image: daemoneye/daemoneye-cli:latestcontainer_name: daemoneye-clidepends_on:- daemoneye-agentvolumes:- /var/lib/daemoneye:/data- ./config:/config:roenvironment:- DaemonEye_DATA_DIR=/datacommand:[--help]restart:nonetworks:- daemoneye-networknetworks:daemoneye-network:driver: bridgevolumes:daemoneye-data:driver: localdaemoneye-logs:driver: local
Production Docker Compose#
docker-compose.prod.yml:
version:'3.8'services:procmond:image: daemoneye/procmond:1.0.0container_name: daemoneye-procmondprivileged:trueuser: 1000:1000volumes:- daemoneye-data:/data- daemoneye-logs:/logs- ./config/procmond.yaml:/config/config.yaml:ro- ./rules:/rules:roenvironment:- DaemonEye_LOG_LEVEL=info- DaemonEye_DATA_DIR=/data- DaemonEye_LOG_DIR=/logs- DaemonEye_RULE_DIR=/rulescommand:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkhealthcheck:test:[CMD, procmond, health]interval: 30stimeout: 10sretries:3start_period: 40sdaemoneye-agent:image: daemoneye/daemoneye-agent:1.0.0container_name: daemoneye-agentdepends_on:procmond:condition: service_healthyuser: 1000:1000volumes:- daemoneye-data:/data- daemoneye-logs:/logs- ./config/daemoneye-agent.yaml:/config/config.yaml:roenvironment:- DaemonEye_LOG_LEVEL=info- DaemonEye_DATA_DIR=/data- DaemonEye_LOG_DIR=/logs- DaemonEye_PROCMOND_ENDPOINT=tcp://procmond:8080command:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkhealthcheck:test:[CMD, daemoneye-agent, health]interval: 30stimeout: 10sretries:3start_period: 40ssecurity-center:image: daemoneye/security-center:1.0.0container_name: daemoneye-security-centerdepends_on:daemoneye-agent:condition: service_healthyuser: 1000:1000volumes:- daemoneye-data:/data- ./config/security-center.yaml:/config/config.yaml:roenvironment:- DaemonEye_LOG_LEVEL=info- DaemonEye_DATA_DIR=/data- DaemonEye_AGENT_ENDPOINT=tcp://daemoneye-agent:8080- DaemonEye_WEB_PORT=8080command:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkports:- 8080:8080healthcheck:test:[CMD, curl, -f, http://localhost:8080/health]interval: 30stimeout: 10sretries:3start_period: 40snginx:image: nginx:alpinecontainer_name: daemoneye-nginxdepends_on:security-center:condition: service_healthyvolumes:- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro- ./nginx/ssl:/etc/nginx/ssl:roports:- 80:80- 443:443restart: unless-stoppednetworks:- daemoneye-networknetworks:daemoneye-network:driver: bridgeipam:config:-subnet: 172.20.0.0/16volumes:daemoneye-data:driver: localdaemoneye-logs:driver: local
Development Docker Compose#
docker-compose.dev.yml:
version:'3.8'services:procmond:build:context: .dockerfile: procmond/Dockerfilecontainer_name: daemoneye-procmond-devprivileged:truevolumes:- ./data:/data- ./logs:/logs- ./config:/config:ro- ./rules:/rules:roenvironment:- DaemonEye_LOG_LEVEL=debug- DaemonEye_DATA_DIR=/data- DaemonEye_LOG_DIR=/logs- DaemonEye_RULE_DIR=/rulescommand:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkdaemoneye-agent:build:context: .dockerfile: daemoneye-agent/Dockerfilecontainer_name: daemoneye-agent-devdepends_on:- procmondvolumes:- ./data:/data- ./logs:/logs- ./config:/config:roenvironment:- DaemonEye_LOG_LEVEL=debug- DaemonEye_DATA_DIR=/data- DaemonEye_LOG_DIR=/logs- DaemonEye_PROCMOND_ENDPOINT=tcp://procmond:8080command:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkdaemoneye-cli:build:context: .dockerfile: daemoneye-cli/Dockerfilecontainer_name: daemoneye-cli-devdepends_on:- daemoneye-agentvolumes:- ./data:/data- ./config:/config:roenvironment:- DaemonEye_DATA_DIR=/datacommand:[--help]restart:nonetworks:- daemoneye-networknetworks:daemoneye-network:driver: bridge
Production Deployment#
Production Configuration#
Environment Variables:
# .env fileDaemonEye_VERSION=1.0.0DaemonEye_LOG_LEVEL=infoDaemonEye_DATA_DIR=/var/lib/daemoneyeDaemonEye_LOG_DIR=/var/log/daemoneyeDaemonEye_CONFIG_DIR=/etc/daemoneye# Database settingsDATABASE_PATH=/var/lib/daemoneye/processes.dbDATABASE_RETENTION_DAYS=30# Alerting settingsALERTING_SYSLOG_ENABLED=trueALERTING_SYSLOG_FACILITY=daemonALERTING_WEBHOOK_ENABLED=falseALERTING_WEBHOOK_URL=https://alerts.example.com/webhookALERTING_WEBHOOK_TOKEN=${WEBHOOK_TOKEN}# Security settingsSECURITY_ENABLE_PRIVILEGE_DROPPING=trueSECURITY_DROP_TO_USER=1000SECURITY_DROP_TO_GROUP=1000SECURITY_ENABLE_AUDIT_LOGGING=true# Performance settingsAPP_SCAN_INTERVAL_MS=60000APP_BATCH_SIZE=1000APP_MAX_MEMORY_MB=512APP_MAX_CPU_PERCENT=5.0
Production Docker Compose:
version:'3.8'services:procmond:image: daemoneye/procmond:${DaemonEye_VERSION}container_name: daemoneye-procmondprivileged:trueuser: ${SECURITY_DROP_TO_USER}:${SECURITY_DROP_TO_GROUP}volumes:- daemoneye-data:/data- daemoneye-logs:/logs- ./config/procmond.yaml:/config/config.yaml:ro- ./rules:/rules:roenvironment:- DaemonEye_LOG_LEVEL=${DaemonEye_LOG_LEVEL}- DaemonEye_DATA_DIR=${DaemonEye_DATA_DIR}- DaemonEye_LOG_DIR=${DaemonEye_LOG_DIR}- DaemonEye_RULE_DIR=/rulescommand:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkhealthcheck:test:[CMD, procmond, health]interval: 30stimeout: 10sretries:3start_period: 40slogging:driver: json-fileoptions:max-size: 100mmax-file:'5'daemoneye-agent:image: daemoneye/daemoneye-agent:${DaemonEye_VERSION}container_name: daemoneye-agentdepends_on:procmond:condition: service_healthyuser: ${SECURITY_DROP_TO_USER}:${SECURITY_DROP_TO_GROUP}volumes:- daemoneye-data:/data- daemoneye-logs:/logs- ./config/daemoneye-agent.yaml:/config/config.yaml:roenvironment:- DaemonEye_LOG_LEVEL=${DaemonEye_LOG_LEVEL}- DaemonEye_DATA_DIR=${DaemonEye_DATA_DIR}- DaemonEye_LOG_DIR=${DaemonEye_LOG_DIR}- DaemonEye_PROCMOND_ENDPOINT=tcp://procmond:8080command:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkhealthcheck:test:[CMD, daemoneye-agent, health]interval: 30stimeout: 10sretries:3start_period: 40slogging:driver: json-fileoptions:max-size: 100mmax-file:'5'security-center:image: daemoneye/security-center:${DaemonEye_VERSION}container_name: daemoneye-security-centerdepends_on:daemoneye-agent:condition: service_healthyuser: ${SECURITY_DROP_TO_USER}:${SECURITY_DROP_TO_GROUP}volumes:- daemoneye-data:/data- ./config/security-center.yaml:/config/config.yaml:roenvironment:- DaemonEye_LOG_LEVEL=${DaemonEye_LOG_LEVEL}- DaemonEye_DATA_DIR=${DaemonEye_DATA_DIR}- DaemonEye_AGENT_ENDPOINT=tcp://daemoneye-agent:8080- DaemonEye_WEB_PORT=8080command:[--config, /config/config.yaml]restart: unless-stoppednetworks:- daemoneye-networkports:- 8080:8080healthcheck:test:[CMD, curl, -f, http://localhost:8080/health]interval: 30stimeout: 10sretries:3start_period: 40slogging:driver: json-fileoptions:max-size: 100mmax-file:'5'networks:daemoneye-network:driver: bridgeipam:config:-subnet: 172.20.0.0/16volumes:daemoneye-data:driver: localdaemoneye-logs:driver: local
Deployment Scripts#
deploy.sh:
#!/bin/bashset-e# ConfigurationCOMPOSE_FILE="docker-compose.prod.yml"ENV_FILE=".env"BACKUP_DIR="/backup/daemoneye"LOG_DIR="/var/log/daemoneye"# Colors for outputRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m'# No Color# Functionslog_info(){echo-e"${GREEN}[INFO]${NC}$1"}log_warn(){echo-e"${YELLOW}[WARN]${NC}$1"}log_error(){echo-e"${RED}[ERROR]${NC}$1"}# Check prerequisitescheck_prerequisites(){log_info"Checking prerequisites..."if! command-v docker &> /dev/null;thenlog_error"Docker is not installed"exit 1fiif! command-v docker-compose &> /dev/null;thenlog_error"Docker Compose is not installed"exit 1fiif[!-f"$ENV_FILE"];thenlog_error"Environment file $ENV_FILE not found"exit 1fiif[!-f"$COMPOSE_FILE"];thenlog_error"Compose file $COMPOSE_FILE not found"exit 1filog_info"Prerequisites check passed"}# Backup existing deploymentbackup_deployment(){log_info"Backing up existing deployment..."if[-d"$BACKUP_DIR"];thenrm-rf"$BACKUP_DIR"fimkdir-p"$BACKUP_DIR"# Backup data volumesifdocker volume ls |grep-q daemoneye-data;thendocker run --rm-v daemoneye-data:/data -v"$BACKUP_DIR":/backup alpine tar czf /backup/data.tar.gz -C /data .fi# Backup logsif[-d"$LOG_DIR"];thencp-r"$LOG_DIR""$BACKUP_DIR/logs"filog_info"Backup completed"}# Deploy DaemonEyedeploy_daemoneye(){log_info"Deploying DaemonEye..."# Pull latest imagesdocker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" pull# Stop existing servicesdocker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" down# Start servicesdocker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" up -d# Wait for services to be healthylog_info"Waiting for services to be healthy..."sleep 30# Check service healthifdocker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" ps |grep-q"unhealthy";thenlog_error"Some services are unhealthy"docker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" logsexit 1filog_info"Deployment completed successfully"}# Main executionmain(){log_info"Starting DaemonEye deployment..."check_prerequisitesbackup_deploymentdeploy_daemoneyelog_info"DaemonEye deployment completed successfully"}# Run main functionmain"$@"
rollback.sh:
#!/bin/bashset-e# ConfigurationCOMPOSE_FILE="docker-compose.prod.yml"ENV_FILE=".env"BACKUP_DIR="/backup/daemoneye"# Colors for outputRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m'# No Color# Functionslog_info(){echo-e"${GREEN}[INFO]${NC}$1"}log_warn(){echo-e"${YELLOW}[WARN]${NC}$1"}log_error(){echo-e"${RED}[ERROR]${NC}$1"}# Rollback deploymentrollback_deployment(){log_info"Rolling back DaemonEye deployment..."# Stop current servicesdocker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" down# Restore data volumesif[-f"$BACKUP_DIR/data.tar.gz"];thendocker run --rm-v daemoneye-data:/data -v"$BACKUP_DIR":/backup alpine tar xzf /backup/data.tar.gz -C /datafi# Restore logsif[-d"$BACKUP_DIR/logs"];thencp-r"$BACKUP_DIR/logs"/* /var/log/daemoneye/fi# Start servicesdocker-compose-f"$COMPOSE_FILE"--env-file"$ENV_FILE" up -dlog_info"Rollback completed"}# Main executionmain(){log_info"Starting DaemonEye rollback..."rollback_deploymentlog_info"DaemonEye rollback completed successfully"}# Run main functionmain"$@"
Kubernetes Deployment#
Note: The Kubernetes manifests below reference
Docker images. Until official images are published, you must either:
- Build images locally and push to your container registry, then
update image references in manifests- Use imagePullPolicy: Never and pre-load images on cluster nodes
Kubernetes Manifests#
Namespace:
# namespace.yamlapiVersion: v1kind: Namespacemetadata:name: daemoneyelabels:name: daemoneye
ConfigMap:
# configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: daemoneye-confignamespace: daemoneyedata: procmond.yaml: | app: scan_interval_ms: 30000 batch_size: 1000 log_level: info data_dir: /data log_dir: /logs database: path: /data/processes.db retention_days: 30 security: enable_privilege_dropping: true drop_to_user: 1000 drop_to_group: 1000 daemoneye-agent.yaml: | app: scan_interval_ms: 30000 batch_size: 1000 log_level: info data_dir: /data log_dir: /logs database: path: /data/processes.db retention_days: 30 alerting: enabled: true sinks: - type: syslog enabled: true facility: daemon - type: webhook enabled: true url: http://daemoneye-webhook:8080/webhook
Secret:
# secret.yamlapiVersion: v1kind: Secretmetadata:name: daemoneye-secretsnamespace: daemoneyetype: Opaquedata:webhook-token: <base64-encoded-token>database-encryption-key: <base64-encoded-key>
PersistentVolumeClaim:
# pvc.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:name: daemoneye-datanamespace: daemoneyespec:accessModes:- ReadWriteOnceresources:requests:storage: 10GistorageClassName: fast-ssd
DaemonSet for procmond:
# procmond-daemonset.yamlapiVersion: apps/v1kind: DaemonSetmetadata:name: daemoneye-procmondnamespace: daemoneyespec:selector:matchLabels:app: daemoneye-procmondtemplate:metadata:labels:app: daemoneye-procmondspec:serviceAccountName: daemoneye-procmondcontainers:-name: procmondimage: daemoneye/procmond:1.0.0imagePullPolicy: IfNotPresentsecurityContext:privileged:truerunAsUser:1000runAsGroup:1000volumeMounts:-name: configmountPath: /configreadOnly:true-name: datamountPath: /data-name: logsmountPath: /logs-name: rulesmountPath: /rulesreadOnly:trueenv:-name: DaemonEye_LOG_LEVELvalue: info-name: DaemonEye_DATA_DIRvalue: /data-name: DaemonEye_LOG_DIRvalue: /logscommand:[procmond]args:[--config, /config/procmond.yaml]resources:requests:memory: 256Micpu: 100mlimits:memory: 512Micpu: 500mlivenessProbe:exec:command:- procmond- healthinitialDelaySeconds:30periodSeconds:30timeoutSeconds:10failureThreshold:3readinessProbe:exec:command:- procmond- healthinitialDelaySeconds:10periodSeconds:10timeoutSeconds:5failureThreshold:3volumes:-name: configconfigMap:name: daemoneye-config-name: datapersistentVolumeClaim:claimName: daemoneye-data-name: logsemptyDir:{}-name: rulesconfigMap:name: daemoneye-rulestolerations:-key: node-role.kubernetes.io/masteroperator: Existseffect: NoSchedule-key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedule
Deployment for daemoneye-agent:
# daemoneye-agent-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: daemoneye-agentnamespace: daemoneyespec:replicas:1selector:matchLabels:app: daemoneye-agenttemplate:metadata:labels:app: daemoneye-agentspec:serviceAccountName: daemoneye-agentcontainers:-name: daemoneye-agentimage: daemoneye/daemoneye-agent:1.0.0imagePullPolicy: IfNotPresentsecurityContext:runAsUser:1000runAsGroup:1000volumeMounts:-name: configmountPath: /configreadOnly:true-name: datamountPath: /data-name: logsmountPath: /logsenv:-name: DaemonEye_LOG_LEVELvalue: info-name: DaemonEye_DATA_DIRvalue: /data-name: DaemonEye_LOG_DIRvalue: /logs-name: DaemonEye_PROCMOND_ENDPOINTvalue: tcp://daemoneye-procmond:8080command:[daemoneye-agent]args:[--config, /config/daemoneye-agent.yaml]resources:requests:memory: 512Micpu: 200mlimits:memory: 1Gicpu: 1000mlivenessProbe:exec:command:- daemoneye-agent- healthinitialDelaySeconds:30periodSeconds:30timeoutSeconds:10failureThreshold:3readinessProbe:exec:command:- daemoneye-agent- healthinitialDelaySeconds:10periodSeconds:10timeoutSeconds:5failureThreshold:3volumes:-name: configconfigMap:name: daemoneye-config-name: datapersistentVolumeClaim:claimName: daemoneye-data-name: logsemptyDir:{}
Service:
# service.yamlapiVersion: v1kind: Servicemetadata:name: daemoneye-agentnamespace: daemoneyespec:selector:app: daemoneye-agentports:-name: httpport:8080targetPort:8080protocol: TCPtype: ClusterIP
ServiceAccount and RBAC:
# rbac.yamlapiVersion: v1kind: ServiceAccountmetadata:name: daemoneye-procmondnamespace: daemoneye---apiVersion: v1kind: ServiceAccountmetadata:name: daemoneye-agentnamespace: daemoneye---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:name: daemoneye-procmondrules:-apiGroups:[""]resources:["nodes","pods"]verbs:["get","list","watch"]-apiGroups:[""]resources:["pods/exec"]verbs:["create"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: daemoneye-procmondroleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: daemoneye-procmondsubjects:-kind: ServiceAccountname: daemoneye-procmondnamespace: daemoneye---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:name: daemoneye-agentrules:-apiGroups:[""]resources:["pods","services","endpoints"]verbs:["get","list","watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: daemoneye-agentroleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: daemoneye-agentsubjects:-kind: ServiceAccountname: daemoneye-agentnamespace: daemoneye
Helm Chart#
Chart.yaml:
# Chart.yamlapiVersion: v2name: daemoneyedescription: DaemonEye Security Monitoring Agenttype: applicationversion:1.0.0appVersion:1.0.0keywords:- security- monitoring- processes- threat-detectionhome: https://daemoneye.comsources:- https://github.com/daemoneye/daemoneyemaintainers:-name: DaemonEye Teamemail: team@daemoneye.com
values.yaml:
# values.yamlimage:repository: daemoneyetag:1.0.0pullPolicy: IfNotPresentreplicaCount:1serviceAccount:create:trueannotations:{}name:''podSecurityContext:runAsUser:1000runAsGroup:1000fsGroup:1000securityContext:allowPrivilegeEscalation:falsecapabilities:drop:- ALLreadOnlyRootFilesystem:truerunAsNonRoot:truerunAsUser:1000service:type: ClusterIPport:8080ingress:enabled:falseclassName:''annotations:{}hosts:-host: daemoneye.example.compaths:-path: /pathType: Prefixtls:[]resources:limits:cpu: 1000mmemory: 1Girequests:cpu: 200mmemory: 512Miautoscaling:enabled:falseminReplicas:1maxReplicas:10targetCPUUtilizationPercentage:80targetMemoryUtilizationPercentage:80nodeSelector:{}tolerations:[]affinity:{}persistence:enabled:truestorageClass:''accessMode: ReadWriteOncesize: 10Giconfig:app:scan_interval_ms:30000batch_size:1000log_level: infodatabase:retention_days:30alerting:enabled:truesinks:-type: syslogenabled:truefacility: daemonsecrets:{}monitoring:enabled:falseserviceMonitor:enabled:falsenamespace:''interval: 30sscrapeTimeout: 10s
Security Considerations#
Container Security#
Security Context:
securityContext:runAsUser:1000runAsGroup:1000runAsNonRoot:trueallowPrivilegeEscalation:falsereadOnlyRootFilesystem:truecapabilities:drop:- ALLadd:- CAP_SYS_PTRACE # Only for procmond
Privileged Containers:
# Only procmond needs privileged accesssecurityContext:privileged:truecapabilities:add:- CAP_SYS_PTRACE- CAP_SYS_ADMIN
Network Security:
# Network policiesapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: daemoneye-network-policynamespace: daemoneyespec:podSelector:matchLabels:app: daemoneyepolicyTypes:- Ingress- Egressingress:-from:-namespaceSelector:matchLabels:name: daemoneyeports:-protocol: TCPport:8080egress:-to:-namespaceSelector:matchLabels:name: daemoneyeports:-protocol: TCPport:8080
Image Security#
Image Scanning:
# Scan images for vulnerabilitiesdocker run --rm-v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy image daemoneye/procmond:1.0.0# Scan with specific severity levelsdocker run --rm-v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy image --severity HIGH,CRITICAL daemoneye/procmond:1.0.0
Image Signing:
# Sign images with Docker Content TrustexportDOCKER_CONTENT_TRUST=1docker push daemoneye/procmond:1.0.0
Multi-stage Builds:
# Multi-stage build for smaller attack surfaceFROM rust:1.91-alpine AS builderWORKDIR /appCOPY . .RUNcargo build --releaseFROM alpine:3.18RUNapk add --no-cache ca-certificatesCOPY--from=builder /app/target/release/procmond /usr/local/bin/USER 1000:1000ENTRYPOINT ["procmond"]
Monitoring and Logging#
Container Monitoring#
Prometheus Metrics:
# Enable metrics collectionobservability:enable_metrics:truemetrics_port:9090metrics_path: /metrics
Grafana Dashboard:
{"dashboard":{"title":"DaemonEye Monitoring","panels":[{"title":"Process Collection Rate","type":"graph","targets":[{"expr":"rate(daemoneye_processes_collected_total[5m])","legendFormat":"Processes/sec"}]},{"title":"Memory Usage","type":"graph","targets":[{"expr":"daemoneye_memory_usage_bytes","legendFormat":"Memory Usage"}]}]}}
Log Aggregation#
Fluentd Configuration:
# fluentd-configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: fluentd-confignamespace: daemoneyedata: fluent.conf: | <source> @type tail path /var/log/daemoneye/*.log pos_file /var/log/fluentd/daemoneye.log.pos tag daemoneye.* format json </source> <match daemoneye.**> @type elasticsearch host elasticsearch.logging.svc.cluster.local port 9200 index_name daemoneye type_name _doc </match>
ELK Stack Integration:
# elasticsearch-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: elasticsearchnamespace: loggingspec:replicas:1selector:matchLabels:app: elasticsearchtemplate:metadata:labels:app: elasticsearchspec:containers:-name: elasticsearchimage: docker.elastic.co/elasticsearch/elasticsearch:8.8.0env:-name: discovery.typevalue: single-node-name: xpack.security.enabledvalue:'false'ports:-containerPort:9200resources:requests:memory: 1Gicpu: 500mlimits:memory: 2Gicpu: 1000m
Troubleshooting#
Common Issues#
Container Won't Start:
# Check container logsdocker logs daemoneye-procmond# Check container statusdocker ps -a# Check resource usagedocker stats daemoneye-procmond
Permission Denied:
# Check file permissionsdocker exec daemoneye-procmond ls -la /data# Fix permissionsdocker exec daemoneye-procmond chown -R 1000:1000 /data
Network Issues:
# Check network connectivitydocker exec daemoneye-agent ping daemoneye-procmond# Check DNS resolutiondocker exec daemoneye-agent nslookup daemoneye-procmond
Database Issues:
# Check database statusdocker exec daemoneye-agent daemoneye-cli database status# Check database integritydocker exec daemoneye-agent daemoneye-cli database integrity-check# Repair databasedocker exec daemoneye-agent daemoneye-cli database repair
Debug Mode#
Enable Debug Logging:
# docker-compose.ymlservices:procmond:environment:- DaemonEye_LOG_LEVEL=debugcommand:[procmond, --config, /config/config.yaml, --log-level, debug]
Debug Container:
# Run debug containerdocker run -it--rm--privileged\-v /var/lib/daemoneye:/data \-v /var/log/daemoneye:/logs \ daemoneye/procmond:latest /bin/sh# Check system capabilitiesdocker run --rm--privileged daemoneye/procmond:latest capsh --print
Performance Issues#
High CPU Usage:
# Check CPU usagedocker stats daemoneye-procmond# Reduce scan frequencydocker exec daemoneye-procmond daemoneye-cli config set app.scan_interval_ms 120000
High Memory Usage:
# Check memory usagedocker stats daemoneye-procmond# Limit memory usagedocker run -d--memory=512m daemoneye/procmond:latest
Slow Database Operations:
# Check database performancedocker exec daemoneye-agent daemoneye-cli database query-stats# Optimize databasedocker exec daemoneye-agent daemoneye-cli database optimize
Health Checks#
Container Health:
# Check container healthdocker inspect daemoneye-procmond |jq'.[0].State.Health'# Run health check manuallydocker exec daemoneye-procmond procmond health
Service Health:
# Check service healthcurl http://localhost:8080/health# Check metricscurl http://localhost:9090/metrics
This Docker deployment guide provides comprehensive instructions
for containerizing and deploying DaemonEye. For additional help, consult
the troubleshooting section or contact support.
Source note: Populated from the public repo
(docs/src/deployment/docker.md) on 2026-04-18. This page
was previously empty; the content above mirrors the repo at the time of
sync.