Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
3a5f26b
added nodejs foxx support
bluepal-yaswanth-peravali Nov 28, 2025
e53489f
removed CRLF to LF conversion in node22base docker
bluepal-yaswanth-peravali Nov 28, 2025
2bf3e7f
attended PR comments
bluepal-yaswanth-peravali Dec 2, 2025
991c44e
Fixed clipy warning
bluepal-yaswanth-peravali Dec 2, 2025
45d7bf0
Added versions for npm packages in node base dockerfile
bluepal-yaswanth-peravali Dec 2, 2025
de1bb90
Implement dependency checking to avoid duplicating base packages
bluepal-yaswanth-peravali Dec 2, 2025
30a2ce6
Minor correction in Changelog
bluepal-yaswanth-peravali Dec 2, 2025
32637c6
added auth label in deployment.yaml
bluepal-yaswanth-peravali Dec 5, 2025
e182eeb
added-nodejs-express-support
bluepal-yaswanth-peravali Dec 18, 2025
52d16e6
Merge branch 'main' of https://github.com/arangodb/servicemaker into …
bluepal-yaswanth-peravali Mar 12, 2026
401eb89
add nodejs support
bluepal-yaswanth-peravali Mar 12, 2026
51c902c
removed docs
bluepal-yaswanth-peravali Mar 12, 2026
6178042
modified changlog.md
bluepal-yaswanth-peravali Mar 13, 2026
6e07d5c
modified values.yaml
bluepal-yaswanth-peravali Mar 16, 2026
6ba6e6e
added undici in nodejs test project
bluepal-yaswanth-peravali Mar 17, 2026
5242f52
modified the scripts related to node_modules installation
bluepal-yaswanth-peravali Mar 20, 2026
6f9a414
Add logging and debug output to prepareproject.sh for CI visibility
bluepal-yaswanth-peravali Mar 30, 2026
49687e6
revert commit 6f9a414
bluepal-yaswanth-peravali Mar 31, 2026
5751c44
Merge branch 'main' of https://github.com/arangodb/servicemaker into …
bluepal-yaswanth-peravali Apr 7, 2026
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
132 changes: 132 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Changelog

All notable changes to ServiceMaker will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

#### Node.js Project Support

- **Node.js Base Image**: Added `baseimages/Dockerfile.node22base` for creating Node.js 22 base images
- Base image `arangodb/node22base:latest` provides immutable foundation for all Node.js services
- Installs Node.js 22 from NodeSource
- Pre-installs common packages with version pinning: `arangojs@^10.2.2`, `semver@^7.6.3`, `lodash@^4.17.21`, `dayjs@^1.11.10`, `uuid@^9.0.1`, `dotenv@^16.4.5`, `axios@^1.7.2`, `joi@^17.13.3`, `winston@^3.15.0`, `async@^3.2.5`, `jsonwebtoken@^9.0.2`, `bcrypt@^5.1.1`
- Creates base `node_modules` at `/home/user/node_modules` with SHA256 checksums for dependency tracking
- Base image is immutable and pre-scanned for security vulnerabilities
- Added to `baseimages/imagelist.txt` as `node22base`

- **Node.js Dockerfile Template**: Created `Dockerfile.nodejs.template` for building Node.js service images
- Uses Node.js 22 base image (`arangodb/node22base:latest`)
- Copies project directory directly to `/project/{project-name}/`
- Configures working directory and user permissions
- Sets `NODE_PATH` environment variable for module resolution (project `node_modules` first, then base)
- Executes `prepareproject-nodejs.sh` for dependency management
- Runs applications directly with `node {ENTRYPOINT}` command

- **Dependency Management System**: Added intelligent dependency resolution to avoid duplicating base packages
- **`scripts/check-base-dependencies.js`**: Analyzes project dependencies against base packages
- Checks if packages exist in base `node_modules` at `/home/user/node_modules`
- Uses `semver` to verify version compatibility between base and project requirements
- Outputs JSON with packages that need installation (missing or incompatible versions) and a `filteredDependencies` object for rewriting `package.json`
- Provides detailed dependency analysis summary to stderr

- **`scripts/prepareproject-nodejs.sh`**: Installs only missing or incompatible dependencies
- Base `node_modules` at `/home/user/node_modules` is immutable and never copied
- Pre-install analysis using `check-base-dependencies.js` to identify required packages
- Temporarily rewrites `package.json` to contain only the missing dependencies before running `npm install --production`, then restores the original — this prevents npm 7+ from reconciling the full dependency tree and re-installing packages already present in the base image
- Results in smaller project `node_modules` and `project.tar.gz` files
- Maintains base image immutability for security scanning

