During a webpack step in our builds, a large number of unexpected parallel node processes are started, leading to the build hanging and finally bailing out due to exceeding the 4 GB memory quota.
We don’t see the parallel node processes when running the exact same steps locally, in the exact same environment (including env variables set by Circle and by ourselves in the build config). So locally the build takes no more than 1.5 GB of memory.
Here’s a link to the minimal build configuration where this behaviour can be observed:. I’ve also collected a memory profile by polling all node
processes in ps aux
every second.
local results (expected)
running time
59 s
peak memory consumption
< 1.5 GB
CircleCI results ()
running time
- output freezes after 3 min 38 s
- SSH session terminates after 4 min 18 s
- Circle reports build step duration of 8 min 40 s
peak memory consumption
> 4.3 GB
other idiosyncracies
- note that the profile only reports 1 min 2 s in the
TIME
column ofps aux
just before the freeze (just - also notice how in the profile the
TIME
column doesn’t increment by 1 on each actual second as it should – it runs a lot slower
profiling method
Build analysed https://circleci.com/gh/kalohq/frontend/24882#tests/containers/1
Locally, all steps run 1:1 as in the build, with environment variables 1:1 copied over from the steps Start container (1)
and echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" echo "CODECOV_TOKEN=$CODECOV_TOKEN" echo "DOCKER_EMAIL=$DOCKER_EMAIL" echo "DOCKER_PASS=$DOCKER_PASS" echo "DOCKER_USER=$DOCKER_USER" echo "GITHUB_TOKEN=$GITHUB_TOKEN" echo "HIPCHAT_V1_KEY=$HIPCHAT_V1_KEY" echo "LYSTACOP_SECRET=$LYSTACOP_SECRET" echo "RELEASE_ROCKET_SLACK_TOKEN=$RELEASE_ROCKET_SLACK_TOKEN" echo "SALT_KEY=$SALT_KEY" (1)
Profile run during step case $CIRCLE_NODE_INDEX in 0) true;; 1) ./bin/build.sh -e docker;; esac (1)
.
Profiling loop:
while sleep 1; do
echo -e '\n\n\n\n\n'
ps aux | sort -k6,6n | grep node | grep -v Applications | grep -v 'grep node'
done