Hello there I have this dockerfile with some scripts that will install a nextjs app i want to replce npm with pnpm with no luck
Dockerfile
FROM node:lts-bullseye
# Declare build arguments and set default values
ARG TARGET_WORKDIR=/project
ARG MY_UID=1000
ARG MY_GID=1000
# Set environment variables
ENV TARGET_WORKDIR=${TARGET_WORKDIR}
ENV NEXT_TELEMETRY_DISABLED=1
WORKDIR ${TARGET_WORKDIR}
# Install system dependencies and create the user and group in one layer
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
&& if ! getent group ${MY_GID} >/dev/null; then \
groupadd -g ${MY_GID} container_group; \
else \
groupmod -n container_group $(getent group ${MY_GID} | cut -d: -f1); \
fi && \
if ! getent passwd ${MY_UID} >/dev/null; then \
useradd -u ${MY_UID} -g ${MY_GID} -m container_user; \
else \
usermod -d /home/container_user -l container_user $(getent passwd ${MY_UID} | cut -d: -f1); \
fi && \
mkdir -p /home/container_user /home/container_user/.vscode-server ${TARGET_WORKDIR}/application/node_modules && \
chown -R container_user:container_group /home/container_user /home/container_user/.vscode-server ${TARGET_WORKDIR} && \
rm -rf /var/lib/apt/lists/*
# Copy entrypoint script into the image and set permissions
COPY ./setup/scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# Switch to the non-root user
USER container_user
# Set npm directories to user's home directory
RUN mkdir -p /home/container_user/.npm /home/container_user/.npm-global && \
npm config set prefix /home/container_user/.npm-global && \
npm config set cache /home/container_user/.npm && \
npm install -g npm
# Update PATH environment variable
ENV PATH=$PATH:/home/container_user/.npm-global/bin
# Set the entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Expose port 3000
EXPOSE 3000
# Default command
CMD ["bash"]
scripts/entrypoint.sh
#!/bin/bash
# Ensure the TARGET_WORKDIR environment variable is set
export TARGET_WORKDIR=${TARGET_WORKDIR:-/project}
# Path to the bootstrap script
BOOTSTRAP_SCRIPT=${TARGET_WORKDIR}/setup/scripts/bootstrap.sh
# Check if the bootstrap script exists
if [ -f "$BOOTSTRAP_SCRIPT" ]; then
# Make sure it's executable
chmod +x "$BOOTSTRAP_SCRIPT"
# Run the bootstrap script
"$BOOTSTRAP_SCRIPT"
else
echo "Bootstrap script not found at $BOOTSTRAP_SCRIPT"
exit 1
fi
# Navigate to the project directory
cd "${TARGET_WORKDIR}/application"
# Execute the CMD passed from the Dockerfile or docker-compose
exec "$@"
scripts/bootstrap.sh
#!/bin/bash
set -e
if [ -z "$TARGET_WORKDIR" ]; then
echo "Error: TARGET_WORKDIR is not set."
exit 1
fi
next_project_dir=${TARGET_WORKDIR}/application
next_version=${NEXT_VERSION}
# during build let's initialise a default next js project with sensible defaults (each to their own ofc, modify as necessary before running)
# we have to bootstrap the app in the /tmp dir and copy files into the next_project_dir due to the the node_modules docker compose mount which prevents create-next-app from succeeding due to existing files in the target dir, so we skip install here, copy everything over then install node modules later
# test if the target next project dir is empty (minus the node_modules mount) and if so start bootstrapping
if [ ! -d "$next_project_dir" ] || [ -z "$(ls -A "$next_project_dir" | grep -v '^node_modules$' | head -n1)" ]; then
# this uses `create-next-app` for bootstrapping, run `npx create-next-app@latest`
# to see available options
echo "Initializing Next.js project..."
# Initialize in a temporary directory
tmp_dir="/tmp/next_app"
echo "Clearing any existing temporary files"
rm -rf "$tmp_dir" || {
echo "Failed to remove temporary files"
exit 1
}
echo "Ensuring temp dir exists"
mkdir -p "$tmp_dir" || {
echo "Failed to create temp dir"
exit 1
}
echo "Switching to temp dir"
cd "$tmp_dir" || {
echo "Failed to change directory to temp dir"
exit 1
}
# Initialize Next.js project
echo "Running create-next-app for version $NEXT_VERSION..."
if ! npx --yes create-next-app@$NEXT_VERSION . --yes \
--ts \
--tailwind \
--eslint \
--app \
--src-dir \
--use-npm \
--import-alias "@/*" \
--skip-install; then
echo "Next.js project initialization failed."
exit 1
fi
# ensure working directory exists
mkdir -p $next_project_dir || {
echo "Failed to create directory: $next_project_dir"
exit 1
}
cp -R . "$next_project_dir" || {
echo "Failed to copy files across"
exit 1
}
rm -rf "$tmp_dir" || {
echo "Failed to remove temporary files"
exit 1
}
# chown -R "$(id -u):$(id -g)" "$next_project_dir"
else
echo "Next.js project already initialized, skipping bootstrapping."
fi
if [ -z "$(ls -A "$next_project_dir/node_modules" | head -n1)" ]; then
# Install node modules (required to run separately to the above if the docker volume is destroyed after the project has been initialised or an existing project has been dropped in)
echo "Installing node modules..."
# navigate to the working directory
cd $next_project_dir || {
echo "Failed to navigate to directory: $next_project_dir"
exit 1
}
npm install --loglevel verbose
fi
in the dockerfile I have tried to npm add -g pnpm but i get an error that pnpm is not found, i want to replace npm with pnpm for the node_module installation
I believe you should replace line 43 in the Dockerfile:
RUN npm install -g npm
with the command:
RUN npm install -g pnpm
Also, modify line 115 in the bootstrap.sh file:
npm install --loglevel verbose
to:
pnpm install --loglevel verbose
This is what I think, and I wish you success!!