- **Project Type Detection**: Extended `detect_project_type()` in `src/main.rs` to support Node.js projects
- Detects Node.js projects by presence of `package.json` file
- Requires absence of `services.json` and `manifest.json` (distinguishes from Foxx services)
- Project type: `nodejs` (for Node.js applications)
- Returns error if `services.json` or `manifest.json` is found (not supported)

- **Entrypoint Auto-Detection**: Added automatic entrypoint detection for Node.js projects
- Function `detect_nodejs_entrypoint()` checks `package.json` `main` field first
- Falls back to extracting from `start` script if `main` is not present
- Supports scripts like `"start": "node index.js"` format
- Provides sensible default (`index.js`) if detection fails

- **Package.json Metadata Support**: Added functions to read Node.js project metadata
- `read_name_from_package_json()`: Extracts project name from `package.json`
- `read_service_info_from_package_json()`: Extracts name and version for Helm charts
- Used for auto-detecting project name and generating Helm charts

- **Environment Variable Support**: Added support for reading environment variables from `.env.example` files
- Function `read_env_example()` automatically reads `.env.example` file if present in project root
- Parses `KEY=VALUE` format with support for single and double quotes
- Handles comments (lines starting with `#`) and empty lines
- Auto-quotes values containing spaces or special characters for Docker `ENV` directives
- Injects environment variables into Dockerfile for all project types (Python and Node.js)
- Works seamlessly with existing project structures

- **Default Base Image Constants**: Introduced compile-time constants for default base images
- `DEFAULT_PYTHON_BASE_IMAGE`: `"arangodb/py13base:latest"`
- `DEFAULT_NODEJS_BASE_IMAGE`: `"arangodb/node22base:latest"`
- Automatically selects appropriate default when user doesn't specify base image
- Tracks explicit user intent to avoid overriding user choices

### Changed

- **Main Application Logic**: Extended `src/main.rs` to support Node.js projects
- Added Node.js project type detection and handling in main function
- Added entrypoint auto-detection for Node.js projects from `package.json`
- Added environment variable reading from `.env.example` for all project types
- Added Dockerfile modification function for Node.js projects (`modify_dockerfile_nodejs`)
- Added Node.js preparation script (`prepareproject-nodejs.sh`) and dependency checker (`check-base-dependencies.js`) to embedded scripts list
- Modified Dockerfile generation to use appropriate template based on project type (Python or Node.js)
- Updated Helm chart generation to support both Python and Node.js projects
- Enhanced project metadata extraction to support both `pyproject.toml` and `package.json`
- Updated file copying logic to skip `node_modules` directories (prevents copying local dependencies)

- **Entrypoint Script**: Enhanced `baseimages/scripts/entrypoint.sh` to support Node.js services
- Detects Node.js applications by checking for `package.json` without `services.json` or `manifest.json`
- Automatically runs `node {ENTRYPOINT}` for Node.js applications
- Maintains backward compatibility with Python services
- Uses `NODE_PATH` environment variable for module resolution

- **Archive Creation Script**: Updated `scripts/zipper.sh` to handle both Python and Node.js projects
- Includes `the_venv/` directory for Python projects
- Includes project directory (which contains `node_modules/`) for Node.js projects
- Provides informational messages when `node_modules` is detected
- Enhanced documentation with clear comments explaining both project types

- **File Copying Logic**: Updated `copy_dir_recursive()` in `src/main.rs` to skip `node_modules` directories
- Prevents copying local `node_modules` which should be installed fresh in Docker build
- Ensures only project source code is copied, dependencies are installed in container
- Maintains consistency with Python's `.venv` exclusion

- **Base Image List**: Updated `baseimages/imagelist.txt` to include `node22base` entry

---

## [0.9.2] - 2024-XX-XX

### Features

- Python service support with `pyproject.toml`
- Base image management for Python 3.13 (`arangodb/py13base:latest`)
- Docker image building and pushing
- Helm chart generation
- Project tar.gz creation
- Virtual environment management with `uv`
- Automatic entrypoint detection for Python projects (single .py file)
- Project metadata extraction from `pyproject.toml`

---

## Notes

- All changes maintain backward compatibility with existing Python projects
- Node.js support is additive and does not affect Python service functionality
- Node.js applications are detected automatically and require no special configuration files
- Environment variables from `.env.example` are automatically injected into Docker images
- Base images must be built separately using `baseimages/build.sh` before use
- Windows users should use WSL or Linux environment for building base images
- The dependency checking system ensures efficient builds by avoiding package duplication while maintaining compatibility
26 changes: 26 additions & 0 deletions Dockerfile.nodejs.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Dockerfile template for Node.js/Express projects
# This template is used for Node.js projects with package.json (no services.json or manifest.json)
FROM {BASE_IMAGE}

USER root

