refactor(nvm): Move wrapper scripts to image_support_files directory
Improved code organization and maintainability: - Created image_support_files/ directory for Docker helper scripts - Moved bash-with-nvm and docker-entrypoint.sh to support directory - Added comprehensive README.md documenting each script's purpose - Updated Dockerfile to COPY from organized directory structure Benefits: - Cleaner repository structure - Scripts are now version-controlled files (not echo chains) - Easier to read, modify, and maintain - Self-documented with in-directory README No functional changes - all nvm functionality remains identical.
This commit is contained in:
25
Dockerfile
25
Dockerfile
@@ -93,31 +93,14 @@ RUN printf '%s\n%s\n%s\n\n%s\n' \
|
||||
'[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"' \
|
||||
"$(cat /etc/bash.bashrc)" > /etc/bash.bashrc
|
||||
|
||||
# Create a shell wrapper that sources nvm before executing commands
|
||||
RUN echo '#!/bin/bash' > /usr/local/bin/bash-with-nvm \
|
||||
&& echo 'set -e' >> /usr/local/bin/bash-with-nvm \
|
||||
&& echo 'export NVM_DIR="/usr/local/nvm"' >> /usr/local/bin/bash-with-nvm \
|
||||
&& echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> /usr/local/bin/bash-with-nvm \
|
||||
&& echo 'eval "$@"' >> /usr/local/bin/bash-with-nvm \
|
||||
&& chmod +x /usr/local/bin/bash-with-nvm
|
||||
# Copy nvm wrapper scripts from support directory
|
||||
COPY image_support_files/bash-with-nvm /usr/local/bin/bash-with-nvm
|
||||
COPY image_support_files/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/bash-with-nvm /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Use wrapper for RUN commands to enable nvm
|
||||
SHELL ["/usr/local/bin/bash-with-nvm"]
|
||||
|
||||
# Create entrypoint wrapper for runtime nvm support (CI/CD workflows)
|
||||
RUN echo '#!/bin/bash' > /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo 'set -e' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo 'export NVM_DIR="/usr/local/nvm"' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo '# If command is bash, source nvm in it' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo 'if [ "$1" = "bash" ] && [ "$2" = "-c" ]; then' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo ' shift 2' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo ' exec bash -c "source /etc/bash.bashrc && $*"' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo 'else' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo ' exec "$@"' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& echo 'fi' >> /usr/local/bin/docker-entrypoint.sh \
|
||||
&& chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Enable nvm for runtime bash commands (CI/CD workflows)
|
||||
ENV BASH_ENV=/etc/bash.bashrc
|
||||
|
||||
|
||||
90
image_support_files/README.md
Normal file
90
image_support_files/README.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Image Support Files
|
||||
|
||||
This directory contains helper scripts that are copied into the Docker image during build to enable NVM functionality.
|
||||
|
||||
## Files
|
||||
|
||||
### `bash-with-nvm`
|
||||
|
||||
**Purpose**: Wrapper script for Dockerfile RUN commands
|
||||
|
||||
**Usage**: Set as SHELL directive in Dockerfile
|
||||
```dockerfile
|
||||
SHELL ["/usr/local/bin/bash-with-nvm"]
|
||||
```
|
||||
|
||||
**What it does**:
|
||||
- Sources nvm before executing each Dockerfile RUN command
|
||||
- Enables direct usage of `nvm` commands without manual sourcing
|
||||
- Example: `RUN nvm install 18` works without `bash -c "source ..."`
|
||||
|
||||
**Location in image**: `/usr/local/bin/bash-with-nvm`
|
||||
|
||||
**How it works**:
|
||||
1. Exports NVM_DIR environment variable
|
||||
2. Sources `$NVM_DIR/nvm.sh` to load nvm functions
|
||||
3. Executes the command passed to it via `eval "$@"`
|
||||
|
||||
---
|
||||
|
||||
### `docker-entrypoint.sh`
|
||||
|
||||
**Purpose**: ENTRYPOINT script for runtime nvm support
|
||||
|
||||
**Usage**: Set as ENTRYPOINT in Dockerfile
|
||||
```dockerfile
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
```
|
||||
|
||||
**What it does**:
|
||||
- Makes nvm available in `docker run ... bash -c` commands
|
||||
- Enables nvm in CI/CD workflow scripts
|
||||
- Passes through non-bash commands unchanged
|
||||
|
||||
**Location in image**: `/usr/local/bin/docker-entrypoint.sh`
|
||||
|
||||
**How it works**:
|
||||
1. Loads nvm in the entrypoint environment
|
||||
2. Detects if command is `bash -c ...`
|
||||
3. If yes: Injects `source /etc/bash.bashrc` before the user's command
|
||||
4. If no: Executes command as-is with `exec "$@"`
|
||||
|
||||
**Examples**:
|
||||
- `docker run image bash -c "nvm install 18"` → nvm is available
|
||||
- `docker run image node --version` → Passes through to node binary
|
||||
- CI/CD: `run: nvm install 19` → Works automatically
|
||||
|
||||
---
|
||||
|
||||
## Why These Scripts Are Needed
|
||||
|
||||
**The Problem**:
|
||||
- nvm is a bash function, not a binary executable
|
||||
- It must be sourced into each shell session
|
||||
- Docker RUN commands and `bash -c` don't automatically source it
|
||||
|
||||
**The Solution**:
|
||||
1. **bash-with-nvm**: Makes Dockerfile RUN commands work
|
||||
2. **docker-entrypoint.sh**: Makes runtime `bash -c` commands work
|
||||
3. **/etc/bash.bashrc** (configured in Dockerfile): Makes interactive shells work
|
||||
|
||||
Together, these provide seamless nvm access in all contexts.
|
||||
|
||||
---
|
||||
|
||||
## Maintenance
|
||||
|
||||
**Modifying the scripts**:
|
||||
1. Edit the file in this directory
|
||||
2. Rebuild the Docker image
|
||||
3. Test with both `docker build` and `docker run` scenarios
|
||||
|
||||
**Testing checklist**:
|
||||
- [ ] `RUN nvm install 18` works in Dockerfile
|
||||
- [ ] `docker run image bash -c "nvm install 18"` works
|
||||
- [ ] `docker run image node --version` still works (fallback)
|
||||
- [ ] CI/CD workflows can use nvm commands
|
||||
|
||||
**Debugging**:
|
||||
- View script in running container: `docker run image cat /usr/local/bin/bash-with-nvm`
|
||||
- Test entrypoint manually: `docker run --entrypoint /bin/bash image -c "nvm --version"`
|
||||
9
image_support_files/bash-with-nvm
Normal file
9
image_support_files/bash-with-nvm
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Load nvm before executing Dockerfile RUN commands
|
||||
export NVM_DIR="/usr/local/nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
|
||||
# Execute the command passed to this wrapper
|
||||
eval "$@"
|
||||
14
image_support_files/docker-entrypoint.sh
Normal file
14
image_support_files/docker-entrypoint.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Load nvm in the entrypoint environment
|
||||
export NVM_DIR="/usr/local/nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
|
||||
# If command is bash -c, inject bashrc sourcing to make nvm available
|
||||
if [ "$1" = "bash" ] && [ "$2" = "-c" ]; then
|
||||
shift 2
|
||||
exec bash -c "source /etc/bash.bashrc && $*"
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user