{"owner":"MODSetter","repo":"SurfSense","hasDocker":true,"hasCompose":true,"hasDockerfile":false,"composePath":"docker/docker-compose.yml","servicesCount":12,"services":[{"name":"db","image":"pgvector/pgvector:pg17","restart":"unless-stopped","command":"postgres -c config_file=/etc/postgresql/postgresql.conf","environment":["POSTGRES_USER=${DB_USER:-surfsense}","POSTGRES_PASSWORD=${DB_PASSWORD:-surfsense}","POSTGRES_DB=${DB_NAME:-surfsense}"],"volumes":["postgres_data:/var/lib/postgresql/data","./postgresql.conf:/etc/postgresql/postgresql.conf:ro"]},{"name":"migrations","image":"ghcr.io/modsetter/surfsense-backend:${SURFSENSE_VERSION:-latest}${SURFSENSE_VARIANT:+-${SURFSENSE_VARIANT}}","restart":"no","environment":["DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}}","PYTHONPATH=/app","SERVICE_ROLE=migrate","MIGRATION_TIMEOUT=${MIGRATION_TIMEOUT:-900}"],"depends_on":["db"]},{"name":"redis","image":"redis:8-alpine","restart":"unless-stopped","command":"redis-server --appendonly yes","volumes":["redis_data:/data"]},{"name":"searxng","image":"searxng/searxng:2026.3.13-3c1f68c59","restart":"unless-stopped","environment":["SEARXNG_SECRET=${SEARXNG_SECRET:-surfsense-searxng-secret}"],"volumes":["./searxng:/etc/searxng"]},{"name":"opensandbox-server","image":"opensandbox/server:v0.2.2","restart":"unless-stopped","environment":["OPENSANDBOX_SERVER_API_KEY=${OPENSANDBOX_API_KEY:-surfsense-dev-sandbox}"],"volumes":["/var/run/docker.sock:/var/run/docker.sock","./opensandbox/sandbox.toml:/etc/opensandbox/config.toml:ro","opensandbox_data:/data"]},{"name":"sandbox-image","image":"ghcr.io/modsetter/surfsense-sandbox:${SURFSENSE_VERSION:-latest}"},{"name":"proxy","image":"caddy:2-alpine","restart":"unless-stopped","ports":["${LISTEN_HTTP_PORT:-3929}:80","${LISTEN_HTTPS_PORT:-443}:443"],"environment":["SURFSENSE_SITE_ADDRESS=${SURFSENSE_SITE_ADDRESS:-:80}","CERT_EMAIL=${CERT_EMAIL:-}","CERT_ACME_CA=${CERT_ACME_CA:-https://acme-v02.api.letsencrypt.org/directory}","CERT_ACME_DNS=${CERT_ACME_DNS:-}","TRUSTED_PROXIES=${TRUSTED_PROXIES:-0.0.0.0/0}","SURFSENSE_MAX_BODY_SIZE=${SURFSENSE_MAX_BODY_SIZE:-5GB}"],"volumes":["./proxy/Caddyfile:/etc/caddy/Caddyfile:ro","caddy_data:/data","caddy_config:/config"],"depends_on":["frontend","backend","zero-cache"]},{"name":"backend","image":"ghcr.io/modsetter/surfsense-backend:${SURFSENSE_VERSION:-latest}${SURFSENSE_VARIANT:+-${SURFSENSE_VARIANT}}","restart":"unless-stopped","environment":["DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}}","CELERY_BROKER_URL=${REDIS_URL:-redis://redis:6379/0}","CELERY_RESULT_BACKEND=${REDIS_URL:-redis://redis:6379/0}","REDIS_APP_URL=${REDIS_URL:-redis://redis:6379/0}","CELERY_TASK_DEFAULT_QUEUE=surfsense","PYTHONPATH=/app","UVICORN_LOOP=asyncio","UNSTRUCTURED_HAS_PATCHED_LOOP=1","FILE_STORAGE_LOCAL_PATH=/app/.local_object_store","NEXT_FRONTEND_URL=${NEXT_FRONTEND_URL:-${SURFSENSE_PUBLIC_URL:-http://localhost:${LISTEN_HTTP_PORT:-3929}}}","BACKEND_URL=${BACKEND_URL:-${SURFSENSE_PUBLIC_URL:-http://localhost:${LISTEN_HTTP_PORT:-3929}}}","WHATSAPP_BRIDGE_URL=${WHATSAPP_BRIDGE_URL:-http://whatsapp-bridge:9929}","SEARXNG_URL=${SEARXNG_URL:-http://searxng:8080}","MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-500}","SANDBOX_ENABLED=${SANDBOX_ENABLED:-TRUE}","SANDBOX_PROVIDER=${SANDBOX_PROVIDER:-opensandbox}","DAYTONA_API_KEY=${DAYTONA_API_KEY:-}","DAYTONA_API_URL=${DAYTONA_API_URL:-https://app.daytona.io/api}","DAYTONA_TARGET=${DAYTONA_TARGET:-us}","DAYTONA_SNAPSHOT_ID=${DAYTONA_SNAPSHOT_ID:-}","OPENSANDBOX_DOMAIN=${OPENSANDBOX_DOMAIN:-opensandbox-server:8080}","OPENSANDBOX_API_KEY=${OPENSANDBOX_API_KEY:-surfsense-dev-sandbox}","SANDBOX_IMAGE=${SANDBOX_IMAGE:-ghcr.io/modsetter/surfsense-sandbox:${SURFSENSE_VERSION:-latest}}","SERVICE_ROLE=api"],"volumes":["shared_temp:/shared_tmp","object_store:/app/.local_object_store"],"depends_on":["db","redis","migrations"]},{"name":"celery_worker","image":"ghcr.io/modsetter/surfsense-backend:${SURFSENSE_VERSION:-latest}${SURFSENSE_VARIANT:+-${SURFSENSE_VARIANT}}","restart":"unless-stopped","environment":["DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}}","CELERY_BROKER_URL=${REDIS_URL:-redis://redis:6379/0}","CELERY_RESULT_BACKEND=${REDIS_URL:-redis://redis:6379/0}","REDIS_APP_URL=${REDIS_URL:-redis://redis:6379/0}","CELERY_TASK_DEFAULT_QUEUE=surfsense","PYTHONPATH=/app","FILE_STORAGE_LOCAL_PATH=/app/.local_object_store","SEARXNG_URL=${SEARXNG_URL:-http://searxng:8080}","SANDBOX_ENABLED=${SANDBOX_ENABLED:-TRUE}","SANDBOX_PROVIDER=${SANDBOX_PROVIDER:-opensandbox}","OPENSANDBOX_DOMAIN=${OPENSANDBOX_DOMAIN:-opensandbox-server:8080}","OPENSANDBOX_API_KEY=${OPENSANDBOX_API_KEY:-surfsense-dev-sandbox}","SANDBOX_IMAGE=${SANDBOX_IMAGE:-ghcr.io/modsetter/surfsense-sandbox:${SURFSENSE_VERSION:-latest}}","DAYTONA_API_KEY=${DAYTONA_API_KEY:-}","DAYTONA_API_URL=${DAYTONA_API_URL:-https://app.daytona.io/api}","DAYTONA_TARGET=${DAYTONA_TARGET:-us}","DAYTONA_SNAPSHOT_ID=${DAYTONA_SNAPSHOT_ID:-}","SERVICE_ROLE=worker"],"volumes":["shared_temp:/shared_tmp","object_store:/app/.local_object_store"],"depends_on":["db","redis","migrations","backend"]},{"name":"celery_beat","image":"ghcr.io/modsetter/surfsense-backend:${SURFSENSE_VERSION:-latest}${SURFSENSE_VARIANT:+-${SURFSENSE_VARIANT}}","restart":"unless-stopped","environment":["DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}}","CELERY_BROKER_URL=${REDIS_URL:-redis://redis:6379/0}","CELERY_RESULT_BACKEND=${REDIS_URL:-redis://redis:6379/0}","CELERY_TASK_DEFAULT_QUEUE=surfsense","PYTHONPATH=/app","SERVICE_ROLE=beat"],"depends_on":["db","redis","migrations","celery_worker"]},{"name":"zero-cache","image":"rocicorp/zero:1.6.0","restart":"unless-stopped","environment":["ZERO_UPSTREAM_DB=${ZERO_UPSTREAM_DB:-postgresql://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}?sslmode=${DB_SSLMODE:-disable}}","ZERO_CVR_DB=${ZERO_CVR_DB:-postgresql://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}?sslmode=${DB_SSLMODE:-disable}}","ZERO_CHANGE_DB=${ZERO_CHANGE_DB:-postgresql://${DB_USER:-surfsense}:${DB_PASSWORD:-surfsense}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-surfsense}?sslmode=${DB_SSLMODE:-disable}}","ZERO_REPLICA_FILE=/data/zero.db","ZERO_ADMIN_PASSWORD=${ZERO_ADMIN_PASSWORD:-surfsense-zero-admin}","ZERO_APP_PUBLICATIONS=${ZERO_APP_PUBLICATIONS:-zero_publication}","ZERO_AUTO_RESET=${ZERO_AUTO_RESET:-true}","ZERO_NUM_SYNC_WORKERS=${ZERO_NUM_SYNC_WORKERS:-4}","ZERO_UPSTREAM_MAX_CONNS=${ZERO_UPSTREAM_MAX_CONNS:-20}","ZERO_CVR_MAX_CONNS=${ZERO_CVR_MAX_CONNS:-30}","ZERO_QUERY_URL=${ZERO_QUERY_URL:-http://frontend:3000/api/zero/query}","ZERO_MUTATE_URL=${ZERO_MUTATE_URL:-http://frontend:3000/api/zero/mutate}","ZERO_QUERY_FORWARD_COOKIES=${ZERO_QUERY_FORWARD_COOKIES:-true}","ZERO_QUERY_API_KEY=${ZERO_QUERY_API_KEY:-}","ZERO_AUTH_REVALIDATE_INTERVAL_SECONDS=${ZERO_AUTH_REVALIDATE_INTERVAL_SECONDS:-60}","ZERO_AUTH_RETRANSFORM_INTERVAL_SECONDS=${ZERO_AUTH_RETRANSFORM_INTERVAL_SECONDS:-60}"],"volumes":["zero_cache_data:/data"],"depends_on":["db","migrations"]},{"name":"frontend","image":"ghcr.io/modsetter/surfsense-web:${SURFSENSE_VERSION:-latest}","restart":"unless-stopped","environment":["AUTH_TYPE=${AUTH_TYPE:-LOCAL}","SUNSET_MODE=${SUNSET_MODE:-}","ETL_SERVICE=${ETL_SERVICE:-DOCLING}","DEPLOYMENT_MODE=${DEPLOYMENT_MODE:-self-hosted}","SURFSENSE_BACKEND_INTERNAL_URL=http://backend:8000","MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-500}"],"depends_on":["backend","zero-cache"]}],"exposedPorts":["3929","443"],"dockerRunCommand":"docker run -d --name surfsense -p 3929:3929 --restart always pgvector/pgvector:pg17","podmanRunCommand":"podman run -d --name surfsense -p 3929:3929 --restart always pgvector/pgvector:pg17","skopeoInspectCommand":"skopeo inspect docker://docker.io/pgvector/pgvector:pg17","orasPullCommand":"oras pull pgvector/pgvector:pg17","registryMeta":{"provider":"dockerhub","image":"pgvector/pgvector","canonicalImage":"docker.io/pgvector/pgvector:pg17","latestTag":"pg17","cliCommands":{"dockerRun":"docker run -d --name surfsense -p 3929:3929 --restart always pgvector/pgvector:pg17","dockerPull":"docker pull pgvector/pgvector:pg17","podmanRun":"podman run -d --name surfsense -p 3929:3929 --restart always pgvector/pgvector:pg17","skopeoInspect":"skopeo inspect docker://docker.io/pgvector/pgvector:pg17","orasPull":"oras pull pgvector/pgvector:pg17","composeYaml":"services:\n  surfsense:\n    image: pgvector/pgvector:pg17\n    restart: unless-stopped\n    ports:\n      - \"3929:3929\""}}}