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"' \
|
'[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"' \
|
||||||
"$(cat /etc/bash.bashrc)" > /etc/bash.bashrc
|
"$(cat /etc/bash.bashrc)" > /etc/bash.bashrc
|
||||||
|
|
||||||
# Create a shell wrapper that sources nvm before executing commands
|
# Copy nvm wrapper scripts from support directory
|
||||||
RUN echo '#!/bin/bash' > /usr/local/bin/bash-with-nvm \
|
COPY image_support_files/bash-with-nvm /usr/local/bin/bash-with-nvm
|
||||||
&& echo 'set -e' >> /usr/local/bin/bash-with-nvm \
|
COPY image_support_files/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||||
&& echo 'export NVM_DIR="/usr/local/nvm"' >> /usr/local/bin/bash-with-nvm \
|
RUN chmod +x /usr/local/bin/bash-with-nvm /usr/local/bin/docker-entrypoint.sh
|
||||||
&& 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
|
|
||||||
|
|
||||||
# Use wrapper for RUN commands to enable nvm
|
# Use wrapper for RUN commands to enable nvm
|
||||||
SHELL ["/usr/local/bin/bash-with-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)
|
# Enable nvm for runtime bash commands (CI/CD workflows)
|
||||||
ENV BASH_ENV=/etc/bash.bashrc
|
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