diff --git a/changelog.md b/changelog.md index d2be8c4..27e838e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,18 @@ # Changelog +## 2025-10-26 - 5.0.147 - feat(nvm) +Enable full nvm support in Docker builds and CI/CD workflows + +- Added global nvm configuration in /etc/bash.bashrc (prepended before interactive check) +- Created bash-with-nvm wrapper for Dockerfile RUN commands +- Added intelligent ENTRYPOINT for runtime nvm support +- nvm commands now work directly in Dockerfile RUN without manual sourcing +- nvm commands work in CI/CD workflow bash -c scripts automatically +- Changed default SHELL directive to use nvm wrapper +- Backward compatible: npmci still available, ENV PATH preserved for fallback +- Non-bash shells fall back to ENV PATH (v20.12.2) +- Both interactive and non-interactive shells have full nvm access + ## 2024-11-17 - 5.0.146 - fix(Dockerfiles) Correct Docker image source host in various Dockerfiles diff --git a/readme.hints.md b/readme.hints.md index 0519ecb..df8a5d4 100644 --- a/readme.hints.md +++ b/readme.hints.md @@ -1 +1,84 @@ - \ No newline at end of file +# Technical Implementation Notes + +## NVM Support (v5.0.147) + +### How NVM Works in This Image + +The image provides full nvm support in three contexts: + +1. **Dockerfile RUN commands**: Via `/usr/local/bin/bash-with-nvm` wrapper +2. **CI/CD workflow scripts**: Via /etc/bash.bashrc prepended configuration +3. **Interactive shells**: Via /etc/bash.bashrc standard loading + +### Key Components + +#### 1. /etc/bash.bashrc (Prepended NVM Init) +- NVM initialization is **prepended** to /etc/bash.bashrc +- **Critical**: Placed BEFORE the `[ -z "$PS1" ] && return` line +- This ensures nvm loads in both interactive AND non-interactive bash shells +- Location: Lines 1-3 of /etc/bash.bashrc + +#### 2. /usr/local/bin/bash-with-nvm (Build-Time Wrapper) +- Wrapper script that sources nvm before executing Dockerfile RUN commands +- Used via `SHELL ["/usr/local/bin/bash-with-nvm"]` directive +- Ensures nvm is available during `docker build` without manual sourcing + +#### 3. /usr/local/bin/docker-entrypoint.sh (Runtime Wrapper) +- ENTRYPOINT that detects `bash -c` commands +- Automatically injects `source /etc/bash.bashrc` for bash -c invocations +- Passes through other commands unchanged +- Critical for CI/CD workflow support + +#### 4. ENV PATH Fallback +- Maintains `ENV PATH` pointing to default Node v20.12.2 +- Ensures non-bash shells (sh, dash) still have node access +- Backward compatible with existing usage + +### Why This Approach Works + +**Problem**: nvm is a shell function, not a binary +- Can't be found in PATH +- Must be sourced into each shell session +- Docker's /bin/sh doesn't support bash functions + +**Solution Strategy**: +1. Prepend nvm init to /etc/bash.bashrc (before early return) +2. Use wrapper for build-time (SHELL directive) +3. Use ENTRYPOINT for runtime (docker run / CI/CD) +4. Keep ENV PATH for fallback + +### Version Persistence Limitation + +Each Dockerfile RUN command creates a new shell: + +```dockerfile +RUN nvm install 18 # Installs but doesn't persist +RUN node --version # Shows v20.12.2 (ENV PATH) +``` + +**Workaround**: Chain commands or set default: + +```dockerfile +RUN nvm install 18 && nvm alias default 18 +RUN node --version # Now shows v18.x.x +``` + +### Testing Performed + +- ✅ Dockerfile RUN: `nvm install`, `nvm use`, version switching +- ✅ Runtime bash -c: All nvm commands work +- ✅ CI/CD workflows: Tested in .gitea/workflows context +- ✅ Backward compat: pnpm, npmci, ENV PATH fallback +- ✅ Multi-stage builds: nvm available in all stages +- ✅ Interactive shells: Full nvm access + +### Maintenance Notes + +**If updating nvm version**: Modify line 86 in Dockerfile + +**If base image changes**: Verify /etc/bash.bashrc structure still has early return pattern + +**If ENTRYPOINT conflicts**: Users can override with `--entrypoint` flag: +```bash +docker run --entrypoint /bin/bash image -c "commands" +``` diff --git a/readme.md b/readme.md index a53c693..8cc67b1 100644 --- a/readme.md +++ b/readme.md @@ -41,6 +41,65 @@ RUN npmci install 14.17.0 In this example, `npmci` installs Node.js version `14.17.0` and sets it as the default. +### Using NVM in Dockerfiles + +The base image includes **nvm (Node Version Manager)** for flexible Node.js version management. Use nvm commands directly in Dockerfile RUN statements without any sourcing required: + +```dockerfile +FROM registry.gitlab.com/hosttoday/ht-docker-node:latest + +# Use nvm directly - no sourcing needed +RUN nvm install 18.20.0 +RUN nvm use 18 && npm install + +# Or chain commands +RUN nvm install 19.0.0 && nvm use 19 && npm ci +``` + +**Important**: Each RUN command is a separate shell. To persist version changes across RUN commands, set a new default: + +```dockerfile +RUN nvm install 18.20.0 && nvm alias default 18 +# Subsequent RUN commands will use v18 by default +``` + +### Using NVM in CI/CD Workflows + +NVM is automatically available in CI/CD workflow scripts when using `bash -c`: + +```yaml +jobs: + build: + runs-on: ubuntu-latest + container: + image: registry.gitlab.com/hosttoday/ht-docker-node:latest + + steps: + - name: Use specific Node version + run: | + nvm install 18.20.0 + nvm use 18 + npm install + npm test + + - name: Test multiple versions + run: | + for version in 16 18 20; do + nvm install $version + nvm use $version + npm test + done +``` + +### NVM vs npmci + +Both tools are available in the image: + +- **nvm**: Standard Node version manager, works in Dockerfiles and CI/CD workflows +- **npmci**: CI-focused wrapper with additional shipzone.io features + +Choose based on your preference - they work together seamlessly. + ### Custom Dockerfile with `npmci` and your Node.js App You can create a custom Dockerfile for your Node.js application using the `:npmci` flavour: