# ───────────────────────────────────────────────────────────────────────────── # Reconner — docker compose. # # docker compose up -d --build # build the image and start on :8080 # docker compose logs -f # follow logs (admin password prints here # # on the very first boot) # docker compose down # stop (the named volume keeps the DB) # # Configuration is via a .env file next to this one (copy .env.example → .env). # The database + config persist in the `reconner-data` named volume, so updating # the image (docker compose pull / up -d --build) never loses your data. # ───────────────────────────────────────────────────────────────────────────── services: reconner: build: context: . dockerfile: Dockerfile image: ghcr.io/rootdr-backup/reconner:latest container_name: reconner restart: unless-stopped # The entrypoint uses root only for the one-time ownership migration of # pre-v3 volumes, then drops permanently to uid/gid 10001 before startup. user: "0:0" # Bound the entire container, including Chromium and external scanner child # processes. Override these in .env for the host sizes documented in # README.Docker.md; Go's internal memory budget auto-detects this cgroup. mem_limit: "${RECON_MEMORY_LIMIT:-3g}" pids_limit: ${RECON_PIDS_LIMIT:-512} ports: # host:container — change HOST_PORT in .env to expose a different port. - "${HOST_PORT:-8080}:8080" environment: # The app always listens on 8080 inside the container; map it above. PORT: "8080" ADMIN_USER: "${ADMIN_USER:-admin}" # Leave ADMIN_PASSWORD unset for a random password generated on first boot # (printed once in the logs). Set it in .env to pin a known password. ADMIN_PASSWORD: "${ADMIN_PASSWORD:-}" volumes: - reconner-data:/data # Chromium headless is happier with a little more shared memory. shm_size: "512m" healthcheck: test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/api/health"] interval: 30s timeout: 5s retries: 5 start_period: 40s volumes: reconner-data: