-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Closed
Description
Version: denoland/deno:2.3.5
🐞 Deno FFI Plugin Load Error in Docker on MacBook M4 Pro
📌 Issue Summary
When running a Deno app using deno-bcrypt in Docker on a MacBook M4 Pro (or any Apple Silicon chip), you may encounter this error:
error: Uncaught (in promise) Error: Could not open library: Could not open library: /deno-dir/plug/https/github.com/f1dff8b6d21e6f91fc972acd4a3ce646b546535da3cabec18138cf42dc67ccc9.so: cannot open shared object file: No such file or directory
⚙️ Background
deno-bcrypt uses FFI with Deno.dlopen() to load .so binaries.
These binaries are not universal; they are compiled for specific architectures.
Your machine uses the ARM64 (aarch64) architecture, but Docker pulls the x86_64 or Linux-only builds by default.
The plugin’s native .so file either:
Doesn't exist for aarch64 in the plugin’s releases
Or, fails to download or install in a compatible format
🧪 How to Reproduce
bash
Always show details
Copy
docker run -it -p 1993:1993 -v $PWD:/app denoland/deno:2.3.5 run --allow-net --allow-ffi --allow-env --allow-read /app/main.ts
Results in:
bash
Always show details
Copy
error: Could not open library: .../github.com/...so: cannot open shared object file: No such file or directory
🔍 Root Cause
deno-bcrypt lacks .so binaries for aarch64 Linux in its GitHub releases.
Deno tries to download one, fails, and doesn’t fall back to build-from-source.
Docker does not persist plugin cache across runs unless mounted explicitly.
Docker image is Linux-based (alpine or debian), which adds complexity when running on macOS ARM chips.
✅ Workarounds
✅ 1. Use Pure JS/TS Hashing Library
Switch to a fallback implementation like:
bcryptjs
argon2-browser
They are slower, but don't depend on FFI and work across all environments.
✅ 2. Custom Docker Image with Cached Plugin Directory
Create a Dockerfile:
Dockerfile
Always show details
Copy
FROM denoland/deno:2.3.5
WORKDIR /app
COPY . .
ENV DENO_DIR=/app/deno-dir
CMD ["run", "--allow-net", "--allow-read", "--allow-env", "--allow-ffi", "main.ts"]
Then run:
bash
Always show details
Copy
docker build -t my-deno-app .
docker run -it -v $PWD:/app my-deno-app
✅ 3. Persist Deno Plugin Cache Using a Volume
Mount the .cache/deno path explicitly:
bash
Always show details
Copy
docker run -it \\
-v $PWD:/app \\
-v $HOME/.cache/deno:/deno-dir \\
-e DENO_DIR=/deno-dir \\
denoland/deno:2.3.5 run --allow-net --allow-read --allow-env --allow-ffi /app/main.ts
❌ Not Recommended
❌ Expecting Deno to always download a matching .so binary
❌ Using native FFI in a cross-architecture environment without fallback
🧠 Conclusion
This issue is not due to a bug in Docker or Deno itself. It’s a consequence of:
Using native FFI (deno-bcrypt) on an unsupported architecture
Not persisting Deno’s plugin download/cache directory across runs
💡 The best long-term solution is to avoid FFI-dependent libraries unless they offer universal or ARM-compatible builds.
🛠️ Recommendations
Request aarch64-unknown-linux-gnu builds from the plugin maintainer.
Use pure TypeScript libraries unless performance mandates FFI.
Avoid native plugins for apps that need portability across Docker, macOS, or ARM-based servers.
"""
Metadata
Metadata
Assignees
Labels
No labels