Search code examples
node.jsdockernpm

/node_modules/.bin/../node/bin/node: 1: This: not found


Problem:

I set up a Docker Compose on my Linux (Kubuntu) laptop that includes a python container which runs Django and uses React for a Frontend. When I brought the Docker files over to my Windows 10 desktop, I am getting the following error: /node_modules/.bin/../node/bin/node: 1: This: not found

My efforts so far:

I've checked Node and npm versions inside the container on each system; they are both v22.4.0 and 10.8.1 respectively, so versions does not seem to be the issue.

I've tried to set up this docker environment on a different Windows laptop, I am getting the same /node_modules/.bin/../node/bin/node: 1: This: not found error, which suggests to me that this is a Linux-Windows issue, not something specific to my desktop.

I've found an existing StackOverflow question with no answer and another with only a comment that led to a GitHub issue on the now-archived npm repo, but none of these seem to apply to Docker. I tried to follow the directions that seemed to solve the issue for most people in the GitHub issue, but I am using nvm on my Windows machine and do not have a C:/Users/{username}/AppData/Roaming/npm or C:/Users/{username}/AppData/Roaming/npm-cache folder to delete. I did try changing my Node version using nvm, but the error persists. I'm also not convinced that the error should be happening in a Docker container even if there was an issue with Node/npm on my Windows system; the Docker is installing Node directly from source (see below for details).

I'm at a bit of a dead end of what else to check, suggestions appreciated.

Setup Details:

All the details can be seen at my GitHub branch for trying to get this up and running, but I'll include the Dockerfile for the affected container as well as the compose file here for convenience. GitHub is not tracking my node_modules directory because it's so large, but if I should include details about that let me know and I will provide them. My package.json and package-lock.json can be found in the Frontend directory.

Python container Dockerfile:

# syntax=docker/dockerfile:1

ARG PYTHON_VERSION=3.12.2
FROM python:${PYTHON_VERSION} AS base

RUN apt-get update \
    && apt-get upgrade -y \
    && apt-get install -y sudo gcc default-libmysqlclient-dev pkg-config \
    && rm -rf /var/lib/apt/lists/*

# Prevents Python from writing pyc files.
ENV PYTHONDONTWRITEBYTECODE=1

# Keeps Python from buffering stdout and stderr to avoid situations where
# the application crashes without emitting any logs due to buffering.
ENV PYTHONUNBUFFERED=1

# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN useradd -m --uid "${UID}" appuser
RUN echo 'appuser:askStackOverflow' | chpasswd
RUN usermod -aG sudo appuser

# Create a sudoers configuration file in /etc/sudoers.d/
RUN echo 'appuser localhost=(root) NOPASSWD: /usr/bin/npm' > /etc/sudoers.d/myuser \
    && chmod 440 /etc/sudoers.d/myuser \
    && chown root:root /etc/sudoers.d/myuser


RUN cd /home/appuser/
WORKDIR /home/appuser/

# Copy the source code into the container.
COPY . /home/appuser/

# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds.
# Leverage a bind mount to requirements.txt to avoid having to copy them into
# into this layer.
RUN --mount=type=cache,target=/root/.cache/pip \
    --mount=type=bind,source=requirements.txt,target=requirements.txt \
    pip install --root-user-action=ignore --upgrade pip \
    && pip install --root-user-action=ignore mysqlclient \
    && pip install --root-user-action=ignore -r requirements.txt


RUN curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
RUN bash nodesource_setup.sh
RUN apt-get -y install nodejs

# Switch to the non-privileged user to run the application.
# USER appuser

WORKDIR /home/appuser/Frontend/
RUN sudo /usr/bin/npm install

VOLUME /home/appuser/Frontend/src/
VOLUME /home/appuser/MemeCataloger2/
VOLUME /home/appuser/api/
VOLUME /home/appuser/Sockets/

WORKDIR /home/appuser/

# Expose the port that the application listens on.
EXPOSE 8000

# Make migrations to the database
RUN python manage.py makemigrations

# Run the application.
CMD ["bash", "-c", "python manage.py migrate & python manage.py runserver 0.0.0.0:8000 & cd /home/appuser/Frontend/ && npm run dev"]

compose.yaml:

services:
  db:
    build:
      context: ./MySqlDockerSetup
    restart: always
    user: root
    secrets:
      - db-password
      - django-db-password
    volumes:
      - db-data:/var/lib/mysql
    # environment:
      # MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db-password
      # MYSQL_USER: django
      # MYSQL_PASSWORD_FILE: /run/secrets/django-db-password
    healthcheck:
        test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
        interval: 10s
        timeout: 10s
        retries: 3
    expose:
      - 3306:3306

  redis:
    image: redis:7
    ports:
     - 6379:6379

  server:
    build:
      context: .
    volumes:
        - ./Frontend/src:/home/appuser/Frontend/src:rshared
        - ./MemeCataloger2:/home/appuser/MemeCataloger2:rshared
        - ./api:/home/appuser/api:rshared
        - ./Sockets:/home/appuser/Sockets:rshared

    ports:
      - 8000:8000
    depends_on:
        db:
            condition: service_healthy

volumes:
    db-data:
    server-frontend-src:
    server-memecataloger2:
    server-api:
    server-sockets:

secrets:
  db-password:
    file: ./MySqlDockerSetup/db-password.txt
  django-db-password:
    file: ./MySqlDockerSetup/django-db-password.txt

Solution

  • Figured it out -- the problem here is that my project directory was copied into the container (COPY . /home/appuser/) including the node_modules folder on my Windows machine. This Windows node_modules folder in the Linux environment was causing problems with npm, which was getting confused about context.

    In my case, the easiest solution was to just delete the node_modules folder on my Windows machine, but generally just exclusing it from being copied into the Linux container should work (or maybe deleting it from the Linux container after copying project files, but that seems like a huge waste of time, given that when node_modules is included, it outweighs all the code I've written on this project, so copying and then deleting most of the data seems wasteful... But you know your project, maybe it makes sense for you).