Trying to run python child process on nodejs app but cannot get sortedcontainers to be recognized

Pip will not install. Tried a virtual environment but docker file refuses to install sortedcontainers. When I ssh into the app, python3 is recognized but pip3 is not. Here is my dockerfile below. Still new to fly.io and docker. And “which python3” results in “/usr/bin/python3” not “/opt/venv/bin/python3”

# Adjust NODE_VERSION as desired
ARG NODE_VERSION=20.11.0
# non slim version so that python3 comes installed
FROM node:${NODE_VERSION} AS base

LABEL fly_launch_runtime="Node.js"

# Node.js app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"

# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build node modules and python3
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential node-gyp pkg-config \
    python3 \
    python3-pip \
    python3-dev \
    python3-venv \
    && rm -rf /var/lib/apt/lists/*
    
    # python-is-python3 \

# Create and activate virtual environment
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"


# Install Python dependencies in the virtual environment
RUN pip3 install --no-cache-dir \
    sortedcontainers \
    cython

# Install node modules
COPY package-lock.json package.json ./
RUN npm ci

# Copy application code
COPY . .

# Ensure Python scripts use the virtual environment
ENV PYTHONPATH="$VIRTUAL_ENV/lib/python3.11/site-packages:$PYTHONPATH"

# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app /app

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD [ "node", "index.js" ]

Hi… I’m no Python expert, but this part deserves a closer look, I think. All of your ENV manipulations are in that throwaway phase…

(The non-obviousness of this is one of the weak points of Dockerfile syntax, in my opinion.)

Hope this helps get things unstuck!

I guess I wouldn’t know how to get rid of that since I’m not sure of its significance to

# Copy built application
COPY --from=build /app /app

I’d just remove these two:

# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app /app

This removes the reset back to the base, which then makes the COPY between stages redundant. The disadvantage is you’ll get a larger image, but at least it will work for now.

1 Like

Thank you yes! This worked!

1 Like

Excellent!

Multi-stage build is ace, but it can be more complicated to work with. The idea is that you create at least one intermediate image, which contain all sorts of cruft as well as build artifacts. You then create a clean (output) stage into which you just copy your artifacts, e.g. a compiler or transpiler files.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.