# Copy scripts and project files
COPY ./scripts /scripts
COPY {PROJECT_DIR} /project/{PROJECT_DIR}
RUN chown -R user:user /project/{PROJECT_DIR}

USER user
WORKDIR /project/{WORKDIR}

# Set NODE_PATH to resolve from project node_modules first, then base node_modules
# This allows npm to install only missing/incompatible packages in project directory
# while still accessing base packages from /home/user/node_modules
ENV NODE_PATH={NODE_PATH}

# Install project dependencies (only missing/incompatible ones)
RUN /scripts/prepareproject-nodejs.sh

EXPOSE {PORT}

# Run Node.js application directly using node
CMD ["node", "{ENTRYPOINT}"]
44 changes: 44 additions & 0 deletions baseimages/Dockerfile.node22base
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM debian:trixie-slim

COPY ./scripts /scripts
RUN /scripts/debinstall.sh

# Install Node.js 22
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
apt-get install -y nodejs && \
apt-get clean

WORKDIR /home/user
USER user

# Create base node_modules with standard packages (immutable, pre-scanned)
# This location is used by all projects and should never be modified
# Standard packages are selected to benefit most projects while keeping image size reasonable
RUN npm init -y && \
npm install \
express@^4.18.2 \
arangojs@^10.2.2 \
# Dependency checking utility
semver@^7.6.3 \
# 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

# Create checksums for base node_modules (for tracking, base remains immutable)
RUN find node_modules -type f -print0 | \
xargs -0 sha256sum > sums_sha256

CMD [ "/scripts/entrypoint.sh" ]
1 change: 1 addition & 0 deletions baseimages/imagelist.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
py13base
py13cugraph
py13torch
node22base
24 changes: 17 additions & 7 deletions baseimages/scripts/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,26 @@ if test -e project.tar.gz ; then
tar xzvf project.tar.gz > /dev/null
fi

# Run the entrypoint if configured:
# Detect service type and run accordingly
if test -e entrypoint ; then
ENTRYPOINT=$(cat entrypoint)
echo Running project ...
. /home/user/.local/bin/env
. /home/user/the_venv/bin/activate
for p in /project/the_venv/lib/python*/site-packages ; do
export PYTHONPATH=$p
done
exec python $ENTRYPOINT

# Check if it's a Node.js application (package.json exists, no services.json or manifest.json)
if [ -f "package.json" ]; then
# Node.js application
echo "Detected Node.js application"
exec node $ENTRYPOINT
else
# Python service (has pyproject.toml or no package.json)
echo "Detected Python service"
. /home/user/.local/bin/env
. /home/user/the_venv/bin/activate
for p in /project/the_venv/lib/python*/site-packages ; do
export PYTHONPATH=$p
done
exec python $ENTRYPOINT
fi
fi

echo No entrypoint found, running bash instead...
Expand Down
4 changes: 4 additions & 0 deletions charts/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ spec:
release: {{ .Release.Name }}
type: deployment
profiles.arangodb.com/deployment: deployment
integration.profiles.arangodb.com/authn: v1
integration.profiles.arangodb.com/authz: v1
permissions.arangodb.com/token: {{ template "template.releaseName" . }}-token
spec:
serviceAccountName: {{ template "template.releaseName" . }}
containers:
- name: {SERVICE_NAME}
image: {IMAGE_NAME}
Expand Down
17 changes: 17 additions & 0 deletions charts/templates/service-account.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "template.releaseName" . }}
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ template "template.name" . }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
release: {{ .Release.Name }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
34 changes: 34 additions & 0 deletions charts/templates/token-permissions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: permission.arangodb.com/v1alpha1
kind: ArangoPermissionToken
metadata:
name: {{ template "template.releaseName" . }}-token
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ template "template.name" . }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
release: {{ .Release.Name }}
spec:
deployment:
name: {{ .Values.arangodb_platform.deployment.name }}
ttl: {{ .Values.auth.service_token.ttl | default "1h" | quote }}
{{- if .Values.auth.service_token.roles }}
roles:
{{- range .Values.auth.service_token.roles }}
- {{ . | quote }}
{{- end }}
{{- end }}
policy:
statements:
{{- range .Values.auth.service_token.policy_statements }}
- actions:
{{- range .actions }}
- {{ . | quote }}
{{- end }}
resources:
{{- range .resources }}
- {{ . | quote }}
{{- end }}
effect: {{ .effect | quote }}
{{- end }}
14 changes: 13 additions & 1 deletion charts/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@ imagePullSecrets: []
# Deployment
arangodb_platform:
deployment:
name: PLACEHOLDER
name: deployment

# Profiles
profiles: ""

auth:
service_token:
ttl: "1h"
roles:
- "{SERVICE_NAME}-service"
policy_statements:
- actions:
- "db:*"
resources:
- "db:database:*"
effect: "Allow"
Loading