Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ ENV NEXT_TELEMETRY_DISABLED=1
ENV DATA_DIR=/data
ENV DATA_CACHE_DIR=$DATA_DIR/.sourcebot
ENV SOURCEBOT_PUBLIC_KEY_PATH=/app/public.pem
# Per-process Node heap caps (MB) for the web/backend processes, consumed by
# supervisord.conf. entrypoint.sh overrides these at runtime, computing them from
# the container's memory limit; these defaults (0 = V8 default) are a backstop so
# supervisord's %(ENV_...)s interpolation resolves even if entrypoint is bypassed.
ENV WEB_MAX_OLD_SPACE_SIZE=0
ENV BACKEND_MAX_OLD_SPACE_SIZE=0
# PAPIK = Project API Key
# Note that this key does not need to be kept secret, so it's not
# necessary to use Docker build secrets here.
Expand Down
46 changes: 46 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -196,5 +196,51 @@ DATABASE_URL="$DATABASE_URL" yarn workspace @sourcebot/db prisma:migrate:prod
# Create the log directory if it doesn't exist
mkdir -p /var/log/sourcebot

# --- Node.js heap sizing ---------------------------------------------------
# `web` and `backend` are Node processes that share this container's memory
# limit with `zoekt`. V8's default old-space heap does NOT track the cgroup
# limit, so by default `web` caps near ~4GB regardless of a larger container
# (and OOMs there once its working set grows). Derive a per-process
# --max-old-space-size from the container's memory limit so each Node process
# gets an appropriate slice without the two heaps over-committing the cgroup.
# These values are passed to the `web`/`backend` commands in supervisord.conf.
# A value of 0 means "let V8 pick its own default" (used when no limit is set).
#
# Optional overrides (env):
# WEB_HEAP_PERCENT / BACKEND_HEAP_PERCENT - % of the container limit
# (defaults: 55 / 20)
# WEB_MAX_OLD_SPACE_SIZE / BACKEND_MAX_OLD_SPACE_SIZE - absolute MB; when set,
# used as-is (skips the %).
container_mem_limit_mb() {
_limit=""
if [ -r /sys/fs/cgroup/memory.max ]; then # cgroup v2
_limit=$(cat /sys/fs/cgroup/memory.max 2>/dev/null)
elif [ -r /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then # cgroup v1
_limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null)
fi
# "max" (v2) or the v1 unlimited sentinel (~2^63) both mean "no limit".
case "$_limit" in
''|max) echo 0; return;;
esac
if [ "$_limit" -gt 9223372036854000000 ] 2>/dev/null; then echo 0; return; fi
echo $(( _limit / 1024 / 1024 ))
}

resolve_heap_mb() { # $1=explicit override $2=percent $3=default-percent
if [ -n "$1" ]; then echo "$1"; return; fi
_pct="${2:-$3}"
if [ "$MEM_LIMIT_MB" -gt 0 ]; then echo $(( MEM_LIMIT_MB * _pct / 100 )); else echo 0; fi
}

MEM_LIMIT_MB=$(container_mem_limit_mb)
export WEB_MAX_OLD_SPACE_SIZE=$(resolve_heap_mb "$WEB_MAX_OLD_SPACE_SIZE" "$WEB_HEAP_PERCENT" 55)
export BACKEND_MAX_OLD_SPACE_SIZE=$(resolve_heap_mb "$BACKEND_MAX_OLD_SPACE_SIZE" "$BACKEND_HEAP_PERCENT" 20)

if [ "$MEM_LIMIT_MB" -gt 0 ]; then
echo -e "\e[34m[Info] Container memory limit: ${MEM_LIMIT_MB}MB. Node heap caps (--max-old-space-size) — web: ${WEB_MAX_OLD_SPACE_SIZE}MB, backend: ${BACKEND_MAX_OLD_SPACE_SIZE}MB.\e[0m"
else
echo -e "\e[34m[Info] No container memory limit detected; using V8 default heap sizing for web/backend.\e[0m"
fi

# Run supervisord
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf
7 changes: 5 additions & 2 deletions supervisord.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ stdout_logfile_maxbytes=0
redirect_stderr=true

[program:web]
command=./prefix-output.sh node packages/web/server.js
# --max-old-space-size is computed from the container memory limit in entrypoint.sh
# (0 = V8 default). Per-process so web/backend don't over-commit the shared cgroup.
command=./prefix-output.sh node --max-old-space-size=%(ENV_WEB_MAX_OLD_SPACE_SIZE)s packages/web/server.js
priority=20
autostart=true
autorestart=true
Expand All @@ -24,7 +26,8 @@ stdout_logfile_maxbytes=0
redirect_stderr=true

[program:backend]
command=./prefix-output.sh node packages/backend/dist/index.js
# See [program:web]; cap computed from the container memory limit in entrypoint.sh.
command=./prefix-output.sh node --max-old-space-size=%(ENV_BACKEND_MAX_OLD_SPACE_SIZE)s packages/backend/dist/index.js
priority=20
autostart=true
autorestart=true
Expand Down
Loading