# Security Search — production docker-compose. # # Publishes host port 5140 on loopback by default. Set # SECURITYSEARCH_BIND_ADDRESS to a private Docker-host bridge address when a # containerized reverse proxy must reach it; never expose this port publicly. services: security-search: build: context: . dockerfile: Dockerfile image: security-search:latest container_name: security-search restart: unless-stopped # init: true # tini already in image; belt-and-braces environment: - FOURGET_PROTO=http - FOURGET_SERVER_NAME=Security Search - FOURGET_SERVER_SHORT_DESCRIPTION=Privacy-first proxy search engine - FOURGET_DEFAULT_THEME=Tron - FOURGET_DEFAULT_NSFW=yes # Provider defaults. Google is backed by the bundled CSE-compatible # implementation; Brave remains available in every provider picker. - FOURGET_DEFAULT_SCRAPER_WEB=google - FOURGET_DEFAULT_SCRAPER_IMAGES=google - FOURGET_DEFAULT_SCRAPER_NEWS=reddit - FOURGET_API_ENABLED=true - FOURGET_BOT_PROTECTION=0 - FOURGET_MAX_SEARCHES=10000 - FOURGET_INSTANCES=https://securityops.co # Optional private egress pools. Set only the pool name in the host # environment or .env; keep the matching credential file outside Git. # Compose passes these entries through only when they are defined. - FOURGET_PROXY_GOOGLE - FOURGET_PROXY_GOOGLE_CSE - FOURGET_PROXY_GOOGLE_API - FOURGET_PROXY_BRAVE - FOURGET_PROXY_DDG - FOURGET_SOURCE_IP_GOOGLE - FOURGET_SOURCE_IP_BRAVE # Tells PHP that the front-facing protocol is HTTPS even though # NPM hits us over HTTP. Only meaningful behind a TLS terminator. - HTTPS=on # Private published endpoint used by local clients or the reverse proxy. ports: - "${SECURITYSEARCH_BIND_ADDRESS:-127.0.0.1}:5140:80" networks: - bridge # ------------------------------------------------------------------ # Hardening — drop all kernel caps and re-add only what httpd needs. # ------------------------------------------------------------------ security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - SETUID - SETGID - NET_BIND_SERVICE # bind to port 80 # ------------------------------------------------------------------ # The root filesystem remains writable for root during entrypoint config # generation. Shipped source is root-owned/0644, so Apache workers cannot # modify PHP or application assets; only the icons volume is worker-writable. # ------------------------------------------------------------------ read_only: false tmpfs: - /tmp:size=64M,mode=1777 # - /run:size=8M # - /var/run:size=8M # - /var/log/apache2:size=32M # - /var/cache/mod_ssl:size=8M volumes: # Persist the favicon cache across container rebuilds — saves a # lot of upstream calls. - icons-cache:/var/www/html/4get/icons # ---- OPTIONAL: uncomment any of these to mount host content ---- # - ./banners:/var/www/html/4get/banner:ro # - ./static/themes:/var/www/html/4get/static/themes:ro # - ./data/captcha:/var/www/html/4get/data/captcha:ro # - ./data/api_keys:/var/www/html/4get/data/api_keys:ro # - ./data/proxies:/var/www/html/4get/data/proxies:ro # ---- HTTPS direct mode (not needed if behind NPM) ---- # - /etc/letsencrypt/live/securityops.co:/etc/4get/certs:ro deploy: resources: limits: memory: 512M cpus: '1.0' reservations: memory: 128M cpus: '0.25' healthcheck: test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://127.0.0.1/"] interval: 30s timeout: 5s retries: 3 start_period: 30s # Cap log size so a runaway error doesn't fill the host disk. logging: driver: "json-file" options: max-size: "10m" max-file: "3" tag: "security-search" volumes: icons-cache: driver: local networks: bridge: driver: bridge