-
Notifications
You must be signed in to change notification settings - Fork 0
added nodejs foxx support #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
bluepal-yaswanth-peravali
commented
Nov 28, 2025
- Added Node.js/Foxx service support with base image and Dockerfile template
- Implemented automatic wrapper structure generation for single service directories
- Added dependency management with safety checks and recovery mechanisms
- Extended project type detection and CLI arguments (--mount-path)
- Enhanced entrypoint script for auto-detection of service types
- Maintains backward compatibility with Python services
neunhoef
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments. All in all this goes in the right direction, but we must avoid the copying of the dependencies to /project.
| - Added conditional compilation for Unix-specific file permissions (`#[cfg(unix)]`) | ||
| - Windows builds now skip `set_mode()` calls that are Unix-only | ||
|
|
||
| ### Technical Details |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the technical details a re not needed in the Changelog. They should be somewhere, but here, we would like to at most have a link to that other place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technical details are moved to docs/ARCHITECTURE.md and link to that file is placed here
baseimages/Dockerfile.node22base
Outdated
| RUN mkdir -p base_node_modules && \ | ||
| cd base_node_modules && \ | ||
| npm init -y && \ | ||
| npm install @arangodb/node-foxx@^0.0.1-alpha.0 \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to come up with a good selection of "standard" tools and libs to include into the base image, so that many projects can benefit from having a good part of their dependencies in the base image. This crucially depends on us finding a way to avoid copying all dependencies to /project/node_modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the following npm libraries to the base image with version pinning for reproducible builds:
Essential utilities: lodash@^4.17.21, dayjs@^1.11.10, uuid@^9.0.1, dotenv@^16.4.5
HTTP clients: axios@^1.7.2
Validation: joi@^17.13.3
Logging: winston@^3.15.0
Async utilities: async@^3.2.5
Security: jsonwebtoken@^9.0.2, bcrypt@^5.1.1
As suggested, avoided copying dependencies to /project/node_modules. npm installs only project-specific dependencies that are missing or incompatible with the base packages in /home/user/node_modules. This keeps the base image immutable while allowing projects to override versions when needed.
scripts/prepareproject-nodejs.sh
Outdated
| # We're already in /project/{PROJECT_DIR} from the Dockerfile WORKDIR | ||
| PROJECT_DIR=$(pwd) | ||
|
|
||
| # Copy base node_modules if they exist in base image |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do not want this. This is totally against the spirit of "base images". If we do this, we might as well start with an empty base image and put everything. The idea should be this:
Assume a node project needs libraries A, B, C, D, E and F. It declares all of them in its package.json file.
The idea of a "base image" is now to have a Docker image, which is totally immutable (allowing to pre-scan it for security vulnerabilities), which includes a suitable nodejs version (say 22) and might include some of these libraries already. So for example, it could contain A, B and C in versions, which fit would fulfill the requirements of the project.
But libraries D, E and F happen to not be included in the base image.
Now we need a way to use standard tooling to create a runnable environment. So the idea is that the base image contains its stuff under the path /home/user/node_modules (including A, B, and C in the right version).
I think we should now be able to tell npm to create a /project/node_modules, which contains only D, E and F in the right version, so that /project/node_modules/** and /home/user/node_modules together constitute the right environment for the project to run.
This has multiple benefits:
- We use automatic tools to install the project.
- We only put the additional stuff in /project, so that a potential project.tar.gz is as small as possible.
- We keep the base image immutable to allow for pre-scanning.
- We only have to scan the stuff in /project for vulnerabilities.
- We get a derived docker image, which is self-contained, and we get a project.tar.gz, which can be put on top of the base images, so that with this and the base image (immutable) we can run the project, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented dependency checking to avoid duplication and align with the base image approach.
What I implemented:
- Pre-install dependency check: check-base-dependencies.js analyzes each dependency in package.json against /home/user/node_modules
- Version compatibility: Uses semver to verify if base package versions satisfy project requirements
- Selective installation: Only packages missing from base or with incompatible versions are installed to /project/{service-name}/node_modules
- Result:
- Base image (/home/user/node_modules) contains A, B, C (immutable, pre-scanned)
- Project (/project/{service-name}/node_modules) contains only D, E, F (missing packages)
- NODE_PATH resolves from both locations at runtime
| @@ -0,0 +1,202 @@ | |||
|
|
|||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove the license file here. it is our own code, so we are allowed to do this. This is not relevant for the test project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the License file
src/main.rs
Outdated
| } | ||
|
|
||
| // Set default base image for Node.js if not specified | ||
| if args.base_image == "arangodb/py13base:latest" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is brittle, since we assume here that the default, which is elsewhere, is exactly this, if we change this later, this code here will break. Rather, let's introduce a flag which says if the base image has been set explicitly, and if not, and we see it is a node project, we set the node default. We should also introduce compile time constants for these default images.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented:
- Compile-time constants (DEFAULT_PYTHON_BASE_IMAGE, DEFAULT_NODEJS_BASE_IMAGE)
- Flag to track explicit user choice (base_image_explicitly_set)
- Smart defaults: only set Node.js default if user didn't explicitly set base image
- Removed magic string comparisons. Defaults are defined once as constants, so future changes won't break the logic.
src/main.rs
Outdated
| } | ||
|
|
||
| // Set default base image for Node.js if not specified | ||
| if args.base_image == "arangodb/py13base:latest" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented:
- Compile-time constants (DEFAULT_PYTHON_BASE_IMAGE, DEFAULT_NODEJS_BASE_IMAGE)
- Flag to track explicit user choice (base_image_explicitly_set)
- Smart defaults: only set Node.js default if user didn't explicitly set base image
- Removed magic string comparisons. Defaults are defined once as constants, so future changes won't break the logic.
src/main.rs
Outdated
|
|
||
| /// Mount path for the service (required for Foxx services, e.g., /itz) | ||
| #[arg(long)] | ||
| mount_path: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have to give the mount path here? Should this not be a choice which happens when we actually deploy the project? The helm chart makes a guess (I think it uses /_services/<name of project> or so. But in principle, this could be changed at deploy time. If we add the option here, we should also use this to change the helm chart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Foxx services require a mount path in services.json (read by node-foxx at runtime), so I added this in CLI options. But, Since the Helm chart manages routing at deployment, now I removed --mount-path from CLI options and hardcode "/" in the generated services.json as a default.