feat(nvm): Enable full nvm support in Docker builds and CI/CD workflows
- Add global nvm configuration in /etc/bash.bashrc (prepended before PS1 check) - Create bash-with-nvm wrapper for Dockerfile RUN commands - Add intelligent ENTRYPOINT for runtime nvm support - Change default SHELL directive to use nvm wrapper - nvm commands work directly in RUN without manual sourcing - nvm commands work in CI/CD workflow bash -c scripts - Maintain backward compatibility: npmci still available, ENV PATH preserved - Non-bash shells fall back to ENV PATH (v20.12.2) - Both interactive and non-interactive shells have full nvm access Technical implementation: - /etc/bash.bashrc: NVM init prepended before early return - /usr/local/bin/bash-with-nvm: Build-time wrapper via SHELL directive - /usr/local/bin/docker-entrypoint.sh: Runtime wrapper for bash -c detection - ENV PATH fallback ensures non-bash compatibility Tested: - Dockerfile RUN: install, use, version switching - Runtime bash -c: all nvm commands - CI/CD workflows: .gitea context - Backward compat: pnpm, npmci, ENV PATH - Multi-stage builds, interactive shells
This commit is contained in:
		
							
								
								
									
										46
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -85,18 +85,58 @@ RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selectio | |||||||
| # Install nvm with node and npm | # Install nvm with node and npm | ||||||
| RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash | RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash | ||||||
|  |  | ||||||
|  | # Make nvm available globally in all bash shells (interactive + non-interactive) | ||||||
|  | # IMPORTANT: Prepend to bashrc, before the "[ -z "$PS1" ] && return" line | ||||||
|  | RUN printf '%s\n%s\n%s\n\n%s\n' \ | ||||||
|  |     'export NVM_DIR="/usr/local/nvm"' \ | ||||||
|  |     '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' \ | ||||||
|  |     '[ -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 | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  |  | ||||||
| # prepare pnpm | # prepare pnpm | ||||||
| ENV PNPM_HOME="/root/.local/share/pnpm/pnpm" | ENV PNPM_HOME="/root/.local/share/pnpm/pnpm" | ||||||
| RUN mkdir -p ${PNPM_HOME} | RUN mkdir -p ${PNPM_HOME} | ||||||
| ENV PATH="$PNPM_HOME:$PATH" | ENV PATH="$PNPM_HOME:$PATH" | ||||||
|  |  | ||||||
| RUN bash -c "source $NVM_DIR/nvm.sh \ | # Now nvm is available directly without sourcing | ||||||
|     && nvm install $NODE_VERSION_STABLE \ | RUN nvm install $NODE_VERSION_STABLE \ | ||||||
|     && nvm alias default $NODE_VERSION_STABLE \ |     && nvm alias default $NODE_VERSION_STABLE \ | ||||||
|     && nvm use default \ |     && nvm use default \ | ||||||
|     && curl -fsSL https://get.pnpm.io/install.sh | bash - \ |     && curl -fsSL https://get.pnpm.io/install.sh | bash - \ | ||||||
|     && pnpm -v \ |     && pnpm -v \ | ||||||
|     && pnpm config set unsafe-perm true" |     && pnpm config set unsafe-perm true | ||||||
|  |  | ||||||
| ENV NODE_PATH $NVM_DIR/v$NODE_VERSION_STABLE/lib/node_modules | ENV NODE_PATH $NVM_DIR/v$NODE_VERSION_STABLE/lib/node_modules | ||||||
| ENV PATH      $NVM_DIR/versions/node/v$NODE_VERSION_STABLE/bin:$PATH | ENV PATH      $NVM_DIR/versions/node/v$NODE_VERSION_STABLE/bin:$PATH | ||||||
|  |  | ||||||
|  | # Set entrypoint to make nvm available in all runtime contexts | ||||||
|  | ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] | ||||||
|  | CMD ["bash"] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user