From e01559047670db91bfe1f2ea9659ec81113b7422 Mon Sep 17 00:00:00 2001 From: nicolaipre <16032412+nicolaipre@users.noreply.github.com> Date: Mon, 13 Oct 2025 15:59:12 +0200 Subject: [PATCH] Added docker-compose.yml and Makefile for easier setup of Sandfly. --- .gitignore | 2 + Makefile | 48 ++++++++++++++ docker-compose.yml | 158 +++++++++++++++++++++++++++++++++++++++++++++ env.example | 20 ++++++ 4 files changed, 228 insertions(+) create mode 100644 Makefile create mode 100644 docker-compose.yml create mode 100644 env.example diff --git a/.gitignore b/.gitignore index 7ee9362..982be25 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ setup/setup_data/config.* docker_images +sandfly-data +.env diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..44c1264 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +.PHONY: help init start stop logs clean node dev + +SANDFLY_VERSION ?= 5.5.1 +SANDFLY_IMAGE_BASE ?= quay.io/sandfly +SANDFLY_HOSTNAME ?= localhost + +help: ## Show this help message + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-15s %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +init: ## Initialize Sandfly (first time setup) + @if [ ! -f .env ]; then \ + echo "Error: .env file not found. Copy env.example to .env first"; \ + exit 1; \ + fi + @mkdir -p sandfly-data/postgres sandfly-data/ssl + @if [ ! -f sandfly-data/postgres.admin.password.txt ]; then \ + grep '^POSTGRES_PASSWORD=' .env | cut -d'=' -f2 > sandfly-data/postgres.admin.password.txt; \ + fi + @docker compose up -d sandfly-postgres + @docker compose --profile setup up sandfly-init + @docker rm sandfly-init 2>/dev/null || true + @echo "Initialization complete! Run 'make start' to start services." + @echo "################################################################################" + @printf 'Admin username: %s\n' "admin" + @printf 'Admin password: %s\n' "$$(tr -d '\n' < sandfly-data/admin.password.txt)" + @echo "################################################################################" + +start: ## Start Sandfly services + @if [ ! -f sandfly-data/config.server.json ]; then \ + echo "Error: Sandfly not initialized. Run 'make init' first"; \ + exit 1; \ + fi + @docker compose up -d + +logs: ## Show logs + @docker compose logs -f + +stop: ## Stop all services + @docker compose down + +clean: ## Remove all data and containers + @read -p "Remove all data? (yes/no): " confirm && [ "$$confirm" = "yes" ] + @docker compose down + @sudo rm -rf sandfly-data + +dev: ## Start development environment + @$(MAKE) start + @$(MAKE) node diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..47e23ec --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,158 @@ +services: + + sandfly-postgres: + image: docker.io/library/postgres:14.18 + container_name: sandfly-postgres + restart: unless-stopped + environment: + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme} + PGDATA: /var/lib/postgresql/data + volumes: + - ./sandfly-data/postgres:/var/lib/postgresql/data + - /dev/urandom:/dev/random:ro + networks: + - sandfly-net + ports: + - "5432:5432" + logging: + driver: json-file + options: + max-size: "20m" + max-file: "5" + command: | + -c max_connections=${POSTGRES_MAX_CONNECTIONS:-60} + -c shared_buffers=${POSTGRES_SHARED_BUFFERS:-262144}kB + -c effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-786432}kB + -c maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-1048576}kB + -c checkpoint_completion_target=0.9 + -c wal_buffers=${POSTGRES_WAL_BUFFERS:-32}kB + -c default_statistics_target=100 + -c random_page_cost=2 + -c effective_io_concurrency=100 + -c work_mem=${POSTGRES_WORK_MEM:-64}kB + -c min_wal_size=2GB + -c max_wal_size=8GB + -c max_worker_processes=${POSTGRES_MAX_WORKER_PROCESSES:-4} + -c max_parallel_workers_per_gather=${POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER:-4} + -c max_parallel_workers=${POSTGRES_MAX_PARALLEL_WORKERS:-4} + -c max_parallel_maintenance_workers=${POSTGRES_MAX_PARALLEL_MAINTENANCE_WORKERS:-4} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 30s + + sandfly-init: + image: ${SANDFLY_IMAGE_BASE:-quay.io/sandfly}/sandfly:${SANDFLY_VERSION:-5.5.1} + container_name: sandfly-init + depends_on: + sandfly-postgres: + condition: service_healthy + environment: + - SANDFLY_SETUP_AUTO_HOSTNAME=${SANDFLY_HOSTNAME} + - SANDFLY_AUTO=YES + volumes: + - ./sandfly-data:/opt/sandfly/install/setup_data + - ./sandfly-data/ssl:/opt/sandfly/conf/ssl + - ./setup/setup_data/templates:/opt/sandfly/install/setup_data/templates:ro + - /dev/urandom:/dev/random:ro + networks: + - sandfly-net + command: | + sh -c ' + if [ ! -f /opt/sandfly/install/setup_data/config.server.json ]; then + echo "Running Sandfly setup..." + /opt/sandfly/install/install_server.sh + /opt/sandfly/install/install_ssl.sh + /opt/sandfly/install/install_keys.sh + /opt/sandfly/install/install_config_json.sh + echo "Setup complete!" + else + echo "Setup already complete, skipping..." + fi + ' + profiles: + - setup + + sandfly-server: + image: ${SANDFLY_IMAGE_BASE:-quay.io/sandfly}/sandfly:${SANDFLY_VERSION:-5.5.1} + container_name: sandfly-server + restart: unless-stopped + depends_on: + sandfly-postgres: + condition: service_healthy + volumes: + - /dev/urandom:/dev/random:ro + - ./sandfly-data:/opt/sandfly/install/setup_data:ro + - ./sandfly-data/ssl:/opt/sandfly/conf/ssl:ro + networks: + - sandfly-net + ports: + - "443:8443" + - "8000:8000" + logging: + driver: json-file + options: + max-size: "${LOG_MAX_SIZE:-100m}" + max-file: "5" + command: | + sh -c ' + export CONFIG_JSON=$$(cat /opt/sandfly/install/setup_data/config.server.json) + /opt/sandfly/start_api.sh + ' + #healthcheck: + # test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + # interval: 30s + # timeout: 10s + # retries: 5 + # start_period: 60s + + # Sandfly Node (for scanning) + sandfly-node: + image: ${SANDFLY_IMAGE_BASE:-quay.io/sandfly}/sandfly:${SANDFLY_VERSION:-5.5.1} + container_name: sandfly-node + restart: unless-stopped + depends_on: + - sandfly-server + #condition: service_healthy + environment: + - LOCAL_SERVER=true + volumes: + - /dev/urandom:/dev/random:ro + - ./sandfly-data:/opt/sandfly/install/setup_data + - ./sandfly-data/ssl:/opt/sandfly/conf/ssl:ro + networks: + - sandfly-net + logging: + driver: json-file + options: + max-size: "${LOG_MAX_SIZE:-100m}" + max-file: "5" + command: | + sh -c ' + export CONFIG_JSON=$$(cat /opt/sandfly/install/setup_data/config.node.json) + /opt/sandfly/start_node.sh + ' + profiles: + - node + + # Credentials Adapter (optional) + sandfly-credentials-adapter: + image: ${SANDFLY_IMAGE_BASE:-quay.io/sandfly}/sandfly-credentials-adapter:${SANDFLY_VERSION:-5.5.1} + container_name: sandfly-credentials-adapter + restart: unless-stopped + depends_on: + sandfly-server: + condition: service_healthy + networks: + - sandfly-net + profiles: + - credentials + + +networks: + sandfly-net: + driver: bridge + name: sandfly-net + diff --git a/env.example b/env.example new file mode 100644 index 0000000..b4dfc56 --- /dev/null +++ b/env.example @@ -0,0 +1,20 @@ +# Sandfly Configuration +SANDFLY_VERSION=5.5.1 +SANDFLY_IMAGE_BASE=quay.io/sandfly +SANDFLY_HOSTNAME=hostname + +# Logging Configuration +LOG_MAX_SIZE=100m + +# PostgreSQL Configuration +POSTGRES_PASSWORD=changeme +POSTGRES_MAX_CONNECTIONS=60 +POSTGRES_SHARED_BUFFERS=262144 +POSTGRES_EFFECTIVE_CACHE_SIZE=786432 +POSTGRES_MAINTENANCE_WORK_MEM=1048576 +POSTGRES_WAL_BUFFERS=32 +POSTGRES_WORK_MEM=64 +POSTGRES_MAX_WORKER_PROCESSES=4 +POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER=4 +POSTGRES_MAX_PARALLEL_WORKERS=4 +POSTGRES_MAX_PARALLEL_MAINTENANCE_WORKERS=4