Skip to content
Merged
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
45 changes: 45 additions & 0 deletions image/scripts/check_clone3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/sh

# Debian 13 uses a glibc that creates threads with the clone3 syscall.
# It expects an ENOSYS error before falling back to the old method.
#
# Docker started returning ENOSYS in 20.10.10. Older versions
# used EPERM instead.

# Check if clone3 is denied. It is syscall 435 on every architecture that both
# Debian 13 and node are available for. Giving it a size of 0 is rejected with
# EINVAL before the kernel creates anything, so this only tells us whether the
# syscall can be reached.
#
# Exit 3 means it was denied. If the status is different, it either passed
# or failed for an unknown reason, and we assume it works.
python3 -c "
import ctypes, errno, sys
libc = ctypes.CDLL(None, use_errno=True)
ctypes.set_errno(0)
libc.syscall(435, None, 0)
sys.exit(3 if ctypes.get_errno() == errno.EPERM else 0)
" 2>/dev/null

if [ $? -ne 3 ]; then
exit 0
fi

cat >&2 <<'EOF'

=> ERROR: The Docker version is outdated

This version of zodern/meteor uses Debian 13, which requires Docker 20.10.10 or newer.

To fix this, either:

* Update Docker to 20.10.10 or newer, or
* Use an older version of zodern/meteor based on Debian 11:
zodern/meteor:0 (or zodern/meteor:0-root)

Adding "--security-opt seccomp=unconfined" to docker run also works, but only
when running the app. It can not be used for docker build.

EOF

exit 1
5 changes: 5 additions & 0 deletions image/scripts/setup_nvm.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
set -e

# On older docker versions, `nvm use` errors with a confusing message.
# First check if we are using a compatible docker version.
sh /home/app/scripts/check_clone3.sh

export NVM_DIR="/home/app/.nvm"
[ -s "$NVM_DIR/nvm.sh" ]
. "$NVM_DIR/nvm.sh"
Expand Down
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ Docker image to run Meteor apps.

Version 1 changed the base image from Debian 11 (bullseye) to Debian 13 (trixie). This is needed to support the uws DDP transport in Meteor 3.5. Old Meteor versions are still compatible. If the new base image causes problems for your app, you can use `zodern/meteor:0` or `zodern/meteor:0-root`.

Version 1 needs Docker 20.10.10 or newer, due to changes in Debian 13. Use `zodern/meteor:0` if you can not update Docker. Using an older version of Docker can result in `node[122]: pthread_create: Operation not permitted. nvm is not compatible with the npm config "prefix" option: currently set to "" `


## How To Use

### Permissions
Expand Down
10 changes: 10 additions & 0 deletions tests/clone3-eperm-seccomp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["clone3"],
"action": "SCMP_ACT_ERRNO",
"errnoRet": 1
}
]
}
37 changes: 37 additions & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ sudo rm -rf /tmp/docker-meteor-tests
mkdir /tmp/docker-meteor-tests
cp -r ../ /tmp/docker-meteor-tests
cd /tmp/docker-meteor-tests/tests
TESTS_DIR="$PWD"

rm -rf ./app
rm -rf ./bundle
Expand Down Expand Up @@ -188,6 +189,37 @@ test_latest() {
test_uws_transport
}

# Docker older than 20.10.10 denies the clone3 syscall with EPERM, which stops
# node from creating threads on the Debian 13 base image. We can't fix that from
# inside the image, but we should explain it instead of letting nvm report the
# npm "prefix" option as "". clone3-eperm-seccomp.json reproduces the old
# default seccomp profile.
test_clone3_check() {
echo "=> Checking clone3 detection"

set +e
output=$(docker run --rm \
--security-opt seccomp="$TESTS_DIR/clone3-eperm-seccomp.json" \
--entrypoint bash \
"$DOCKER_IMAGE" /home/app/scripts/setup_nvm.sh 2>&1)
code=$?
set -e

if [ "$code" -eq 0 ]; then
echo "FAIL: expected a runtime without clone3 to be rejected"
echo "$output"
exit 1
fi

if ! echo "$output" | grep -q "20.10.10"; then
echo "FAIL: the error did not say which Docker version is needed"
echo "$output"
exit 1
fi

echo "SUCCESS"
}

test_versions() {
echo "--- Testing Docker Image $DOCKER_IMAGE ---"

Expand Down Expand Up @@ -232,6 +264,11 @@ export DISABLE_REACT_FAST_REFRESH="true"

DOCKER_IMAGE="zodern/meteor"
NPM_OPTIONS=""

if [[ -z ${METEOR_TEST_OPTION+x} || "$METEOR_TEST_OPTION" == "latest" ]]; then
test_clone3_check
fi

test_versions

DOCKER_IMAGE="zodern/meteor:root"
Expand Down
Loading