#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: run_in_docker.sh [runner options] -- [entrypoint args] Runner options: --build Build image before running --image Override image name (default: codex/similarweb-analytics:latest) --runtime-dir Host path that contains data_api.py (default: /opt/.manus/.sandbox-runtime) --output-dir Host output directory mounted to /data (default: ./similarweb-output) --network Docker network mode (default: bridge) -h, --help Show this message Entrypoint args: --self-test --api --domain --start-date YYYY-MM --end-date YYYY-MM --country --granularity monthly --limit <1..10> --main-domain-only --output /data/.json --dry-run --mock-result Examples: run_in_docker.sh --build -- --self-test run_in_docker.sh -- --api visits-total --domain amazon.com --dry-run run_in_docker.sh -- --api global-rank --domain amazon.com --output /data/amazon-rank.json EOF } SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" IMAGE="${SIMILARWEB_IMAGE:-codex/similarweb-analytics:latest}" RUNTIME_DIR="${SIMILARWEB_RUNTIME_DIR:-/opt/.manus/.sandbox-runtime}" OUTPUT_DIR="${SIMILARWEB_OUTPUT_DIR:-$PWD/similarweb-output}" NETWORK_MODE="${SIMILARWEB_NETWORK_MODE:-bridge}" BUILD_IMAGE=0 while [[ $# -gt 0 ]]; do case "$1" in --build) BUILD_IMAGE=1 shift ;; --image) IMAGE="${2:-}" shift 2 ;; --runtime-dir) RUNTIME_DIR="${2:-}" shift 2 ;; --output-dir) OUTPUT_DIR="${2:-}" shift 2 ;; --network) NETWORK_MODE="${2:-}" shift 2 ;; --) shift break ;; -h|--help) usage exit 0 ;; *) echo "Unknown runner option: $1" >&2 usage >&2 exit 2 ;; esac done if [[ $# -eq 0 ]]; then echo "Missing entrypoint args. Use -- to pass container args." >&2 usage >&2 exit 2 fi if ! command -v docker >/dev/null 2>&1; then echo "docker command not found" >&2 exit 127 fi if [[ ! -d "$RUNTIME_DIR" ]]; then echo "Runtime dir not found: $RUNTIME_DIR" >&2 echo "It must contain data_api.py for real API calls." >&2 exit 1 fi if [[ ! -f "$RUNTIME_DIR/data_api.py" ]]; then echo "Runtime module missing: $RUNTIME_DIR/data_api.py" >&2 exit 1 fi mkdir -p "$OUTPUT_DIR" # Keep container non-root while ensuring mounted output path is writable. chmod 0777 "$OUTPUT_DIR" 2>/dev/null || true if [[ "$BUILD_IMAGE" -eq 1 ]] || ! docker image inspect "$IMAGE" >/dev/null 2>&1; then docker build -t "$IMAGE" -f "$SCRIPT_DIR/docker/Dockerfile" "$SCRIPT_DIR/docker" fi docker run --rm \ --network "$NETWORK_MODE" \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid,size=64m \ --tmpfs /var/tmp:rw,noexec,nosuid,size=32m \ --cap-drop ALL \ --security-opt no-new-privileges \ --pids-limit 256 \ --memory 512m \ --cpus 1.0 \ -e SIMILARWEB_API_KEY \ -e SIMILARWEB_BASE_URL \ -e RAPIDAPI_KEY \ -e RAPIDAPI_SIMILARWEB_HOST \ -v "$RUNTIME_DIR:/opt/.manus/.sandbox-runtime:ro" \ -v "$OUTPUT_DIR:/data:rw" \ "$IMAGE" "$@"